velocious 1.0.428 → 1.0.430
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/build/src/application.d.ts +96 -9
- package/build/src/application.d.ts.map +1 -1
- package/build/src/application.js +127 -28
- package/build/src/authorization/ability.d.ts +72 -31
- package/build/src/authorization/ability.d.ts.map +1 -1
- package/build/src/authorization/ability.js +59 -22
- package/build/src/authorization/base-resource.d.ts +47 -20
- package/build/src/authorization/base-resource.d.ts.map +1 -1
- package/build/src/authorization/base-resource.js +43 -14
- package/build/src/background-jobs/client.d.ts +4 -2
- package/build/src/background-jobs/client.d.ts.map +1 -1
- package/build/src/background-jobs/client.js +4 -2
- package/build/src/background-jobs/cron-expression.d.ts +9 -5
- package/build/src/background-jobs/cron-expression.d.ts.map +1 -1
- package/build/src/background-jobs/cron-expression.js +16 -6
- package/build/src/background-jobs/forked-runner-child.js +12 -5
- package/build/src/background-jobs/job-registry.d.ts +7 -1
- package/build/src/background-jobs/job-registry.d.ts.map +1 -1
- package/build/src/background-jobs/job-registry.js +8 -2
- package/build/src/background-jobs/job-runner.d.ts +1 -0
- package/build/src/background-jobs/job-runner.d.ts.map +1 -1
- package/build/src/background-jobs/job-runner.js +8 -3
- package/build/src/background-jobs/job.d.ts +12 -8
- package/build/src/background-jobs/job.d.ts.map +1 -1
- package/build/src/background-jobs/job.js +12 -6
- package/build/src/background-jobs/json-socket.d.ts +17 -5
- package/build/src/background-jobs/json-socket.d.ts.map +1 -1
- package/build/src/background-jobs/json-socket.js +18 -6
- package/build/src/background-jobs/main.d.ts +118 -32
- package/build/src/background-jobs/main.d.ts.map +1 -1
- package/build/src/background-jobs/main.js +123 -35
- package/build/src/background-jobs/normalize-error.d.ts +2 -1
- package/build/src/background-jobs/normalize-error.d.ts.map +1 -1
- package/build/src/background-jobs/normalize-error.js +5 -3
- package/build/src/background-jobs/scheduler.d.ts +31 -10
- package/build/src/background-jobs/scheduler.d.ts.map +1 -1
- package/build/src/background-jobs/scheduler.js +33 -11
- package/build/src/background-jobs/socket-request.d.ts +2 -0
- package/build/src/background-jobs/socket-request.d.ts.map +1 -1
- package/build/src/background-jobs/socket-request.js +11 -3
- package/build/src/background-jobs/status-reporter.d.ts +5 -2
- package/build/src/background-jobs/status-reporter.d.ts.map +1 -1
- package/build/src/background-jobs/status-reporter.js +6 -3
- package/build/src/background-jobs/store.d.ts +57 -19
- package/build/src/background-jobs/store.d.ts.map +1 -1
- package/build/src/background-jobs/store.js +70 -20
- package/build/src/background-jobs/types.d.ts +7 -7
- package/build/src/background-jobs/types.d.ts.map +1 -1
- package/build/src/background-jobs/types.js +6 -6
- package/build/src/background-jobs/web/authorization.d.ts.map +1 -1
- package/build/src/background-jobs/web/authorization.js +3 -1
- package/build/src/background-jobs/web/controller.d.ts +40 -14
- package/build/src/background-jobs/web/controller.d.ts.map +1 -1
- package/build/src/background-jobs/web/controller.js +46 -15
- package/build/src/background-jobs/web/registry.d.ts +5 -0
- package/build/src/background-jobs/web/registry.d.ts.map +1 -1
- package/build/src/background-jobs/web/registry.js +4 -1
- package/build/src/background-jobs/worker.d.ts +41 -8
- package/build/src/background-jobs/worker.d.ts.map +1 -1
- package/build/src/background-jobs/worker.js +64 -16
- package/build/src/beacon/client.d.ts +39 -12
- package/build/src/beacon/client.d.ts.map +1 -1
- package/build/src/beacon/client.js +45 -15
- package/build/src/beacon/in-process-broker.d.ts +4 -0
- package/build/src/beacon/in-process-broker.d.ts.map +1 -1
- package/build/src/beacon/in-process-broker.js +8 -3
- package/build/src/beacon/in-process-client.d.ts +28 -9
- package/build/src/beacon/in-process-client.d.ts.map +1 -1
- package/build/src/beacon/in-process-client.js +27 -9
- package/build/src/beacon/server.d.ts +13 -2
- package/build/src/beacon/server.d.ts.map +1 -1
- package/build/src/beacon/server.js +21 -5
- package/build/src/beacon/types.d.ts +3 -3
- package/build/src/beacon/types.d.ts.map +1 -1
- package/build/src/beacon/types.js +2 -2
- package/build/src/cli/base-command.d.ts +18 -4
- package/build/src/cli/base-command.d.ts.map +1 -1
- package/build/src/cli/base-command.js +15 -4
- package/build/src/cli/browser-cli.d.ts +3 -0
- package/build/src/cli/browser-cli.d.ts.map +1 -1
- package/build/src/cli/browser-cli.js +7 -2
- package/build/src/cli/commands/background-jobs-main.d.ts +0 -1
- package/build/src/cli/commands/background-jobs-main.d.ts.map +1 -1
- package/build/src/cli/commands/background-jobs-runner.d.ts +0 -1
- package/build/src/cli/commands/background-jobs-runner.d.ts.map +1 -1
- package/build/src/cli/commands/background-jobs-worker.d.ts +0 -1
- package/build/src/cli/commands/background-jobs-worker.d.ts.map +1 -1
- package/build/src/cli/commands/beacon.d.ts +0 -1
- package/build/src/cli/commands/beacon.d.ts.map +1 -1
- package/build/src/cli/commands/console.d.ts +0 -2
- package/build/src/cli/commands/console.d.ts.map +1 -1
- package/build/src/cli/commands/console.js +5 -2
- package/build/src/cli/commands/db/base-command.d.ts +11 -2
- package/build/src/cli/commands/db/base-command.d.ts.map +1 -1
- package/build/src/cli/commands/db/base-command.js +12 -3
- package/build/src/cli/commands/db/create.d.ts +3 -0
- package/build/src/cli/commands/db/create.d.ts.map +1 -1
- package/build/src/cli/commands/db/create.js +4 -1
- package/build/src/cli/commands/db/drop.d.ts +3 -0
- package/build/src/cli/commands/db/drop.d.ts.map +1 -1
- package/build/src/cli/commands/db/drop.js +4 -1
- package/build/src/cli/commands/db/schema/dump.d.ts +0 -2
- package/build/src/cli/commands/db/schema/dump.d.ts.map +1 -1
- package/build/src/cli/commands/db/schema/dump.js +5 -2
- package/build/src/cli/commands/db/schema/load.d.ts +0 -2
- package/build/src/cli/commands/db/schema/load.d.ts.map +1 -1
- package/build/src/cli/commands/db/schema/load.js +5 -2
- package/build/src/cli/commands/db/seed.d.ts +0 -2
- package/build/src/cli/commands/db/seed.d.ts.map +1 -1
- package/build/src/cli/commands/db/seed.js +5 -2
- package/build/src/cli/commands/db/tenants/check.d.ts +4 -1
- package/build/src/cli/commands/db/tenants/check.d.ts.map +1 -1
- package/build/src/cli/commands/db/tenants/check.js +5 -2
- package/build/src/cli/commands/db/tenants/create.d.ts +4 -1
- package/build/src/cli/commands/db/tenants/create.d.ts.map +1 -1
- package/build/src/cli/commands/db/tenants/create.js +5 -2
- package/build/src/cli/commands/db/tenants/migrate.d.ts +4 -1
- package/build/src/cli/commands/db/tenants/migrate.d.ts.map +1 -1
- package/build/src/cli/commands/db/tenants/migrate.js +5 -2
- package/build/src/cli/commands/destroy/migration.d.ts +0 -1
- package/build/src/cli/commands/destroy/migration.d.ts.map +1 -1
- package/build/src/cli/commands/generate/base-models.d.ts +0 -1
- package/build/src/cli/commands/generate/base-models.d.ts.map +1 -1
- package/build/src/cli/commands/generate/frontend-models.d.ts +0 -2
- package/build/src/cli/commands/generate/frontend-models.d.ts.map +1 -1
- package/build/src/cli/commands/generate/frontend-models.js +5 -2
- package/build/src/cli/commands/generate/migration.d.ts +0 -1
- package/build/src/cli/commands/generate/migration.d.ts.map +1 -1
- package/build/src/cli/commands/generate/model.d.ts +0 -1
- package/build/src/cli/commands/generate/model.d.ts.map +1 -1
- package/build/src/cli/commands/init.d.ts +0 -1
- package/build/src/cli/commands/init.d.ts.map +1 -1
- package/build/src/cli/commands/routes.d.ts +0 -1
- package/build/src/cli/commands/routes.d.ts.map +1 -1
- package/build/src/cli/commands/run-script.d.ts +0 -2
- package/build/src/cli/commands/run-script.d.ts.map +1 -1
- package/build/src/cli/commands/run-script.js +5 -2
- package/build/src/cli/commands/runner.d.ts +0 -2
- package/build/src/cli/commands/runner.d.ts.map +1 -1
- package/build/src/cli/commands/runner.js +5 -2
- package/build/src/cli/commands/server.d.ts +0 -1
- package/build/src/cli/commands/server.d.ts.map +1 -1
- package/build/src/cli/commands/test.d.ts +0 -1
- package/build/src/cli/commands/test.d.ts.map +1 -1
- package/build/src/cli/index.d.ts +18 -5
- package/build/src/cli/index.d.ts.map +1 -1
- package/build/src/cli/index.js +25 -8
- package/build/src/cli/tenant-database-command-helper.d.ts +24 -9
- package/build/src/cli/tenant-database-command-helper.d.ts.map +1 -1
- package/build/src/cli/tenant-database-command-helper.js +30 -11
- package/build/src/cli/use-browser-cli.d.ts +1 -0
- package/build/src/cli/use-browser-cli.d.ts.map +1 -1
- package/build/src/cli/use-browser-cli.js +5 -2
- package/build/src/configuration-resolver.d.ts +1 -0
- package/build/src/configuration-resolver.d.ts.map +1 -1
- package/build/src/configuration-resolver.js +2 -1
- package/build/src/configuration-types.d.ts +44 -44
- package/build/src/configuration-types.d.ts.map +1 -1
- package/build/src/configuration-types.js +27 -27
- package/build/src/configuration.d.ts +350 -114
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +416 -128
- package/build/src/controller.d.ts +67 -18
- package/build/src/controller.d.ts.map +1 -1
- package/build/src/controller.js +88 -23
- package/build/src/current-configuration.d.ts +2 -0
- package/build/src/current-configuration.d.ts.map +1 -1
- package/build/src/current-configuration.js +6 -2
- package/build/src/current.d.ts +16 -9
- package/build/src/current.d.ts.map +1 -1
- package/build/src/current.js +15 -8
- package/build/src/database/annotations-async-hooks.js +13 -6
- package/build/src/database/annotations.d.ts +7 -1
- package/build/src/database/annotations.d.ts.map +1 -1
- package/build/src/database/annotations.js +12 -5
- package/build/src/database/drivers/base-column.d.ts +21 -3
- package/build/src/database/drivers/base-column.d.ts.map +1 -1
- package/build/src/database/drivers/base-column.js +21 -3
- package/build/src/database/drivers/base-columns-index.d.ts +9 -0
- package/build/src/database/drivers/base-columns-index.d.ts.map +1 -1
- package/build/src/database/drivers/base-columns-index.js +10 -1
- package/build/src/database/drivers/base-foreign-key.d.ts +15 -3
- package/build/src/database/drivers/base-foreign-key.d.ts.map +1 -1
- package/build/src/database/drivers/base-foreign-key.js +15 -3
- package/build/src/database/drivers/base-table.d.ts +16 -3
- package/build/src/database/drivers/base-table.d.ts.map +1 -1
- package/build/src/database/drivers/base-table.js +16 -3
- package/build/src/database/drivers/base.d.ts +174 -37
- package/build/src/database/drivers/base.d.ts.map +1 -1
- package/build/src/database/drivers/base.js +156 -40
- package/build/src/database/drivers/mssql/column.d.ts +3 -2
- package/build/src/database/drivers/mssql/column.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/column.js +3 -2
- package/build/src/database/drivers/mssql/index.d.ts +5 -6
- package/build/src/database/drivers/mssql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/index.js +38 -7
- package/build/src/database/drivers/mssql/options.d.ts +1 -0
- package/build/src/database/drivers/mssql/options.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/options.js +8 -2
- package/build/src/database/drivers/mssql/sql/create-database.d.ts +1 -0
- package/build/src/database/drivers/mssql/sql/create-database.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/sql/create-database.js +2 -1
- package/build/src/database/drivers/mssql/sql/drop-database.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/sql/drop-database.js +2 -1
- package/build/src/database/drivers/mssql/structure-sql.d.ts +5 -2
- package/build/src/database/drivers/mssql/structure-sql.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/structure-sql.js +5 -2
- package/build/src/database/drivers/mssql/table.d.ts +1 -0
- package/build/src/database/drivers/mssql/table.d.ts.map +1 -1
- package/build/src/database/drivers/mssql/table.js +9 -4
- package/build/src/database/drivers/mysql/column.d.ts +3 -2
- package/build/src/database/drivers/mysql/column.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/column.js +4 -3
- package/build/src/database/drivers/mysql/index.d.ts +11 -3
- package/build/src/database/drivers/mysql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/index.js +54 -10
- package/build/src/database/drivers/mysql/options.d.ts +1 -0
- package/build/src/database/drivers/mysql/options.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/options.js +4 -2
- package/build/src/database/drivers/mysql/query.d.ts +3 -2
- package/build/src/database/drivers/mysql/query.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/query.js +6 -3
- package/build/src/database/drivers/mysql/sql/create-database.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/sql/create-database.js +3 -1
- package/build/src/database/drivers/mysql/structure-sql.d.ts +7 -2
- package/build/src/database/drivers/mysql/structure-sql.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/structure-sql.js +7 -2
- package/build/src/database/drivers/mysql/table.d.ts +1 -0
- package/build/src/database/drivers/mysql/table.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/table.js +7 -3
- package/build/src/database/drivers/pgsql/column.d.ts +3 -2
- package/build/src/database/drivers/pgsql/column.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/column.js +3 -2
- package/build/src/database/drivers/pgsql/index.d.ts +1 -1
- package/build/src/database/drivers/pgsql/index.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/index.js +36 -11
- package/build/src/database/drivers/pgsql/options.d.ts +2 -0
- package/build/src/database/drivers/pgsql/options.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/options.js +3 -1
- package/build/src/database/drivers/pgsql/structure-sql.d.ts +5 -2
- package/build/src/database/drivers/pgsql/structure-sql.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/structure-sql.js +5 -2
- package/build/src/database/drivers/pgsql/table.d.ts +1 -0
- package/build/src/database/drivers/pgsql/table.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/table.js +6 -2
- package/build/src/database/drivers/sqlite/base.d.ts +15 -5
- package/build/src/database/drivers/sqlite/base.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/base.js +79 -27
- package/build/src/database/drivers/sqlite/column.d.ts +3 -2
- package/build/src/database/drivers/sqlite/column.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/column.js +3 -2
- package/build/src/database/drivers/sqlite/connection-sql-js.d.ts +4 -2
- package/build/src/database/drivers/sqlite/connection-sql-js.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/connection-sql-js.js +4 -2
- package/build/src/database/drivers/sqlite/foreign-key.d.ts +3 -2
- package/build/src/database/drivers/sqlite/foreign-key.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/foreign-key.js +3 -2
- package/build/src/database/drivers/sqlite/index.d.ts +18 -5
- package/build/src/database/drivers/sqlite/index.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.js +40 -16
- package/build/src/database/drivers/sqlite/index.native.d.ts +1 -1
- package/build/src/database/drivers/sqlite/index.native.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.native.js +6 -3
- package/build/src/database/drivers/sqlite/index.web.d.ts +16 -4
- package/build/src/database/drivers/sqlite/index.web.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/index.web.js +17 -7
- package/build/src/database/drivers/sqlite/options.d.ts +2 -0
- package/build/src/database/drivers/sqlite/options.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/options.js +3 -1
- package/build/src/database/drivers/sqlite/query.d.ts +3 -2
- package/build/src/database/drivers/sqlite/query.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/query.js +6 -3
- package/build/src/database/drivers/sqlite/query.native.d.ts +2 -2
- package/build/src/database/drivers/sqlite/query.native.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/query.native.js +3 -3
- package/build/src/database/drivers/sqlite/query.web.d.ts +3 -2
- package/build/src/database/drivers/sqlite/query.web.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/query.web.js +6 -3
- package/build/src/database/drivers/sqlite/sql/alter-table.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/sql/alter-table.js +9 -3
- package/build/src/database/drivers/sqlite/structure-sql.d.ts +2 -0
- package/build/src/database/drivers/sqlite/structure-sql.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/structure-sql.js +3 -1
- package/build/src/database/drivers/sqlite/table-rebuilder.d.ts +2 -0
- package/build/src/database/drivers/sqlite/table-rebuilder.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/table-rebuilder.js +3 -1
- package/build/src/database/drivers/sqlite/table.d.ts +2 -0
- package/build/src/database/drivers/sqlite/table.d.ts.map +1 -1
- package/build/src/database/drivers/sqlite/table.js +14 -4
- package/build/src/database/drivers/structure-sql/utils.d.ts +2 -0
- package/build/src/database/drivers/structure-sql/utils.d.ts.map +1 -1
- package/build/src/database/drivers/structure-sql/utils.js +3 -1
- package/build/src/database/handler.d.ts +1 -0
- package/build/src/database/handler.d.ts.map +1 -1
- package/build/src/database/handler.js +2 -1
- package/build/src/database/initializer-from-require-context.d.ts +8 -0
- package/build/src/database/initializer-from-require-context.d.ts.map +1 -1
- package/build/src/database/initializer-from-require-context.js +4 -1
- package/build/src/database/migration/index.d.ts +40 -5
- package/build/src/database/migration/index.d.ts.map +1 -1
- package/build/src/database/migration/index.js +34 -6
- package/build/src/database/migrator/files-finder.d.ts +2 -0
- package/build/src/database/migrator/files-finder.d.ts.map +1 -1
- package/build/src/database/migrator/files-finder.js +6 -2
- package/build/src/database/migrator.d.ts +29 -4
- package/build/src/database/migrator.d.ts.map +1 -1
- package/build/src/database/migrator.js +45 -10
- package/build/src/database/pool/async-tracked-multi-connection.d.ts +125 -31
- package/build/src/database/pool/async-tracked-multi-connection.d.ts.map +1 -1
- package/build/src/database/pool/async-tracked-multi-connection.js +189 -52
- package/build/src/database/pool/base-methods-forward.d.ts +1 -0
- package/build/src/database/pool/base-methods-forward.d.ts.map +1 -1
- package/build/src/database/pool/base-methods-forward.js +12 -3
- package/build/src/database/pool/base.d.ts +39 -7
- package/build/src/database/pool/base.d.ts.map +1 -1
- package/build/src/database/pool/base.js +59 -18
- package/build/src/database/pool/single-multi-use.d.ts +1 -0
- package/build/src/database/pool/single-multi-use.d.ts.map +1 -1
- package/build/src/database/pool/single-multi-use.js +16 -4
- package/build/src/database/query/alter-table-base.d.ts +1 -0
- package/build/src/database/query/alter-table-base.d.ts.map +1 -1
- package/build/src/database/query/alter-table-base.js +3 -1
- package/build/src/database/query/base.d.ts +3 -0
- package/build/src/database/query/base.d.ts.map +1 -1
- package/build/src/database/query/base.js +4 -1
- package/build/src/database/query/create-database-base.d.ts +5 -0
- package/build/src/database/query/create-database-base.d.ts.map +1 -1
- package/build/src/database/query/create-database-base.js +4 -1
- package/build/src/database/query/create-index-base.d.ts +5 -0
- package/build/src/database/query/create-index-base.d.ts.map +1 -1
- package/build/src/database/query/create-index-base.js +4 -1
- package/build/src/database/query/create-table-base.d.ts +2 -0
- package/build/src/database/query/create-table-base.d.ts.map +1 -1
- package/build/src/database/query/create-table-base.js +3 -1
- package/build/src/database/query/delete-base.d.ts +3 -2
- package/build/src/database/query/delete-base.d.ts.map +1 -1
- package/build/src/database/query/delete-base.js +3 -2
- package/build/src/database/query/drop-database-base.d.ts +5 -0
- package/build/src/database/query/drop-database-base.d.ts.map +1 -1
- package/build/src/database/query/drop-database-base.js +4 -1
- package/build/src/database/query/drop-table-base.d.ts +1 -0
- package/build/src/database/query/drop-table-base.d.ts.map +1 -1
- package/build/src/database/query/drop-table-base.js +3 -1
- package/build/src/database/query/from-base.d.ts +6 -1
- package/build/src/database/query/from-base.d.ts.map +1 -1
- package/build/src/database/query/from-base.js +7 -2
- package/build/src/database/query/from-plain.d.ts +1 -0
- package/build/src/database/query/from-plain.d.ts.map +1 -1
- package/build/src/database/query/from-plain.js +2 -1
- package/build/src/database/query/from-table.d.ts +1 -0
- package/build/src/database/query/from-table.d.ts.map +1 -1
- package/build/src/database/query/from-table.js +2 -1
- package/build/src/database/query/index.d.ts +72 -12
- package/build/src/database/query/index.d.ts.map +1 -1
- package/build/src/database/query/index.js +79 -19
- package/build/src/database/query/insert-base.d.ts +13 -8
- package/build/src/database/query/insert-base.d.ts.map +1 -1
- package/build/src/database/query/insert-base.js +10 -5
- package/build/src/database/query/join-base.d.ts +4 -0
- package/build/src/database/query/join-base.d.ts.map +1 -1
- package/build/src/database/query/join-base.js +5 -1
- package/build/src/database/query/join-object.d.ts +11 -0
- package/build/src/database/query/join-object.d.ts.map +1 -1
- package/build/src/database/query/join-object.js +15 -4
- package/build/src/database/query/join-plain.d.ts +1 -0
- package/build/src/database/query/join-plain.d.ts.map +1 -1
- package/build/src/database/query/join-plain.js +2 -1
- package/build/src/database/query/join-tracker.d.ts +7 -0
- package/build/src/database/query/join-tracker.d.ts.map +1 -1
- package/build/src/database/query/join-tracker.js +8 -1
- package/build/src/database/query/model-class-query.d.ts +92 -26
- package/build/src/database/query/model-class-query.d.ts.map +1 -1
- package/build/src/database/query/model-class-query.js +230 -76
- package/build/src/database/query/order-base.d.ts +3 -0
- package/build/src/database/query/order-base.d.ts.map +1 -1
- package/build/src/database/query/order-base.js +4 -1
- package/build/src/database/query/order-column.d.ts +9 -1
- package/build/src/database/query/order-column.d.ts.map +1 -1
- package/build/src/database/query/order-column.js +10 -2
- package/build/src/database/query/order-plain.d.ts +1 -0
- package/build/src/database/query/order-plain.d.ts.map +1 -1
- package/build/src/database/query/order-plain.js +2 -1
- package/build/src/database/query/preloader/belongs-to.d.ts +1 -0
- package/build/src/database/query/preloader/belongs-to.d.ts.map +1 -1
- package/build/src/database/query/preloader/belongs-to.js +68 -23
- package/build/src/database/query/preloader/ensure-model-class-initialized.d.ts +1 -0
- package/build/src/database/query/preloader/ensure-model-class-initialized.d.ts.map +1 -1
- package/build/src/database/query/preloader/ensure-model-class-initialized.js +2 -1
- package/build/src/database/query/preloader/has-many.d.ts +5 -3
- package/build/src/database/query/preloader/has-many.d.ts.map +1 -1
- package/build/src/database/query/preloader/has-many.js +66 -24
- package/build/src/database/query/preloader/has-one.d.ts +1 -0
- package/build/src/database/query/preloader/has-one.d.ts.map +1 -1
- package/build/src/database/query/preloader/has-one.js +26 -9
- package/build/src/database/query/preloader/selection.d.ts +7 -1
- package/build/src/database/query/preloader/selection.d.ts.map +1 -1
- package/build/src/database/query/preloader/selection.js +13 -5
- package/build/src/database/query/preloader.d.ts +1 -0
- package/build/src/database/query/preloader.d.ts.map +1 -1
- package/build/src/database/query/preloader.js +28 -9
- package/build/src/database/query/query-data.d.ts +21 -7
- package/build/src/database/query/query-data.d.ts.map +1 -1
- package/build/src/database/query/query-data.js +37 -18
- package/build/src/database/query/select-base.d.ts +3 -0
- package/build/src/database/query/select-base.d.ts.map +1 -1
- package/build/src/database/query/select-base.js +4 -1
- package/build/src/database/query/select-plain.d.ts +1 -0
- package/build/src/database/query/select-plain.d.ts.map +1 -1
- package/build/src/database/query/select-plain.js +2 -1
- package/build/src/database/query/select-table-and-column.d.ts +1 -0
- package/build/src/database/query/select-table-and-column.d.ts.map +1 -1
- package/build/src/database/query/select-table-and-column.js +2 -1
- package/build/src/database/query/update-base.d.ts +9 -6
- package/build/src/database/query/update-base.d.ts.map +1 -1
- package/build/src/database/query/update-base.js +7 -4
- package/build/src/database/query/upsert-base.d.ts +13 -4
- package/build/src/database/query/upsert-base.d.ts.map +1 -1
- package/build/src/database/query/upsert-base.js +12 -3
- package/build/src/database/query/where-base.d.ts +4 -0
- package/build/src/database/query/where-base.d.ts.map +1 -1
- package/build/src/database/query/where-base.js +5 -1
- package/build/src/database/query/where-combinator.d.ts +1 -0
- package/build/src/database/query/where-combinator.d.ts.map +1 -1
- package/build/src/database/query/where-combinator.js +6 -2
- package/build/src/database/query/where-hash.d.ts +6 -0
- package/build/src/database/query/where-hash.d.ts.map +1 -1
- package/build/src/database/query/where-hash.js +5 -1
- package/build/src/database/query/where-model-class-hash.d.ts +30 -16
- package/build/src/database/query/where-model-class-hash.d.ts.map +1 -1
- package/build/src/database/query/where-model-class-hash.js +55 -20
- package/build/src/database/query/where-not.d.ts +1 -0
- package/build/src/database/query/where-not.d.ts.map +1 -1
- package/build/src/database/query/where-not.js +3 -1
- package/build/src/database/query/where-plain.d.ts +1 -0
- package/build/src/database/query/where-plain.d.ts.map +1 -1
- package/build/src/database/query/where-plain.js +2 -1
- package/build/src/database/query/with-count.d.ts +11 -5
- package/build/src/database/query/with-count.d.ts.map +1 -1
- package/build/src/database/query/with-count.js +36 -15
- package/build/src/database/query-parser/base-query-parser.d.ts +1 -0
- package/build/src/database/query-parser/base-query-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/base-query-parser.js +2 -1
- package/build/src/database/query-parser/from-parser.d.ts +5 -1
- package/build/src/database/query-parser/from-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/from-parser.js +6 -2
- package/build/src/database/query-parser/group-parser.d.ts +2 -0
- package/build/src/database/query-parser/group-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/group-parser.js +3 -1
- package/build/src/database/query-parser/joins-parser.d.ts +1 -0
- package/build/src/database/query-parser/joins-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/joins-parser.js +2 -1
- package/build/src/database/query-parser/limit-parser.d.ts +1 -0
- package/build/src/database/query-parser/limit-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/limit-parser.js +2 -1
- package/build/src/database/query-parser/options.d.ts +15 -4
- package/build/src/database/query-parser/options.d.ts.map +1 -1
- package/build/src/database/query-parser/options.js +11 -3
- package/build/src/database/query-parser/order-parser.d.ts +1 -0
- package/build/src/database/query-parser/order-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/order-parser.js +2 -1
- package/build/src/database/query-parser/select-parser.d.ts +1 -0
- package/build/src/database/query-parser/select-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/select-parser.js +2 -1
- package/build/src/database/query-parser/where-parser.d.ts +1 -0
- package/build/src/database/query-parser/where-parser.d.ts.map +1 -1
- package/build/src/database/query-parser/where-parser.js +2 -1
- package/build/src/database/record/acts-as-list.d.ts +0 -1
- package/build/src/database/record/acts-as-list.d.ts.map +1 -1
- package/build/src/database/record/acts-as-list.js +89 -45
- package/build/src/database/record/attachments/download.d.ts +34 -15
- package/build/src/database/record/attachments/download.d.ts.map +1 -1
- package/build/src/database/record/attachments/download.js +34 -22
- package/build/src/database/record/attachments/handle.d.ts +17 -5
- package/build/src/database/record/attachments/handle.d.ts.map +1 -1
- package/build/src/database/record/attachments/handle.js +25 -9
- package/build/src/database/record/attachments/normalize-input.d.ts +6 -1
- package/build/src/database/record/attachments/normalize-input.d.ts.map +1 -1
- package/build/src/database/record/attachments/normalize-input.js +54 -17
- package/build/src/database/record/attachments/storage-drivers/filesystem.d.ts +7 -1
- package/build/src/database/record/attachments/storage-drivers/filesystem.d.ts.map +1 -1
- package/build/src/database/record/attachments/storage-drivers/filesystem.js +10 -2
- package/build/src/database/record/attachments/storage-drivers/native.d.ts +12 -7
- package/build/src/database/record/attachments/storage-drivers/native.d.ts.map +1 -1
- package/build/src/database/record/attachments/storage-drivers/native.js +13 -6
- package/build/src/database/record/attachments/storage-drivers/s3.d.ts +18 -9
- package/build/src/database/record/attachments/storage-drivers/s3.d.ts.map +1 -1
- package/build/src/database/record/attachments/storage-drivers/s3.js +38 -13
- package/build/src/database/record/attachments/store.d.ts +48 -25
- package/build/src/database/record/attachments/store.d.ts.map +1 -1
- package/build/src/database/record/attachments/store.js +63 -25
- package/build/src/database/record/index.d.ts +394 -146
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +697 -248
- package/build/src/database/record/instance-relationships/base.d.ts +78 -19
- package/build/src/database/record/instance-relationships/base.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/base.js +98 -26
- package/build/src/database/record/instance-relationships/belongs-to.d.ts +1 -0
- package/build/src/database/record/instance-relationships/belongs-to.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/belongs-to.js +13 -5
- package/build/src/database/record/instance-relationships/has-many.d.ts +27 -7
- package/build/src/database/record/instance-relationships/has-many.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/has-many.js +50 -16
- package/build/src/database/record/instance-relationships/has-one.d.ts +4 -1
- package/build/src/database/record/instance-relationships/has-one.d.ts.map +1 -1
- package/build/src/database/record/instance-relationships/has-one.js +28 -10
- package/build/src/database/record/relationships/base.d.ts +61 -14
- package/build/src/database/record/relationships/base.d.ts.map +1 -1
- package/build/src/database/record/relationships/base.js +60 -15
- package/build/src/database/record/relationships/belongs-to.d.ts.map +1 -1
- package/build/src/database/record/relationships/belongs-to.js +9 -3
- package/build/src/database/record/relationships/has-many.d.ts.map +1 -1
- package/build/src/database/record/relationships/has-many.js +9 -3
- package/build/src/database/record/relationships/has-one.d.ts.map +1 -1
- package/build/src/database/record/relationships/has-one.js +9 -3
- package/build/src/database/record/state-machine.d.ts +9 -1
- package/build/src/database/record/state-machine.d.ts.map +1 -1
- package/build/src/database/record/state-machine.js +35 -14
- package/build/src/database/record/user-module.d.ts +2 -0
- package/build/src/database/record/user-module.d.ts.map +1 -1
- package/build/src/database/record/user-module.js +3 -1
- package/build/src/database/record/validators/base.d.ts +4 -2
- package/build/src/database/record/validators/base.d.ts.map +1 -1
- package/build/src/database/record/validators/base.js +4 -2
- package/build/src/database/record/validators/format.d.ts.map +1 -1
- package/build/src/database/record/validators/format.js +2 -1
- package/build/src/database/record/validators/presence.d.ts.map +1 -1
- package/build/src/database/record/validators/presence.js +5 -2
- package/build/src/database/record/validators/uniqueness.d.ts +0 -2
- package/build/src/database/record/validators/uniqueness.d.ts.map +1 -1
- package/build/src/database/record/validators/uniqueness.js +18 -8
- package/build/src/database/table-data/index.d.ts +40 -4
- package/build/src/database/table-data/index.d.ts.map +1 -1
- package/build/src/database/table-data/index.js +38 -5
- package/build/src/database/table-data/table-column.d.ts +43 -5
- package/build/src/database/table-data/table-column.d.ts.map +1 -1
- package/build/src/database/table-data/table-column.js +37 -4
- package/build/src/database/table-data/table-foreign-key.d.ts +8 -0
- package/build/src/database/table-data/table-foreign-key.d.ts.map +1 -1
- package/build/src/database/table-data/table-foreign-key.js +9 -1
- package/build/src/database/table-data/table-index.d.ts +8 -0
- package/build/src/database/table-data/table-index.d.ts.map +1 -1
- package/build/src/database/table-data/table-index.js +6 -1
- package/build/src/database/table-data/table-reference.d.ts +1 -0
- package/build/src/database/table-data/table-reference.d.ts.map +1 -1
- package/build/src/database/table-data/table-reference.js +2 -1
- package/build/src/database/use-database.d.ts +1 -0
- package/build/src/database/use-database.d.ts.map +1 -1
- package/build/src/database/use-database.js +2 -1
- package/build/src/environment-handlers/base.d.ts +94 -36
- package/build/src/environment-handlers/base.d.ts.map +1 -1
- package/build/src/environment-handlers/base.js +90 -36
- package/build/src/environment-handlers/browser.d.ts +33 -3
- package/build/src/environment-handlers/browser.d.ts.map +1 -1
- package/build/src/environment-handlers/browser.js +36 -9
- package/build/src/environment-handlers/node/cli/commands/cli-command-context.d.ts +5 -0
- package/build/src/environment-handlers/node/cli/commands/cli-command-context.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/cli-command-context.js +6 -2
- package/build/src/environment-handlers/node/cli/commands/console.d.ts +3 -2
- package/build/src/environment-handlers/node/cli/commands/console.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/console.js +23 -9
- package/build/src/environment-handlers/node/cli/commands/db/schema/dump.d.ts +4 -1
- package/build/src/environment-handlers/node/cli/commands/db/schema/dump.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/db/schema/dump.js +5 -2
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.d.ts +6 -2
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.js +11 -5
- package/build/src/environment-handlers/node/cli/commands/db/seed.d.ts +15 -5
- package/build/src/environment-handlers/node/cli/commands/db/seed.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/db/seed.js +20 -6
- package/build/src/environment-handlers/node/cli/commands/destroy/migration.d.ts +5 -0
- package/build/src/environment-handlers/node/cli/commands/destroy/migration.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/destroy/migration.js +3 -1
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts +2 -0
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +6 -4
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +43 -29
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +99 -40
- package/build/src/environment-handlers/node/cli/commands/generate/migration.d.ts +5 -0
- package/build/src/environment-handlers/node/cli/commands/generate/migration.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/migration.js +3 -1
- package/build/src/environment-handlers/node/cli/commands/generate/model.d.ts +5 -0
- package/build/src/environment-handlers/node/cli/commands/generate/model.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/model.js +3 -1
- package/build/src/environment-handlers/node/cli/commands/init.d.ts +5 -0
- package/build/src/environment-handlers/node/cli/commands/init.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/init.js +3 -1
- package/build/src/environment-handlers/node/cli/commands/routes.d.ts +3 -0
- package/build/src/environment-handlers/node/cli/commands/routes.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/routes.js +4 -1
- package/build/src/environment-handlers/node/cli/commands/run-script.d.ts +15 -5
- package/build/src/environment-handlers/node/cli/commands/run-script.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/run-script.js +20 -6
- package/build/src/environment-handlers/node/cli/commands/runner.d.ts +18 -6
- package/build/src/environment-handlers/node/cli/commands/runner.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/runner.js +20 -6
- package/build/src/environment-handlers/node/cli/commands/server.d.ts +13 -1
- package/build/src/environment-handlers/node/cli/commands/server.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/server.js +23 -6
- package/build/src/environment-handlers/node.d.ts +14 -2
- package/build/src/environment-handlers/node.d.ts.map +1 -1
- package/build/src/environment-handlers/node.js +107 -39
- package/build/src/error-logger.d.ts +4 -3
- package/build/src/error-logger.d.ts.map +1 -1
- package/build/src/error-logger.js +4 -3
- package/build/src/frontend-model-controller.d.ts +239 -90
- package/build/src/frontend-model-controller.d.ts.map +1 -1
- package/build/src/frontend-model-controller.js +577 -787
- package/build/src/frontend-model-resource/base-resource.d.ts +118 -66
- package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
- package/build/src/frontend-model-resource/base-resource.js +205 -82
- package/build/src/frontend-models/base.d.ts +319 -163
- package/build/src/frontend-models/base.d.ts.map +1 -1
- package/build/src/frontend-models/base.js +717 -366
- package/build/src/frontend-models/clear-pending-debounced-callback.d.ts +2 -1
- package/build/src/frontend-models/clear-pending-debounced-callback.d.ts.map +1 -1
- package/build/src/frontend-models/clear-pending-debounced-callback.js +6 -3
- package/build/src/frontend-models/event-hook-models.d.ts +5 -0
- package/build/src/frontend-models/event-hook-models.d.ts.map +1 -1
- package/build/src/frontend-models/event-hook-models.js +10 -3
- package/build/src/frontend-models/model-registry.d.ts +5 -5
- package/build/src/frontend-models/model-registry.d.ts.map +1 -1
- package/build/src/frontend-models/model-registry.js +5 -5
- package/build/src/frontend-models/outgoing-event-buffer.d.ts +11 -3
- package/build/src/frontend-models/outgoing-event-buffer.d.ts.map +1 -1
- package/build/src/frontend-models/outgoing-event-buffer.js +13 -5
- package/build/src/frontend-models/preloader.d.ts +9 -6
- package/build/src/frontend-models/preloader.d.ts.map +1 -1
- package/build/src/frontend-models/preloader.js +21 -9
- package/build/src/frontend-models/query.d.ts +283 -73
- package/build/src/frontend-models/query.d.ts.map +1 -1
- package/build/src/frontend-models/query.js +331 -203
- package/build/src/frontend-models/resource-config-validation.d.ts +2 -0
- package/build/src/frontend-models/resource-config-validation.d.ts.map +1 -1
- package/build/src/frontend-models/resource-config-validation.js +3 -1
- package/build/src/frontend-models/resource-definition.d.ts +12 -5
- package/build/src/frontend-models/resource-definition.d.ts.map +1 -1
- package/build/src/frontend-models/resource-definition.js +39 -13
- package/build/src/frontend-models/transport-serialization.d.ts +14 -11
- package/build/src/frontend-models/transport-serialization.d.ts.map +1 -1
- package/build/src/frontend-models/transport-serialization.js +80 -53
- package/build/src/frontend-models/use-destroyed-event.d.ts +21 -0
- package/build/src/frontend-models/use-destroyed-event.d.ts.map +1 -1
- package/build/src/frontend-models/use-destroyed-event.js +34 -11
- package/build/src/frontend-models/use-model-class-event.d.ts +24 -0
- package/build/src/frontend-models/use-model-class-event.d.ts.map +1 -1
- package/build/src/frontend-models/use-model-class-event.js +39 -12
- package/build/src/frontend-models/use-updated-event.d.ts +21 -0
- package/build/src/frontend-models/use-updated-event.d.ts.map +1 -1
- package/build/src/frontend-models/use-updated-event.js +37 -12
- package/build/src/frontend-models/websocket-channel.d.ts +51 -9
- package/build/src/frontend-models/websocket-channel.d.ts.map +1 -1
- package/build/src/frontend-models/websocket-channel.js +96 -26
- package/build/src/frontend-models/websocket-publishers.d.ts +2 -0
- package/build/src/frontend-models/websocket-publishers.d.ts.map +1 -1
- package/build/src/frontend-models/websocket-publishers.js +33 -11
- package/build/src/http-client/header.d.ts +1 -0
- package/build/src/http-client/header.d.ts.map +1 -1
- package/build/src/http-client/header.js +2 -1
- package/build/src/http-client/index.d.ts +4 -0
- package/build/src/http-client/index.d.ts.map +1 -1
- package/build/src/http-client/index.js +5 -1
- package/build/src/http-client/request.d.ts +5 -0
- package/build/src/http-client/request.d.ts.map +1 -1
- package/build/src/http-client/request.js +6 -1
- package/build/src/http-client/response.d.ts +14 -4
- package/build/src/http-client/response.d.ts.map +1 -1
- package/build/src/http-client/response.js +14 -4
- package/build/src/http-client/websocket-client.d.ts +1 -0
- package/build/src/http-client/websocket-client.d.ts.map +1 -1
- package/build/src/http-client/websocket-client.js +2 -1
- package/build/src/http-server/client/index.d.ts +16 -2
- package/build/src/http-server/client/index.d.ts.map +1 -1
- package/build/src/http-server/client/index.js +44 -13
- package/build/src/http-server/client/params-to-object.d.ts +16 -10
- package/build/src/http-server/client/params-to-object.d.ts.map +1 -1
- package/build/src/http-server/client/params-to-object.js +46 -17
- package/build/src/http-server/client/request-buffer/form-data-part.d.ts +10 -6
- package/build/src/http-server/client/request-buffer/form-data-part.d.ts.map +1 -1
- package/build/src/http-server/client/request-buffer/form-data-part.js +11 -7
- package/build/src/http-server/client/request-buffer/header.d.ts +1 -0
- package/build/src/http-server/client/request-buffer/header.d.ts.map +1 -1
- package/build/src/http-server/client/request-buffer/header.js +2 -1
- package/build/src/http-server/client/request-buffer/index.d.ts +29 -4
- package/build/src/http-server/client/request-buffer/index.d.ts.map +1 -1
- package/build/src/http-server/client/request-buffer/index.js +43 -9
- package/build/src/http-server/client/request-parser.d.ts +52 -13
- package/build/src/http-server/client/request-parser.d.ts.map +1 -1
- package/build/src/http-server/client/request-parser.js +58 -15
- package/build/src/http-server/client/request-runner.d.ts +5 -1
- package/build/src/http-server/client/request-runner.d.ts.map +1 -1
- package/build/src/http-server/client/request-runner.js +32 -8
- package/build/src/http-server/client/request-timing.d.ts +37 -7
- package/build/src/http-server/client/request-timing.d.ts.map +1 -1
- package/build/src/http-server/client/request-timing.js +32 -8
- package/build/src/http-server/client/request.d.ts +15 -5
- package/build/src/http-server/client/request.d.ts.map +1 -1
- package/build/src/http-server/client/request.js +17 -5
- package/build/src/http-server/client/response.d.ts +22 -4
- package/build/src/http-server/client/response.d.ts.map +1 -1
- package/build/src/http-server/client/response.js +29 -7
- package/build/src/http-server/client/uploaded-file/memory-uploaded-file.d.ts +1 -0
- package/build/src/http-server/client/uploaded-file/memory-uploaded-file.d.ts.map +1 -1
- package/build/src/http-server/client/uploaded-file/memory-uploaded-file.js +3 -1
- package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.d.ts +1 -0
- package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.d.ts.map +1 -1
- package/build/src/http-server/client/uploaded-file/temporary-uploaded-file.js +3 -1
- package/build/src/http-server/client/uploaded-file/uploaded-file.d.ts +2 -0
- package/build/src/http-server/client/uploaded-file/uploaded-file.d.ts.map +1 -1
- package/build/src/http-server/client/uploaded-file/uploaded-file.js +3 -1
- package/build/src/http-server/client/websocket-request.d.ts +24 -12
- package/build/src/http-server/client/websocket-request.d.ts.map +1 -1
- package/build/src/http-server/client/websocket-request.js +24 -10
- package/build/src/http-server/client/websocket-session.d.ts +101 -62
- package/build/src/http-server/client/websocket-session.d.ts.map +1 -1
- package/build/src/http-server/client/websocket-session.js +118 -61
- package/build/src/http-server/cookie.d.ts +36 -8
- package/build/src/http-server/cookie.d.ts.map +1 -1
- package/build/src/http-server/cookie.js +37 -9
- package/build/src/http-server/development-reloader.d.ts +32 -7
- package/build/src/http-server/development-reloader.d.ts.map +1 -1
- package/build/src/http-server/development-reloader.js +39 -10
- package/build/src/http-server/index.d.ts +102 -25
- package/build/src/http-server/index.d.ts.map +1 -1
- package/build/src/http-server/index.js +117 -32
- package/build/src/http-server/remote-address.d.ts +1 -0
- package/build/src/http-server/remote-address.d.ts.map +1 -1
- package/build/src/http-server/remote-address.js +15 -4
- package/build/src/http-server/server-client.d.ts +37 -8
- package/build/src/http-server/server-client.d.ts.map +1 -1
- package/build/src/http-server/server-client.js +48 -12
- package/build/src/http-server/server-lock.d.ts +76 -0
- package/build/src/http-server/server-lock.d.ts.map +1 -0
- package/build/src/http-server/server-lock.js +164 -0
- package/build/src/http-server/websocket-channel-subscribers.d.ts +13 -8
- package/build/src/http-server/websocket-channel-subscribers.d.ts.map +1 -1
- package/build/src/http-server/websocket-channel-subscribers.js +16 -7
- package/build/src/http-server/websocket-channel.d.ts +13 -11
- package/build/src/http-server/websocket-channel.d.ts.map +1 -1
- package/build/src/http-server/websocket-channel.js +8 -12
- package/build/src/http-server/websocket-connection.d.ts +10 -14
- package/build/src/http-server/websocket-connection.d.ts.map +1 -1
- package/build/src/http-server/websocket-connection.js +8 -12
- package/build/src/http-server/websocket-event-log-store.d.ts +48 -10
- package/build/src/http-server/websocket-event-log-store.d.ts.map +1 -1
- package/build/src/http-server/websocket-event-log-store.js +76 -34
- package/build/src/http-server/websocket-events-host.d.ts +21 -15
- package/build/src/http-server/websocket-events-host.d.ts.map +1 -1
- package/build/src/http-server/websocket-events-host.js +20 -11
- package/build/src/http-server/websocket-events.d.ts +8 -7
- package/build/src/http-server/websocket-events.d.ts.map +1 -1
- package/build/src/http-server/websocket-events.js +6 -5
- package/build/src/http-server/worker-handler/channel-subscriber-dispatch.d.ts +3 -2
- package/build/src/http-server/worker-handler/channel-subscriber-dispatch.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/channel-subscriber-dispatch.js +3 -2
- package/build/src/http-server/worker-handler/in-process.d.ts +18 -18
- package/build/src/http-server/worker-handler/in-process.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/in-process.js +28 -20
- package/build/src/http-server/worker-handler/index.d.ts +39 -20
- package/build/src/http-server/worker-handler/index.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/index.js +34 -14
- package/build/src/http-server/worker-handler/worker-thread.d.ts +31 -15
- package/build/src/http-server/worker-handler/worker-thread.d.ts.map +1 -1
- package/build/src/http-server/worker-handler/worker-thread.js +31 -12
- package/build/src/initializer.d.ts +4 -0
- package/build/src/initializer.d.ts.map +1 -1
- package/build/src/initializer.js +5 -1
- package/build/src/jobs/mail-delivery.d.ts +1 -0
- package/build/src/jobs/mail-delivery.d.ts.map +1 -1
- package/build/src/jobs/mail-delivery.js +2 -1
- package/build/src/logger/base-logger.js +2 -2
- package/build/src/logger/console-logger.d.ts +2 -0
- package/build/src/logger/console-logger.d.ts.map +1 -1
- package/build/src/logger/console-logger.js +3 -1
- package/build/src/logger/file-logger.d.ts +2 -0
- package/build/src/logger/file-logger.d.ts.map +1 -1
- package/build/src/logger/file-logger.js +3 -1
- package/build/src/logger/outputs/array-output.d.ts +21 -5
- package/build/src/logger/outputs/array-output.d.ts.map +1 -1
- package/build/src/logger/outputs/array-output.js +19 -6
- package/build/src/logger/outputs/console-output.d.ts +10 -2
- package/build/src/logger/outputs/console-output.d.ts.map +1 -1
- package/build/src/logger/outputs/console-output.js +8 -3
- package/build/src/logger/outputs/file-output.d.ts +20 -5
- package/build/src/logger/outputs/file-output.d.ts.map +1 -1
- package/build/src/logger/outputs/file-output.js +18 -6
- package/build/src/logger/outputs/stdout-output.d.ts +7 -1
- package/build/src/logger/outputs/stdout-output.d.ts.map +1 -1
- package/build/src/logger/outputs/stdout-output.js +9 -3
- package/build/src/logger.d.ts +28 -13
- package/build/src/logger.d.ts.map +1 -1
- package/build/src/logger.js +60 -23
- package/build/src/mailer/backends/smtp.d.ts +5 -0
- package/build/src/mailer/backends/smtp.d.ts.map +1 -1
- package/build/src/mailer/backends/smtp.js +17 -4
- package/build/src/mailer/base.d.ts +33 -17
- package/build/src/mailer/base.d.ts.map +1 -1
- package/build/src/mailer/base.js +54 -18
- package/build/src/mailer/delivery.d.ts +16 -5
- package/build/src/mailer/delivery.d.ts.map +1 -1
- package/build/src/mailer/delivery.js +18 -7
- package/build/src/mailer/index.d.ts +5 -5
- package/build/src/mailer/index.d.ts.map +1 -1
- package/build/src/mailer/index.js +2 -2
- package/build/src/mailer.d.ts +5 -5
- package/build/src/mailer.d.ts.map +1 -1
- package/build/src/mailer.js +2 -2
- package/build/src/plugins/sqljs-wasm-route-controller.d.ts +4 -1
- package/build/src/plugins/sqljs-wasm-route-controller.d.ts.map +1 -1
- package/build/src/plugins/sqljs-wasm-route-controller.js +11 -4
- package/build/src/plugins/sqljs-wasm-route.d.ts +6 -0
- package/build/src/plugins/sqljs-wasm-route.d.ts.map +1 -1
- package/build/src/plugins/sqljs-wasm-route.js +4 -1
- package/build/src/record-payload-values.d.ts +54 -0
- package/build/src/record-payload-values.d.ts.map +1 -0
- package/build/src/record-payload-values.js +80 -0
- package/build/src/routes/app-routes.d.ts +1 -0
- package/build/src/routes/app-routes.d.ts.map +1 -1
- package/build/src/routes/app-routes.js +2 -1
- package/build/src/routes/base-route.d.ts +52 -16
- package/build/src/routes/base-route.d.ts.map +1 -1
- package/build/src/routes/base-route.js +50 -14
- package/build/src/routes/basic-route.d.ts +1 -0
- package/build/src/routes/basic-route.d.ts.map +1 -1
- package/build/src/routes/basic-route.js +13 -4
- package/build/src/routes/built-in/debug/controller.d.ts +4 -1
- package/build/src/routes/built-in/debug/controller.d.ts.map +1 -1
- package/build/src/routes/built-in/debug/controller.js +5 -2
- package/build/src/routes/get-route.d.ts +1 -0
- package/build/src/routes/get-route.d.ts.map +1 -1
- package/build/src/routes/get-route.js +7 -4
- package/build/src/routes/hooks/frontend-model-command-route-hook.d.ts +1 -0
- package/build/src/routes/hooks/frontend-model-command-route-hook.d.ts.map +1 -1
- package/build/src/routes/hooks/frontend-model-command-route-hook.js +6 -2
- package/build/src/routes/index.d.ts +3 -2
- package/build/src/routes/index.d.ts.map +1 -1
- package/build/src/routes/index.js +10 -4
- package/build/src/routes/namespace-route.d.ts +1 -0
- package/build/src/routes/namespace-route.d.ts.map +1 -1
- package/build/src/routes/namespace-route.js +5 -3
- package/build/src/routes/plugin-routes.d.ts +10 -1
- package/build/src/routes/plugin-routes.d.ts.map +1 -1
- package/build/src/routes/plugin-routes.js +11 -3
- package/build/src/routes/post-route.d.ts +1 -0
- package/build/src/routes/post-route.d.ts.map +1 -1
- package/build/src/routes/post-route.js +7 -4
- package/build/src/routes/resolver.d.ts +20 -5
- package/build/src/routes/resolver.d.ts.map +1 -1
- package/build/src/routes/resolver.js +47 -14
- package/build/src/routes/resource-route.d.ts +6 -1
- package/build/src/routes/resource-route.d.ts.map +1 -1
- package/build/src/routes/resource-route.js +10 -4
- package/build/src/testing/base-expect.d.ts +2 -0
- package/build/src/testing/base-expect.d.ts.map +1 -1
- package/build/src/testing/base-expect.js +3 -1
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.d.ts +33 -5
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.d.ts.map +1 -1
- package/build/src/testing/browser-frontend-model-event-hook-scenarios.js +95 -23
- package/build/src/testing/expect-to-change.d.ts +3 -0
- package/build/src/testing/expect-to-change.d.ts.map +1 -1
- package/build/src/testing/expect-to-change.js +4 -1
- package/build/src/testing/expect-utils.d.ts +22 -16
- package/build/src/testing/expect-utils.d.ts.map +1 -1
- package/build/src/testing/expect-utils.js +62 -30
- package/build/src/testing/expect.d.ts +50 -21
- package/build/src/testing/expect.d.ts.map +1 -1
- package/build/src/testing/expect.js +58 -17
- package/build/src/testing/request-client.d.ts +16 -3
- package/build/src/testing/request-client.d.ts.map +1 -1
- package/build/src/testing/request-client.js +17 -4
- package/build/src/testing/test-files-finder.d.ts +41 -9
- package/build/src/testing/test-files-finder.d.ts.map +1 -1
- package/build/src/testing/test-files-finder.js +42 -10
- package/build/src/testing/test-filter-parser.d.ts +6 -0
- package/build/src/testing/test-filter-parser.d.ts.map +1 -1
- package/build/src/testing/test-filter-parser.js +12 -3
- package/build/src/testing/test-runner.d.ts +102 -6
- package/build/src/testing/test-runner.d.ts.map +1 -1
- package/build/src/testing/test-runner.js +115 -23
- package/build/src/testing/test-suite-splitter.d.ts +7 -0
- package/build/src/testing/test-suite-splitter.d.ts.map +1 -1
- package/build/src/testing/test-suite-splitter.js +7 -2
- package/build/src/testing/test.d.ts +20 -4
- package/build/src/testing/test.d.ts.map +1 -1
- package/build/src/testing/test.js +67 -20
- package/build/src/utils/backtrace-cleaner-node.d.ts.map +1 -1
- package/build/src/utils/backtrace-cleaner-node.js +6 -1
- package/build/src/utils/backtrace-cleaner.d.ts +16 -1
- package/build/src/utils/backtrace-cleaner.d.ts.map +1 -1
- package/build/src/utils/backtrace-cleaner.js +20 -2
- package/build/src/utils/ensure-error.d.ts +3 -2
- package/build/src/utils/ensure-error.d.ts.map +1 -1
- package/build/src/utils/ensure-error.js +3 -2
- package/build/src/utils/event-emitter.d.ts.map +1 -1
- package/build/src/utils/event-emitter.js +2 -2
- package/build/src/utils/file-exists.d.ts +1 -0
- package/build/src/utils/file-exists.d.ts.map +1 -1
- package/build/src/utils/file-exists.js +2 -1
- package/build/src/utils/format-value.d.ts +5 -4
- package/build/src/utils/format-value.d.ts.map +1 -1
- package/build/src/utils/format-value.js +12 -7
- package/build/src/utils/model-scope.d.ts +18 -12
- package/build/src/utils/model-scope.d.ts.map +1 -1
- package/build/src/utils/model-scope.js +19 -11
- package/build/src/utils/nest-callbacks.d.ts +1 -0
- package/build/src/utils/nest-callbacks.d.ts.map +1 -1
- package/build/src/utils/nest-callbacks.js +2 -1
- package/build/src/utils/plain-object.d.ts +7 -0
- package/build/src/utils/plain-object.d.ts.map +1 -0
- package/build/src/utils/plain-object.js +13 -0
- package/build/src/utils/ransack.d.ts +29 -5
- package/build/src/utils/ransack.d.ts.map +1 -1
- package/build/src/utils/ransack.js +136 -49
- package/build/src/utils/rest-args-error.d.ts +1 -0
- package/build/src/utils/rest-args-error.d.ts.map +1 -1
- package/build/src/utils/rest-args-error.js +2 -1
- package/build/src/utils/singularize-model-name.d.ts +1 -0
- package/build/src/utils/singularize-model-name.d.ts.map +1 -1
- package/build/src/utils/singularize-model-name.js +2 -1
- package/build/src/utils/to-import-specifier.d.ts.map +1 -1
- package/build/src/utils/to-import-specifier.js +3 -1
- package/build/src/utils/with-tracked-stack-async-hooks.d.ts +8 -5
- package/build/src/utils/with-tracked-stack-async-hooks.d.ts.map +1 -1
- package/build/src/utils/with-tracked-stack-async-hooks.js +32 -13
- package/build/src/utils/with-tracked-stack.d.ts +9 -5
- package/build/src/utils/with-tracked-stack.d.ts.map +1 -1
- package/build/src/utils/with-tracked-stack.js +19 -8
- package/build/src/velocious-error.d.ts +4 -2
- package/build/src/velocious-error.d.ts.map +1 -1
- package/build/src/velocious-error.js +5 -3
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -2,46 +2,67 @@
|
|
|
2
2
|
import AuthorizationBaseResource from "../authorization/base-resource.js";
|
|
3
3
|
import * as inflection from "inflection";
|
|
4
4
|
/**
|
|
5
|
+
* FrontendModelResourceControllerArgs type.
|
|
5
6
|
* @typedef {object} FrontendModelResourceControllerArgs
|
|
6
7
|
* @property {import("../controller.js").default} controller - Frontend-model controller instance.
|
|
7
8
|
* @property {typeof import("../database/record/index.js").default} modelClass - Backing model class.
|
|
8
9
|
* @property {string} modelName - Model name.
|
|
9
|
-
* @property {Record<string,
|
|
10
|
+
* @property {Record<string, ?>} params - Request params.
|
|
10
11
|
* @property {import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | import("../configuration-types.js").FrontendModelResourceConfiguration} resourceConfiguration - Normalized resource configuration (or raw input shape during early bootstrap).
|
|
11
12
|
*/
|
|
12
13
|
/**
|
|
14
|
+
* FrontendModelResourceAbilityArgs type.
|
|
13
15
|
* @typedef {object} FrontendModelResourceAbilityArgs
|
|
14
16
|
* @property {import("../authorization/ability.js").default} [ability] - Ability instance when the resource is used directly for authorization.
|
|
15
|
-
* @property {Record<string,
|
|
16
|
-
* @property {Record<string,
|
|
17
|
+
* @property {Record<string, ?>} [context] - Ability context.
|
|
18
|
+
* @property {Record<string, ?>} [locals] - Ability locals.
|
|
17
19
|
* @property {typeof import("../database/record/index.js").default} [modelClass] - Optional backing model class override.
|
|
18
20
|
* @property {string} [modelName] - Optional model name override.
|
|
19
|
-
* @property {Record<string,
|
|
21
|
+
* @property {Record<string, ?>} [params] - Optional params override.
|
|
20
22
|
* @property {import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | import("../configuration-types.js").FrontendModelResourceConfiguration} [resourceConfiguration] - Optional normalized resource configuration.
|
|
21
23
|
*/
|
|
22
24
|
/**
|
|
23
25
|
* Base class for backend frontend-model resources.
|
|
24
26
|
*/
|
|
25
27
|
export default class FrontendModelBaseResource extends AuthorizationBaseResource {
|
|
26
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Attributes.
|
|
30
|
+
@type {Record<string, ?> | string[] | undefined} */
|
|
27
31
|
static attributes = undefined;
|
|
28
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Abilities.
|
|
34
|
+
@type {string[] | undefined} */
|
|
29
35
|
static abilities = undefined;
|
|
30
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Attachments.
|
|
38
|
+
@type {Record<string, ?> | undefined} */
|
|
31
39
|
static attachments = undefined;
|
|
32
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Collection commands.
|
|
42
|
+
@type {string[] | undefined} */
|
|
33
43
|
static collectionCommands = undefined;
|
|
34
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Built in collection commands.
|
|
46
|
+
@type {string[] | undefined} */
|
|
35
47
|
static builtInCollectionCommands = undefined;
|
|
36
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* Member commands.
|
|
50
|
+
@type {string[] | undefined} */
|
|
37
51
|
static memberCommands = undefined;
|
|
38
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Built in member commands.
|
|
54
|
+
@type {string[] | undefined} */
|
|
39
55
|
static builtInMemberCommands = undefined;
|
|
40
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* Relationships.
|
|
58
|
+
@type {string[] | undefined} */
|
|
41
59
|
static relationships = undefined;
|
|
42
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* Translated attributes.
|
|
62
|
+
@type {string[] | undefined} */
|
|
43
63
|
static translatedAttributes = undefined;
|
|
44
64
|
/**
|
|
65
|
+
* Runs constructor.
|
|
45
66
|
* @param {FrontendModelResourceAbilityArgs | FrontendModelResourceControllerArgs} args - Resource args.
|
|
46
67
|
*/
|
|
47
68
|
constructor(args) {
|
|
@@ -51,27 +72,39 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
51
72
|
locals: "locals" in args ? args.locals || {} : {}
|
|
52
73
|
});
|
|
53
74
|
this.controller = "controller" in args ? args.controller : undefined;
|
|
54
|
-
this.modelClassValue = "modelClass" in args ? args.modelClass : /**
|
|
75
|
+
this.modelClassValue = "modelClass" in args ? args.modelClass : /**
|
|
76
|
+
* Narrows the runtime value to the documented type.
|
|
77
|
+
@type {typeof import("../database/record/index.js").default | undefined} */
|
|
78
|
+
( /**
|
|
79
|
+
* Narrows the runtime value to the documented type.
|
|
80
|
+
@type {typeof FrontendModelBaseResource} */(this.constructor).modelClass());
|
|
55
81
|
this.modelNameValue = "modelName" in args ? args.modelName : (this.modelClassValue?.getModelName ? this.modelClassValue.getModelName() : this.modelClassValue?.name || "");
|
|
56
82
|
this.paramsValue = "params" in args ? args.params : undefined;
|
|
57
|
-
this.resourceConfigurationValue = "resourceConfiguration" in args ? args.resourceConfiguration : /**
|
|
83
|
+
this.resourceConfigurationValue = "resourceConfiguration" in args ? args.resourceConfiguration : /**
|
|
84
|
+
* Narrows the runtime value to the documented type.
|
|
85
|
+
@type {import("../configuration-types.js").FrontendModelResourceConfiguration} */
|
|
86
|
+
({ attributes: [] });
|
|
58
87
|
}
|
|
59
88
|
/**
|
|
89
|
+
* Runs typed controller instance.
|
|
60
90
|
* @returns {import("../controller.js").default & {
|
|
61
|
-
* frontendModelAuthorizedQuery: (action: "index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url") => import("../database/query/model-class-query.js").default<
|
|
62
|
-
* frontendModelIndexQuery: () => import("../database/query/model-class-query.js").default<
|
|
91
|
+
* frontendModelAuthorizedQuery: (action: "index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url") => import("../database/query/model-class-query.js").default<unknown>,
|
|
92
|
+
* frontendModelIndexQuery: () => import("../database/query/model-class-query.js").default<unknown>,
|
|
63
93
|
* frontendModelPreload: () => import("../database/query/index.js").NestedPreloadRecord | null,
|
|
64
|
-
* serializeFrontendModel: (model: import("../database/record/index.js").default) => Promise<Record<string,
|
|
94
|
+
* serializeFrontendModel: (model: import("../database/record/index.js").default) => Promise<Record<string, unknown>>
|
|
65
95
|
* }} - Controller instance with frontend-model helpers.
|
|
66
96
|
*/
|
|
67
97
|
typedControllerInstance() {
|
|
68
|
-
return /** @type {
|
|
98
|
+
return /** Narrows the runtime value to the documented type. @type {?} */ (this.controller);
|
|
69
99
|
}
|
|
70
100
|
/**
|
|
101
|
+
* Runs resource config.
|
|
71
102
|
* @returns {import("../configuration-types.js").FrontendModelResourceConfiguration} - Static resource config (raw user input shape; consumers normalize).
|
|
72
103
|
*/
|
|
73
104
|
static resourceConfig() {
|
|
74
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Config.
|
|
107
|
+
@type {import("../configuration-types.js").FrontendModelResourceConfiguration} */
|
|
75
108
|
const config = {
|
|
76
109
|
attributes: this.attributes || []
|
|
77
110
|
};
|
|
@@ -91,28 +124,43 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
91
124
|
config.relationships = this.relationships;
|
|
92
125
|
return config;
|
|
93
126
|
}
|
|
94
|
-
/**
|
|
127
|
+
/**
|
|
128
|
+
* Runs controller instance.
|
|
129
|
+
* @returns {import("../controller.js").default} - Controller instance.
|
|
130
|
+
*/
|
|
95
131
|
controllerInstance() {
|
|
96
132
|
if (!this.controller)
|
|
97
133
|
throw new Error(`${this.constructor.name} requires a controller instance.`);
|
|
98
134
|
return this.controller;
|
|
99
135
|
}
|
|
100
|
-
/**
|
|
136
|
+
/**
|
|
137
|
+
* Runs model class.
|
|
138
|
+
* @returns {typeof import("../database/record/index.js").default} - Model class.
|
|
139
|
+
*/
|
|
101
140
|
modelClass() {
|
|
102
141
|
if (!this.modelClassValue) {
|
|
103
142
|
throw new Error(`${this.constructor.name} requires a model class.`);
|
|
104
143
|
}
|
|
105
144
|
return this.modelClassValue;
|
|
106
145
|
}
|
|
107
|
-
/**
|
|
146
|
+
/**
|
|
147
|
+
* Runs model name.
|
|
148
|
+
* @returns {string} - Model name.
|
|
149
|
+
*/
|
|
108
150
|
modelName() {
|
|
109
151
|
if (!this.modelNameValue)
|
|
110
152
|
throw new Error(`${this.constructor.name} requires a model name.`);
|
|
111
153
|
return this.modelNameValue;
|
|
112
154
|
}
|
|
113
|
-
/**
|
|
155
|
+
/**
|
|
156
|
+
* Runs params.
|
|
157
|
+
* @returns {Record<string, ?>} - Params.
|
|
158
|
+
*/
|
|
114
159
|
params() { return this.paramsValue || super.params() || {}; }
|
|
115
|
-
/**
|
|
160
|
+
/**
|
|
161
|
+
* Runs resource configuration.
|
|
162
|
+
* @returns {import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | import("../configuration-types.js").FrontendModelResourceConfiguration} - Resource config (normalized at runtime; raw during early bootstrap).
|
|
163
|
+
*/
|
|
116
164
|
resourceConfiguration() {
|
|
117
165
|
if (!this.resourceConfigurationValue)
|
|
118
166
|
throw new Error(`${this.constructor.name} requires a resource configuration.`);
|
|
@@ -153,23 +201,28 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
153
201
|
* Default implementation returns `[]` — nothing permitted. Subclasses
|
|
154
202
|
* must override to enable writes. A resource that does not declare
|
|
155
203
|
* `permittedParams` cannot accept any write.
|
|
156
|
-
* @param {{action?: "create" | "update", params?: Record<string,
|
|
157
|
-
* @returns {Array<string | Record<string,
|
|
204
|
+
* @param {{action?: "create" | "update", params?: Record<string, ?>, ability?: import("../authorization/ability.js").default, locals?: Record<string, ?>}} [arg] - Request context.
|
|
205
|
+
* @returns {Array<string | Record<string, ?>>} - Permit spec.
|
|
158
206
|
*/
|
|
159
207
|
permittedParams(arg) {
|
|
160
208
|
void arg;
|
|
161
209
|
return [];
|
|
162
210
|
}
|
|
163
|
-
/**
|
|
211
|
+
/**
|
|
212
|
+
* Runs primary key.
|
|
213
|
+
* @returns {string} - Primary key.
|
|
214
|
+
*/
|
|
164
215
|
primaryKey() { return this.modelClass().primaryKey(); }
|
|
165
216
|
/**
|
|
217
|
+
* Runs authorized query.
|
|
166
218
|
* @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Ability action.
|
|
167
|
-
* @returns {import("../database/query/model-class-query.js").default
|
|
219
|
+
* @returns {import("../database/query/model-class-query.js").default<?>} - Authorized query.
|
|
168
220
|
*/
|
|
169
221
|
authorizedQuery(action) {
|
|
170
222
|
return this.typedControllerInstance().frontendModelAuthorizedQuery(action);
|
|
171
223
|
}
|
|
172
224
|
/**
|
|
225
|
+
* Runs supports pluck.
|
|
173
226
|
* @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Action.
|
|
174
227
|
* @returns {boolean | Promise<boolean>} - Whether pluck is supported.
|
|
175
228
|
*/
|
|
@@ -178,6 +231,7 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
178
231
|
return Object.getPrototypeOf(this).records === FrontendModelBaseResource.prototype.records;
|
|
179
232
|
}
|
|
180
233
|
/**
|
|
234
|
+
* Runs supports count.
|
|
181
235
|
* @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Action.
|
|
182
236
|
* @returns {boolean | Promise<boolean>} - Whether count is supported.
|
|
183
237
|
*/
|
|
@@ -187,6 +241,7 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
187
241
|
Object.getPrototypeOf(this).count !== FrontendModelBaseResource.prototype.count;
|
|
188
242
|
}
|
|
189
243
|
/**
|
|
244
|
+
* Runs before action.
|
|
190
245
|
* @param {"index" | "find" | "create" | "update" | "destroy" | "attach" | "download" | "url"} action - Action.
|
|
191
246
|
* @returns {boolean | void | Promise<boolean | void>} - Continue processing unless false.
|
|
192
247
|
*/
|
|
@@ -195,18 +250,21 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
195
250
|
// No-op by default.
|
|
196
251
|
}
|
|
197
252
|
/**
|
|
253
|
+
* Runs records.
|
|
198
254
|
* @returns {Promise<import("../database/record/index.js").default[]>} - Records for index action.
|
|
199
255
|
*/
|
|
200
256
|
async records() {
|
|
201
257
|
return await this.typedControllerInstance().frontendModelIndexQuery().toArray();
|
|
202
258
|
}
|
|
203
259
|
/**
|
|
260
|
+
* Runs count.
|
|
204
261
|
* @returns {Promise<number>} - Records count for index action.
|
|
205
262
|
*/
|
|
206
263
|
async count() {
|
|
207
264
|
return await this.typedControllerInstance().frontendModelIndexQuery().count();
|
|
208
265
|
}
|
|
209
266
|
/**
|
|
267
|
+
* Runs find.
|
|
210
268
|
* @param {"find" | "update" | "destroy" | "attach" | "download" | "url"} action - Action.
|
|
211
269
|
* @param {string | number} id - Record id.
|
|
212
270
|
* @returns {Promise<import("../database/record/index.js").default | null>} - Located model.
|
|
@@ -220,8 +278,9 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
220
278
|
return await query.findBy({ [this.primaryKey()]: id });
|
|
221
279
|
}
|
|
222
280
|
/**
|
|
223
|
-
*
|
|
224
|
-
* @param {
|
|
281
|
+
* Runs create.
|
|
282
|
+
* @param {Record<string, ?>} attributes - Create attributes.
|
|
283
|
+
* @param {{controller?: ?, nestedAttributes?: Record<string, ?> | null}} [options] - Save options.
|
|
225
284
|
* @returns {Promise<import("../database/record/index.js").default>} - Created model.
|
|
226
285
|
*/
|
|
227
286
|
async create(attributes, options = {}) {
|
|
@@ -240,6 +299,7 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
240
299
|
return model;
|
|
241
300
|
}
|
|
242
301
|
/**
|
|
302
|
+
* Runs handle unauthorized created model.
|
|
243
303
|
* @param {import("../database/record/index.js").default} model - Created model.
|
|
244
304
|
* @returns {Promise<void>} - Cleanup after failed authorization.
|
|
245
305
|
*/
|
|
@@ -247,9 +307,10 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
247
307
|
await model.destroy();
|
|
248
308
|
}
|
|
249
309
|
/**
|
|
310
|
+
* Runs update.
|
|
250
311
|
* @param {import("../database/record/index.js").default} model - Existing model.
|
|
251
|
-
* @param {Record<string,
|
|
252
|
-
* @param {{controller?:
|
|
312
|
+
* @param {Record<string, ?>} attributes - Update attributes.
|
|
313
|
+
* @param {{controller?: ?, nestedAttributes?: Record<string, ?> | null}} [options] - Save options.
|
|
253
314
|
* @returns {Promise<import("../database/record/index.js").default>} - Updated model.
|
|
254
315
|
*/
|
|
255
316
|
async update(model, attributes, options = {}) {
|
|
@@ -268,19 +329,30 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
268
329
|
}
|
|
269
330
|
/**
|
|
270
331
|
* Assigns attributes to a model, using virtual setters on the resource when available.
|
|
271
|
-
*
|
|
272
332
|
* @param {import("../database/record/index.js").default} model - Model instance.
|
|
273
|
-
* @param {Record<string,
|
|
333
|
+
* @param {Record<string, ?>} attributes - Attributes to assign.
|
|
274
334
|
* @returns {Promise<void>}
|
|
275
335
|
*/
|
|
276
336
|
async _assignWithVirtualSetters(model, attributes) {
|
|
277
|
-
/**
|
|
337
|
+
/**
|
|
338
|
+
* Direct attributes.
|
|
339
|
+
@type {Record<string, ?>} */
|
|
278
340
|
const directAttributes = {};
|
|
279
|
-
const translatedSet = new Set(/**
|
|
341
|
+
const translatedSet = new Set(/**
|
|
342
|
+
* Narrows the runtime value to the documented type.
|
|
343
|
+
@type {typeof FrontendModelBaseResource} */ (this.constructor).translatedAttributes || []);
|
|
280
344
|
for (const [name, value] of Object.entries(attributes)) {
|
|
281
345
|
const resourceSetterName = `set${inflection.camelize(name)}Attribute`;
|
|
282
|
-
if (typeof /**
|
|
283
|
-
|
|
346
|
+
if (typeof /**
|
|
347
|
+
* Narrows the runtime value to the documented type.
|
|
348
|
+
@type {Record<string, ?>} */ ( /**
|
|
349
|
+
* Narrows the runtime value to the documented type.
|
|
350
|
+
@type {?} */(this))[resourceSetterName] === "function") {
|
|
351
|
+
await /**
|
|
352
|
+
* Narrows the runtime value to the documented type.
|
|
353
|
+
@type {Record<string, ?>} */ ( /**
|
|
354
|
+
* Narrows the runtime value to the documented type.
|
|
355
|
+
@type {?} */(this))[resourceSetterName](model, value);
|
|
284
356
|
}
|
|
285
357
|
else if (translatedSet.has(name)) {
|
|
286
358
|
await this._setTranslatedAttributeOnModel(model, name, value);
|
|
@@ -295,21 +367,24 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
295
367
|
}
|
|
296
368
|
/**
|
|
297
369
|
* Sets a translated attribute on a model via the translations relationship.
|
|
298
|
-
*
|
|
299
370
|
* @param {import("../database/record/index.js").default} model - Model instance.
|
|
300
371
|
* @param {string} name - Attribute name.
|
|
301
|
-
* @param {
|
|
372
|
+
* @param {?} value - Attribute value.
|
|
302
373
|
* @returns {Promise<void>}
|
|
303
374
|
*/
|
|
304
375
|
async _setTranslatedAttributeOnModel(model, name, value) {
|
|
305
376
|
const locale = this.context?.configuration?.getLocale?.() || "en";
|
|
306
377
|
const instanceRelationship = model.getRelationshipByName("translations");
|
|
307
|
-
/**
|
|
378
|
+
/**
|
|
379
|
+
* Defines translation.
|
|
380
|
+
@type {import("../database/record/index.js").default | undefined} */
|
|
308
381
|
let translation;
|
|
309
382
|
if (model.isNewRecord()) {
|
|
310
383
|
const loaded = instanceRelationship.loaded();
|
|
311
384
|
if (Array.isArray(loaded)) {
|
|
312
|
-
translation = loaded.find((/**
|
|
385
|
+
translation = loaded.find((/**
|
|
386
|
+
* Narrows the runtime value to the documented type.
|
|
387
|
+
@type {Record<string, ?>} */ t) => t.locale() === locale);
|
|
313
388
|
}
|
|
314
389
|
}
|
|
315
390
|
else {
|
|
@@ -318,18 +393,23 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
318
393
|
}
|
|
319
394
|
const loaded = instanceRelationship.loaded();
|
|
320
395
|
if (Array.isArray(loaded)) {
|
|
321
|
-
translation = loaded.find((/**
|
|
396
|
+
translation = loaded.find((/**
|
|
397
|
+
* Narrows the runtime value to the documented type.
|
|
398
|
+
@type {Record<string, ?>} */ t) => t.locale() === locale);
|
|
322
399
|
}
|
|
323
400
|
}
|
|
324
401
|
if (!translation) {
|
|
325
402
|
translation = instanceRelationship.build({ locale });
|
|
326
403
|
}
|
|
327
|
-
/**
|
|
404
|
+
/**
|
|
405
|
+
* Assignments.
|
|
406
|
+
@type {Record<string, ?>} */
|
|
328
407
|
const assignments = {};
|
|
329
408
|
assignments[name] = value;
|
|
330
409
|
translation.assign(assignments);
|
|
331
410
|
}
|
|
332
411
|
/**
|
|
412
|
+
* Runs destroy.
|
|
333
413
|
* @param {import("../database/record/index.js").default} model - Existing model.
|
|
334
414
|
* @returns {Promise<void>} - No return value.
|
|
335
415
|
*/
|
|
@@ -337,9 +417,10 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
337
417
|
await model.destroy();
|
|
338
418
|
}
|
|
339
419
|
/**
|
|
420
|
+
* Runs serialize.
|
|
340
421
|
* @param {import("../database/record/index.js").default} model - Model to serialize.
|
|
341
422
|
* @param {"index" | "find" | "create" | "update"} [action] - Action.
|
|
342
|
-
* @returns {Promise<Record<string,
|
|
423
|
+
* @returns {Promise<Record<string, ?>>} - Serialized model payload.
|
|
343
424
|
*/
|
|
344
425
|
async serialize(model, action) {
|
|
345
426
|
void action;
|
|
@@ -358,9 +439,9 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
358
439
|
* (allowDestroy, limit, rejectIf) come from the MODEL's
|
|
359
440
|
* `acceptedNestedAttributesFor(name)` declaration.
|
|
360
441
|
* @param {import("../database/record/index.js").default} parent - Parent model instance.
|
|
361
|
-
* @param {Record<string,
|
|
362
|
-
* @param {
|
|
363
|
-
* @param {{attributes: string[], nested: Record<string,
|
|
442
|
+
* @param {Record<string, ?>} nestedAttributes - Nested-attribute payload keyed by relationship name.
|
|
443
|
+
* @param {?} controller - Controller instance for resource resolution and authorization.
|
|
444
|
+
* @param {{attributes: string[], nested: Record<string, ?>} | null} [parentPermit] - Parsed parent permit spec.
|
|
364
445
|
* @returns {Promise<void>}
|
|
365
446
|
*/
|
|
366
447
|
async _applyNestedAttributes(parent, nestedAttributes, controller, parentPermit = null) {
|
|
@@ -375,7 +456,9 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
375
456
|
if (!Array.isArray(entries)) {
|
|
376
457
|
throw new Error(`Expected array for nestedAttributes['${relationshipName}'] but got: ${typeof entries}`);
|
|
377
458
|
}
|
|
378
|
-
const parentModelClass = /**
|
|
459
|
+
const parentModelClass = /**
|
|
460
|
+
* Narrows the runtime value to the documented type.
|
|
461
|
+
@type {?} */ (parent.getModelClass());
|
|
379
462
|
const modelAcceptance = parentModelClass.acceptedNestedAttributesFor?.(relationshipName);
|
|
380
463
|
if (!modelAcceptance) {
|
|
381
464
|
throw new Error(`Model ${parentModelClass.name} does not accept nested attributes for '${relationshipName}'. Declare it via ${parentModelClass.name}.acceptsNestedAttributesFor('${relationshipName}').`);
|
|
@@ -393,7 +476,9 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
393
476
|
if (!definition || definition.type !== "hasMany") {
|
|
394
477
|
throw new Error(`Nested attributes for '${relationshipName}' require a hasMany relationship. v1 does not support '${definition?.type}'.`);
|
|
395
478
|
}
|
|
396
|
-
const targetModelClass = /**
|
|
479
|
+
const targetModelClass = /**
|
|
480
|
+
* Narrows the runtime value to the documented type.
|
|
481
|
+
@type {?} */ (parent.getModelClass()).relationshipModelClass?.(relationshipName);
|
|
397
482
|
if (!targetModelClass) {
|
|
398
483
|
throw new Error(`No target model class resolved for relationship '${relationshipName}' on ${parent.getModelClass().name}.`);
|
|
399
484
|
}
|
|
@@ -438,7 +523,9 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
438
523
|
// The permit's attribute list governs what child fields can be written.
|
|
439
524
|
// Exclude `_destroy` from the writable set since it's a control flag,
|
|
440
525
|
// not an attribute on the record.
|
|
441
|
-
const childWritableAttributes = /**
|
|
526
|
+
const childWritableAttributes = /**
|
|
527
|
+
* Narrows the runtime value to the documented type.
|
|
528
|
+
@type {string[]} */ (childPermit.attributes).filter((name) => name !== "_destroy");
|
|
442
529
|
for (const entry of destroyEntries) {
|
|
443
530
|
const existing = await this._findScopedChild({
|
|
444
531
|
ability,
|
|
@@ -465,18 +552,24 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
465
552
|
});
|
|
466
553
|
if (entry.attributes && typeof entry.attributes === "object") {
|
|
467
554
|
const filtered = filterWritableFrontendModelAttributes(existing, entry.attributes, childResource, childWritableAttributes);
|
|
468
|
-
await /**
|
|
555
|
+
await /**
|
|
556
|
+
* Narrows the runtime value to the documented type.
|
|
557
|
+
@type {?} */ (childResource)._assignWithVirtualSetters(existing, filtered);
|
|
469
558
|
await existing.save();
|
|
470
559
|
}
|
|
471
560
|
if (entry.nestedAttributes) {
|
|
472
|
-
await /**
|
|
561
|
+
await /**
|
|
562
|
+
* Narrows the runtime value to the documented type.
|
|
563
|
+
@type {?} */ (childResource)._applyNestedAttributes(existing, entry.nestedAttributes, controller, childPermit);
|
|
473
564
|
}
|
|
474
565
|
}
|
|
475
566
|
for (const entry of createEntries) {
|
|
476
567
|
const childAttributes = entry?.attributes && typeof entry.attributes === "object" ? entry.attributes : {};
|
|
477
568
|
const child = parentRelationship.build({ ...childAttributes, [foreignKey]: parent.id() });
|
|
478
569
|
const filtered = filterWritableFrontendModelAttributes(child, childAttributes, childResource, childWritableAttributes);
|
|
479
|
-
await /**
|
|
570
|
+
await /**
|
|
571
|
+
* Narrows the runtime value to the documented type.
|
|
572
|
+
@type {?} */ (childResource)._assignWithVirtualSetters(child, filtered);
|
|
480
573
|
await child.save();
|
|
481
574
|
await this._authorizeCreatedChild({
|
|
482
575
|
ability,
|
|
@@ -486,7 +579,9 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
486
579
|
targetModelClass
|
|
487
580
|
});
|
|
488
581
|
if (entry.nestedAttributes) {
|
|
489
|
-
await /**
|
|
582
|
+
await /**
|
|
583
|
+
* Narrows the runtime value to the documented type.
|
|
584
|
+
@type {?} */ (childResource)._applyNestedAttributes(child, entry.nestedAttributes, controller, childPermit);
|
|
490
585
|
}
|
|
491
586
|
}
|
|
492
587
|
}
|
|
@@ -496,7 +591,6 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
496
591
|
* `abilities` mapping — never the parent controller's. This preserves
|
|
497
592
|
* custom mappings like `{update: "manage"}` and catches unmapped actions
|
|
498
593
|
* instead of silently defaulting to the raw action name.
|
|
499
|
-
*
|
|
500
594
|
* @param {import("../configuration-types.js").FrontendModelResourceConfiguration} childResourceConfiguration - Child resource configuration.
|
|
501
595
|
* @param {"create" | "update" | "destroy"} action - Frontend action.
|
|
502
596
|
* @returns {string} - Ability action for the child resource.
|
|
@@ -506,7 +600,9 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
506
600
|
if (!abilities || typeof abilities !== "object" || Array.isArray(abilities)) {
|
|
507
601
|
throw new Error(`Nested child resource must define an 'abilities' object to authorize nested ${action}.`);
|
|
508
602
|
}
|
|
509
|
-
const abilityAction = /**
|
|
603
|
+
const abilityAction = /**
|
|
604
|
+
* Narrows the runtime value to the documented type.
|
|
605
|
+
@type {Record<string, string>} */ (abilities)[action];
|
|
510
606
|
if (typeof abilityAction !== "string" || abilityAction.length < 1) {
|
|
511
607
|
throw new Error(`Nested child resource must define abilities.${action}.`);
|
|
512
608
|
}
|
|
@@ -518,7 +614,6 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
518
614
|
* resource's ability mapping for the requested action. Throws when the
|
|
519
615
|
* child does not exist, does not belong to the current parent, or is
|
|
520
616
|
* not authorized — all of which must roll the transaction back.
|
|
521
|
-
*
|
|
522
617
|
* @param {object} args - Arguments.
|
|
523
618
|
* @param {import("../authorization/ability.js").default | undefined} args.ability - Current ability.
|
|
524
619
|
* @param {"update" | "destroy"} args.action - Frontend action.
|
|
@@ -534,8 +629,14 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
534
629
|
const primaryKey = targetModelClass.primaryKey();
|
|
535
630
|
const lookup = { [primaryKey]: id, [foreignKey]: parent.id() };
|
|
536
631
|
const query = ability
|
|
537
|
-
? /**
|
|
538
|
-
|
|
632
|
+
? /**
|
|
633
|
+
* Narrows the runtime value to the documented type.
|
|
634
|
+
@type {?} */
|
|
635
|
+
(targetModelClass).accessibleFor(this._resolveChildAbilityAction(childResourceConfiguration, action), ability)
|
|
636
|
+
: /**
|
|
637
|
+
* Narrows the runtime value to the documented type.
|
|
638
|
+
@type {?} */
|
|
639
|
+
(targetModelClass).where({});
|
|
539
640
|
const existing = await query.findBy(lookup);
|
|
540
641
|
if (!existing) {
|
|
541
642
|
throw new Error(`Cannot ${action} nested ${relationshipName}[id=${id}]: record not found, does not belong to parent ${parent.getModelClass().name}[id=${parent.id()}], or is not authorized.`);
|
|
@@ -546,7 +647,6 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
546
647
|
* Verifies an already-saved nested child is authorized under the child
|
|
547
648
|
* resource's own `create` ability. Rolls back via thrown error when not
|
|
548
649
|
* authorized so the outer transaction destroys the insert.
|
|
549
|
-
*
|
|
550
650
|
* @param {object} args - Arguments.
|
|
551
651
|
* @param {import("../authorization/ability.js").default | undefined} args.ability - Current ability.
|
|
552
652
|
* @param {import("../database/record/index.js").default} args.child - Child model instance just created.
|
|
@@ -560,7 +660,9 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
560
660
|
return;
|
|
561
661
|
const abilityAction = this._resolveChildAbilityAction(childResourceConfiguration, "create");
|
|
562
662
|
const primaryKey = targetModelClass.primaryKey();
|
|
563
|
-
const authorizedIds = await /**
|
|
663
|
+
const authorizedIds = await /**
|
|
664
|
+
* Narrows the runtime value to the documented type.
|
|
665
|
+
@type {?} */ (targetModelClass)
|
|
564
666
|
.accessibleFor(abilityAction, ability)
|
|
565
667
|
.where({ [primaryKey]: child.readAttribute(primaryKey) })
|
|
566
668
|
.pluck(primaryKey);
|
|
@@ -570,7 +672,6 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
570
672
|
}
|
|
571
673
|
/**
|
|
572
674
|
* Best-effort foreign-key inference for relationships that don't declare it.
|
|
573
|
-
*
|
|
574
675
|
* @param {import("../database/record/index.js").default} parent - Parent model.
|
|
575
676
|
* @param {{foreignKey?: string}} definition - Relationship definition.
|
|
576
677
|
* @returns {string} - Foreign-key attribute name.
|
|
@@ -586,9 +687,8 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
586
687
|
* After nested writes, preload every relationship declared in the
|
|
587
688
|
* parent's permit so the post-save serialize step emits them and the
|
|
588
689
|
* client can reconcile ids.
|
|
589
|
-
*
|
|
590
690
|
* @param {import("../database/record/index.js").default} model - Saved parent model.
|
|
591
|
-
* @param {{attributes: string[], nested: Record<string,
|
|
691
|
+
* @param {{attributes: string[], nested: Record<string, ?>}} permit - Parsed parent permit.
|
|
592
692
|
* @returns {Promise<void>}
|
|
593
693
|
*/
|
|
594
694
|
async _preloadNestedWritableRelationships(model, permit) {
|
|
@@ -596,8 +696,12 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
596
696
|
if (relationshipNames.length === 0)
|
|
597
697
|
return;
|
|
598
698
|
for (const relationshipName of relationshipNames) {
|
|
599
|
-
if (typeof /**
|
|
600
|
-
|
|
699
|
+
if (typeof /**
|
|
700
|
+
* Narrows the runtime value to the documented type.
|
|
701
|
+
@type {?} */ (model).loadRelationship === "function") {
|
|
702
|
+
await /**
|
|
703
|
+
* Narrows the runtime value to the documented type.
|
|
704
|
+
@type {?} */ (model).loadRelationship(relationshipName);
|
|
601
705
|
}
|
|
602
706
|
}
|
|
603
707
|
}
|
|
@@ -618,13 +722,17 @@ export default class FrontendModelBaseResource extends AuthorizationBaseResource
|
|
|
618
722
|
* // tasks: {attributes: ["id", "_destroy", "name"], nested: {}}
|
|
619
723
|
* // }
|
|
620
724
|
* // }
|
|
621
|
-
* @param {Array<string | Record<string,
|
|
622
|
-
* @returns {{attributes: string[], nested: Record<string, {attributes: string[], nested: Record<string,
|
|
725
|
+
* @param {Array<string | Record<string, ?>> | undefined} permitSpec - Flat permit spec.
|
|
726
|
+
* @returns {{attributes: string[], nested: Record<string, {attributes: string[], nested: Record<string, ?>}>}} - Parsed structure.
|
|
623
727
|
*/
|
|
624
728
|
function parsePermittedParams(permitSpec) {
|
|
625
|
-
/**
|
|
729
|
+
/**
|
|
730
|
+
* Attributes.
|
|
731
|
+
@type {string[]} */
|
|
626
732
|
const attributes = [];
|
|
627
|
-
/**
|
|
733
|
+
/**
|
|
734
|
+
* Nested.
|
|
735
|
+
@type {Record<string, {attributes: string[], nested: Record<string, ?>}>} */
|
|
628
736
|
const nested = {};
|
|
629
737
|
if (!Array.isArray(permitSpec))
|
|
630
738
|
return { attributes, nested };
|
|
@@ -654,23 +762,34 @@ function parsePermittedParams(permitSpec) {
|
|
|
654
762
|
return { attributes, nested };
|
|
655
763
|
}
|
|
656
764
|
/**
|
|
657
|
-
*
|
|
658
|
-
* @param {Record<string,
|
|
765
|
+
* Runs filter writable frontend model attributes.
|
|
766
|
+
* @param {Record<string, ?>} receiver - Model instance or prototype.
|
|
767
|
+
* @param {Record<string, ?>} attributes - Incoming frontend-model attributes.
|
|
659
768
|
* @param {FrontendModelBaseResource | null} [resource] - Resource instance for virtual-setter detection.
|
|
660
769
|
* @param {string[] | null} [permittedAttributeNames] - Optional explicit permit list. `null` falls back to setter-existence checks only.
|
|
661
|
-
* @returns {Record<string,
|
|
770
|
+
* @returns {Record<string, ?>} - Writable attributes only.
|
|
662
771
|
*/
|
|
663
|
-
function filterWritableFrontendModelAttributes(receiver, attributes, resource = /**
|
|
772
|
+
function filterWritableFrontendModelAttributes(receiver, attributes, resource = /**
|
|
773
|
+
* Narrows the runtime value to the documented type.
|
|
774
|
+
@type {FrontendModelBaseResource | null} */ (null), permittedAttributeNames = null) {
|
|
664
775
|
// Frontend-model writes should fail fast when callers submit read-only or unknown attrs.
|
|
665
776
|
// Silent drops hide contract mistakes in generated models and app-side wrapper code.
|
|
666
|
-
/**
|
|
777
|
+
/**
|
|
778
|
+
* Writable attributes.
|
|
779
|
+
@type {Record<string, ?>} */
|
|
667
780
|
const writableAttributes = {};
|
|
668
|
-
/**
|
|
781
|
+
/**
|
|
782
|
+
* Invalid attributes.
|
|
783
|
+
@type {string[]} */
|
|
669
784
|
const invalidAttributes = [];
|
|
670
|
-
/**
|
|
785
|
+
/**
|
|
786
|
+
* Not permitted attributes.
|
|
787
|
+
@type {string[]} */
|
|
671
788
|
const notPermittedAttributes = [];
|
|
672
789
|
const permitSet = Array.isArray(permittedAttributeNames) ? new Set(permittedAttributeNames) : null;
|
|
673
|
-
const translatedSet = resource ? new Set(/**
|
|
790
|
+
const translatedSet = resource ? new Set(/**
|
|
791
|
+
* Narrows the runtime value to the documented type.
|
|
792
|
+
@type {typeof FrontendModelBaseResource} */ (resource.constructor).translatedAttributes || []) : new Set();
|
|
674
793
|
for (const [attributeName, value] of Object.entries(attributes)) {
|
|
675
794
|
if (permitSet && !permitSet.has(attributeName)) {
|
|
676
795
|
notPermittedAttributes.push(attributeName);
|
|
@@ -681,7 +800,11 @@ function filterWritableFrontendModelAttributes(receiver, attributes, resource =
|
|
|
681
800
|
if (setterName in receiver) {
|
|
682
801
|
writableAttributes[attributeName] = value;
|
|
683
802
|
}
|
|
684
|
-
else if (resource && typeof /**
|
|
803
|
+
else if (resource && typeof /**
|
|
804
|
+
* Narrows the runtime value to the documented type.
|
|
805
|
+
@type {Record<string, ?>} */ ( /**
|
|
806
|
+
* Narrows the runtime value to the documented type.
|
|
807
|
+
@type {?} */(resource))[resourceSetterName] === "function") {
|
|
685
808
|
writableAttributes[attributeName] = value;
|
|
686
809
|
}
|
|
687
810
|
else if (translatedSet.has(attributeName)) {
|
|
@@ -699,4 +822,4 @@ function filterWritableFrontendModelAttributes(receiver, attributes, resource =
|
|
|
699
822
|
}
|
|
700
823
|
return writableAttributes;
|
|
701
824
|
}
|
|
702
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1yZXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9mcm9udGVuZC1tb2RlbC1yZXNvdXJjZS9iYXNlLXJlc291cmNlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLHlCQUF5QixNQUFNLG1DQUFtQyxDQUFBO0FBQ3pFLE9BQU8sS0FBSyxVQUFVLE1BQU0sWUFBWSxDQUFBO0FBRXhDOzs7Ozs7O0dBT0c7QUFFSDs7Ozs7Ozs7O0dBU0c7QUFFSDs7R0FFRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8seUJBQTBCLFNBQVEseUJBQXlCO0lBQzlFLHlEQUF5RDtJQUN6RCxNQUFNLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQTtJQUM3QixtQ0FBbUM7SUFDbkMsTUFBTSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUE7SUFDNUIsOENBQThDO0lBQzlDLE1BQU0sQ0FBQyxXQUFXLEdBQUcsU0FBUyxDQUFBO0lBQzlCLG1DQUFtQztJQUNuQyxNQUFNLENBQUMsa0JBQWtCLEdBQUcsU0FBUyxDQUFBO0lBQ3JDLG1DQUFtQztJQUNuQyxNQUFNLENBQUMseUJBQXlCLEdBQUcsU0FBUyxDQUFBO0lBQzVDLG1DQUFtQztJQUNuQyxNQUFNLENBQUMsY0FBYyxHQUFHLFNBQVMsQ0FBQTtJQUNqQyxtQ0FBbUM7SUFDbkMsTUFBTSxDQUFDLHFCQUFxQixHQUFHLFNBQVMsQ0FBQTtJQUN4QyxtQ0FBbUM7SUFDbkMsTUFBTSxDQUFDLGFBQWEsR0FBRyxTQUFTLENBQUE7SUFDaEMsbUNBQW1DO0lBQ25DLE1BQU0sQ0FBQyxvQkFBb0IsR0FBRyxTQUFTLENBQUE7SUFFdkM7O09BRUc7SUFDSCxZQUFZLElBQUk7UUFDZCxLQUFLLENBQUM7WUFDSixPQUFPLEVBQUUsU0FBUyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUztZQUNyRCxPQUFPLEVB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cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBBdXRob3JpemF0aW9uQmFzZVJlc291cmNlIGZyb20gXCIuLi9hdXRob3JpemF0aW9uL2Jhc2UtcmVzb3VyY2UuanNcIlxuaW1wb3J0ICogYXMgaW5mbGVjdGlvbiBmcm9tIFwiaW5mbGVjdGlvblwiXG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gRnJvbnRlbmRNb2RlbFJlc291cmNlQ29udHJvbGxlckFyZ3NcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29udHJvbGxlci5qc1wiKS5kZWZhdWx0fSBjb250cm9sbGVyIC0gRnJvbnRlbmQtbW9kZWwgY29udHJvbGxlciBpbnN0YW5jZS5cbiAqIEBwcm9wZXJ0eSB7dHlwZW9mIGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbENsYXNzIC0gQmFja2luZyBtb2RlbCBjbGFzcy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBtb2RlbE5hbWUgLSBNb2RlbCBuYW1lLlxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBwYXJhbXMgLSBSZXF1ZXN0IHBhcmFtcy5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Ob3JtYWxpemVkRnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbiB8IGltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbn0gcmVzb3VyY2VDb25maWd1cmF0aW9uIC0gTm9ybWFsaXplZCByZXNvdXJjZSBjb25maWd1cmF0aW9uIChvciByYXcgaW5wdXQgc2hhcGUgZHVyaW5nIGVhcmx5IGJvb3RzdHJhcCkuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBGcm9udGVuZE1vZGVsUmVzb3VyY2VBYmlsaXR5QXJnc1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9hdXRob3JpemF0aW9uL2FiaWxpdHkuanNcIikuZGVmYXVsdH0gW2FiaWxpdHldIC0gQWJpbGl0eSBpbnN0YW5jZSB3aGVuIHRoZSByZXNvdXJjZSBpcyB1c2VkIGRpcmVjdGx5IGZvciBhdXRob3JpemF0aW9uLlxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBbY29udGV4dF0gLSBBYmlsaXR5IGNvbnRleHQuXG4gKiBAcHJvcGVydHkge1JlY29yZDxzdHJpbmcsIGFueT59IFtsb2NhbHNdIC0gQWJpbGl0eSBsb2NhbHMuXG4gKiBAcHJvcGVydHkge3R5cGVvZiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gW21vZGVsQ2xhc3NdIC0gT3B0aW9uYWwgYmFja2luZyBtb2RlbCBjbGFzcyBvdmVycmlkZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbbW9kZWxOYW1lXSAtIE9wdGlvbmFsIG1vZGVsIG5hbWUgb3ZlcnJpZGUuXG4gKiBAcHJvcGVydHkge1JlY29yZDxzdHJpbmcsIGFueT59IFtwYXJhbXNdIC0gT3B0aW9uYWwgcGFyYW1zIG92ZXJyaWRlLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLk5vcm1hbGl6ZWRGcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uIHwgaW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Gcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9ufSBbcmVzb3VyY2VDb25maWd1cmF0aW9uXSAtIE9wdGlvbmFsIG5vcm1hbGl6ZWQgcmVzb3VyY2UgY29uZmlndXJhdGlvbi5cbiAqL1xuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGJhY2tlbmQgZnJvbnRlbmQtbW9kZWwgcmVzb3VyY2VzLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGcm9udGVuZE1vZGVsQmFzZVJlc291cmNlIGV4dGVuZHMgQXV0aG9yaXphdGlvbkJhc2VSZXNvdXJjZSB7XG4gIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55PiB8IHN0cmluZ1tdIHwgdW5kZWZpbmVkfSAqL1xuICBzdGF0aWMgYXR0cmlidXRlcyA9IHVuZGVmaW5lZFxuICAvKiogQHR5cGUge3N0cmluZ1tdIHwgdW5kZWZpbmVkfSAqL1xuICBzdGF0aWMgYWJpbGl0aWVzID0gdW5kZWZpbmVkXG4gIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55PiB8IHVuZGVmaW5lZH0gKi9cbiAgc3RhdGljIGF0dGFjaG1lbnRzID0gdW5kZWZpbmVkXG4gIC8qKiBAdHlwZSB7c3RyaW5nW10gfCB1bmRlZmluZWR9ICovXG4gIHN0YXRpYyBjb2xsZWN0aW9uQ29tbWFuZHMgPSB1bmRlZmluZWRcbiAgLyoqIEB0eXBlIHtzdHJpbmdbXSB8IHVuZGVmaW5lZH0gKi9cbiAgc3RhdGljIGJ1aWx0SW5Db2xsZWN0aW9uQ29tbWFuZHMgPSB1bmRlZmluZWRcbiAgLyoqIEB0eXBlIHtzdHJpbmdbXSB8IHVuZGVmaW5lZH0gKi9cbiAgc3RhdGljIG1lbWJlckNvbW1hbmRzID0gdW5kZWZpbmVkXG4gIC8qKiBAdHlwZSB7c3RyaW5nW10gfCB1bmRlZmluZWR9ICovXG4gIHN0YXRpYyBidWlsdEluTWVtYmVyQ29tbWFuZHMgPSB1bmRlZmluZWRcbiAgLyoqIEB0eXBlIHtzdHJpbmdbXSB8IHVuZGVmaW5lZH0gKi9cbiAgc3RhdGljIHJlbGF0aW9uc2hpcHMgPSB1bmRlZmluZWRcbiAgLyoqIEB0eXBlIHtzdHJpbmdbXSB8IHVuZGVmaW5lZH0gKi9cbiAgc3RhdGljIHRyYW5zbGF0ZWRBdHRyaWJ1dGVzID0gdW5kZWZpbmVkXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7RnJvbnRlbmRNb2RlbFJlc291cmNlQWJpbGl0eUFyZ3MgfCBGcm9udGVuZE1vZGVsUmVzb3VyY2VDb250cm9sbGVyQXJnc30gYXJncyAtIFJlc291cmNlIGFyZ3MuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihhcmdzKSB7XG4gICAgc3VwZXIoe1xuICAgICAgYWJpbGl0eTogXCJhYmlsaXR5XCIgaW4gYXJncyA/IGFyZ3MuYWJpbGl0eSA6IHVuZGVmaW5lZCxcbiAgICAgIGNvbnRleHQ6IFwiY29udGV4dFwiIGluIGFyZ3MgPyBhcmdzLmNvbnRleHQgfHwge30gOiB7fSxcbiAgICAgIGxvY2FsczogXCJsb2NhbHNcIiBpbiBhcmdzID8gYXJncy5sb2NhbHMgfHwge30gOiB7fVxuICAgIH0pXG5cbiAgICB0aGlzLmNvbnRyb2xsZXIgPSBcImNvbnRyb2xsZXJcIiBpbiBhcmdzID8gYXJncy5jb250cm9sbGVyIDogdW5kZWZpbmVkXG4gICAgdGhpcy5tb2RlbENsYXNzVmFsdWUgPSBcIm1vZGVsQ2xhc3NcIiBpbiBhcmdzID8gYXJncy5tb2RlbENsYXNzIDogLyoqIEB0eXBlIHt0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9ICovICgvKiogQHR5cGUge3R5cGVvZiBGcm9udGVuZE1vZGVsQmFzZVJlc291cmNlfSAqLyAodGhpcy5jb25zdHJ1Y3RvcikubW9kZWxDbGFzcygpKVxuICAgIHRoaXMubW9kZWxOYW1lVmFsdWUgPSBcIm1vZGVsTmFtZVwiIGluIGFyZ3MgPyBhcmdzLm1vZGVsTmFtZSA6ICh0aGlzLm1vZGVsQ2xhc3NWYWx1ZT8uZ2V0TW9kZWxOYW1lID8gdGhpcy5tb2RlbENsYXNzVmFsdWUuZ2V0TW9kZWxOYW1lKCkgOiB0aGlzLm1vZGVsQ2xhc3NWYWx1ZT8ubmFtZSB8fCBcIlwiKVxuICAgIHRoaXMucGFyYW1zVmFsdWUgPSBcInBhcmFtc1wiIGluIGFyZ3MgPyBhcmdzLnBhcmFtcyA6IHVuZGVmaW5lZFxuICAgIHRoaXMucmVzb3VyY2VDb25maWd1cmF0aW9uVmFsdWUgPSBcInJlc291cmNlQ29uZmlndXJhdGlvblwiIGluIGFyZ3MgPyBhcmdzLnJlc291cmNlQ29uZmlndXJhdGlvbiA6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Gcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9ufSAqLyAoe2F0dHJpYnV0ZXM6IFtdfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vY29udHJvbGxlci5qc1wiKS5kZWZhdWx0ICYge1xuICAgKiAgIGZyb250ZW5kTW9kZWxBdXRob3JpemVkUXVlcnk6IChhY3Rpb246IFwiaW5kZXhcIiB8IFwiZmluZFwiIHwgXCJjcmVhdGVcIiB8IFwidXBkYXRlXCIgfCBcImRlc3Ryb3lcIiB8IFwiYXR0YWNoXCIgfCBcImRvd25sb2FkXCIgfCBcInVybFwiKSA9PiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0PGFueT4sXG4gICAqICAgZnJvbnRlbmRNb2RlbEluZGV4UXVlcnk6ICgpID0+IGltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHQ8YW55PixcbiAgICogICBmcm9udGVuZE1vZGVsUHJlbG9hZDogKCkgPT4gaW1wb3J0KFwiLi4vZGF0YWJhc2UvcXVlcnkvaW5kZXguanNcIikuTmVzdGVkUHJlbG9hZFJlY29yZCB8IG51bGwsXG4gICAqICAgc2VyaWFsaXplRnJvbnRlbmRNb2RlbDogKG1vZGVsOiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCkgPT4gUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PlxuICAgKiB9fSAtIENvbnRyb2xsZXIgaW5zdGFuY2Ugd2l0aCBmcm9udGVuZC1tb2RlbCBoZWxwZXJzLlxuICAgKi9cbiAgdHlwZWRDb250cm9sbGVySW5zdGFuY2UoKSB7XG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7YW55fSAqLyAodGhpcy5jb250cm9sbGVyKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb259IC0gU3RhdGljIHJlc291cmNlIGNvbmZpZyAocmF3IHVzZXIgaW5wdXQgc2hhcGU7IGNvbnN1bWVycyBub3JtYWxpemUpLlxuICAgKi9cbiAgc3RhdGljIHJlc291cmNlQ29uZmlnKCkge1xuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Gcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9ufSAqL1xuICAgIGNvbnN0IGNvbmZpZyA9IHtcbiAgICAgIGF0dHJpYnV0ZXM6IHRoaXMuYXR0cmlidXRlcyB8fCBbXVxuICAgIH1cblxuICAgIGlmICh0aGlzLmFiaWxpdGllcykgY29uZmlnLmFiaWxpdGllcyA9IHRoaXMuYWJpbGl0aWVzXG4gICAgaWYgKHRoaXMuYXR0YWNobWVudHMpIGNvbmZpZy5hdHRhY2htZW50cyA9IHRoaXMuYXR0YWNobWVudHNcbiAgICBpZiAodGhpcy5idWlsdEluQ29sbGVjdGlvbkNvbW1hbmRzKSBjb25maWcuYnVpbHRJbkNvbGxlY3Rpb25Db21tYW5kcyA9IHRoaXMuYnVpbHRJbkNvbGxlY3Rpb25Db21tYW5kc1xuICAgIGlmICh0aGlzLmJ1aWx0SW5NZW1iZXJDb21tYW5kcykgY29uZmlnLmJ1aWx0SW5NZW1iZXJDb21tYW5kcyA9IHRoaXMuYnVpbHRJbk1lbWJlckNvbW1hbmRzXG4gICAgaWYgKHRoaXMuY29sbGVjdGlvbkNvbW1hbmRzKSBjb25maWcuY29sbGVjdGlvbkNvbW1hbmRzID0gdGhpcy5jb2xsZWN0aW9uQ29tbWFuZHNcbiAgICBpZiAodGhpcy5tZW1iZXJDb21tYW5kcykgY29uZmlnLm1lbWJlckNvbW1hbmRzID0gdGhpcy5tZW1iZXJDb21tYW5kc1xuICAgIGlmICh0aGlzLnJlbGF0aW9uc2hpcHMpIGNvbmZpZy5yZWxhdGlvbnNoaXBzID0gdGhpcy5yZWxhdGlvbnNoaXBzXG5cbiAgICByZXR1cm4gY29uZmlnXG4gIH1cblxuICAvKiogQHJldHVybnMge2ltcG9ydChcIi4uL2NvbnRyb2xsZXIuanNcIikuZGVmYXVsdH0gLSBDb250cm9sbGVyIGluc3RhbmNlLiAqL1xuICBjb250cm9sbGVySW5zdGFuY2UoKSB7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xsZXIpIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IHJlcXVpcmVzIGEgY29udHJvbGxlciBpbnN0YW5jZS5gKVxuXG4gICAgcmV0dXJuIHRoaXMuY29udHJvbGxlclxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHt0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IC0gTW9kZWwgY2xhc3MuICovXG4gIG1vZGVsQ2xhc3MoKSB7XG4gICAgaWYgKCF0aGlzLm1vZGVsQ2xhc3NWYWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gcmVxdWlyZXMgYSBtb2RlbCBjbGFzcy5gKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm1vZGVsQ2xhc3NWYWx1ZVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtzdHJpbmd9IC0gTW9kZWwgbmFtZS4gKi9cbiAgbW9kZWxOYW1lKCkge1xuICAgIGlmICghdGhpcy5tb2RlbE5hbWVWYWx1ZSkgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gcmVxdWlyZXMgYSBtb2RlbCBuYW1lLmApXG5cbiAgICByZXR1cm4gdGhpcy5tb2RlbE5hbWVWYWx1ZVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAtIFBhcmFtcy4gKi9cbiAgcGFyYW1zKCkgeyByZXR1cm4gdGhpcy5wYXJhbXNWYWx1ZSB8fCBzdXBlci5wYXJhbXMoKSB8fCB7fSB9XG5cbiAgLyoqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLk5vcm1hbGl6ZWRGcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uIHwgaW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Gcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9ufSAtIFJlc291cmNlIGNvbmZpZyAobm9ybWFsaXplZCBhdCBydW50aW1lOyByYXcgZHVyaW5nIGVhcmx5IGJvb3RzdHJhcCkuICovXG4gIHJlc291cmNlQ29uZmlndXJhdGlvbigpIHtcbiAgICBpZiAoIXRoaXMucmVzb3VyY2VDb25maWd1cmF0aW9uVmFsdWUpIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IHJlcXVpcmVzIGEgcmVzb3VyY2UgY29uZmlndXJhdGlvbi5gKVxuXG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2VDb25maWd1cmF0aW9uVmFsdWVcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgUmFpbHMtc3Ryb25nLXBhcmFtcyAvIGFwaV9tYWtlci1zdHlsZSBwZXJtaXQgc3BlYyBkZWNsYXJpbmdcbiAgICogd2hpY2ggYXR0cmlidXRlcyBhbmQgbmVzdGVkIGF0dHJpYnV0ZXMgYXJlIHdyaXRhYmxlIGZvciB0aGUgY3VycmVudFxuICAgKiByZXF1ZXN0LiBTdWJtaXR0aW5nIGFuIGF0dHJpYnV0ZSBvciBuZXN0ZWQtcmVsYXRpb25zaGlwIGtleSB0aGF0IGlzXG4gICAqIG5vdCBwZXJtaXR0ZWQgcmFpc2VzIGFuIGVycm9yIGFuZCBmYWlscyB0aGUgd3JpdGUuXG4gICAqXG4gICAqIFRoZSByZXR1cm5lZCB2YWx1ZSBpcyBhIGZsYXQgYXJyYXkgdGhhdCBtaXhlczpcbiAgICogICAtIGBcImF0dHJpYnV0ZU5hbWVcImAgc3RyaW5ncyBmb3IgcGxhaW4gYXR0cmlidXRlIHdyaXRlc1xuICAgKiAgIC0gYHs8cmVsYXRpb25zaGlwTmFtZT5BdHRyaWJ1dGVzOiBbLi4uXX1gIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlXG4gICAqICAgICBpcyBpdHNlbGYgYSBwZXJtaXQgc3BlYyBmb3IgdGhlIG5lc3RlZCByZWxhdGlvbnNoaXBcbiAgICpcbiAgICogVGhpcyBtYXRjaGVzIFJhaWxzIHN0cm9uZ19wYXJhbXMgKGBwZXJtaXQoOmZpcnN0X25hbWUsIDpsYXN0X25hbWUsXG4gICAqIGNvbnRhY3RfYXR0cmlidXRlczogWzplbWFpbCwgZGV0YWlsc19hdHRyaWJ1dGVzOiBbOmRldGFpbF1dKWApIGFuZFxuICAgKiB0aGUgYXBpX21ha2VyIHNpc3RlciBwcm9qZWN0LiBJbmNsdWRlIGBcIl9kZXN0cm95XCJgIGluc2lkZSBhIG5lc3RlZFxuICAgKiBwZXJtaXQgdG8gYWxsb3cgYF9kZXN0cm95OiB0cnVlYCBlbnRyaWVzIGZvciB0aGF0IHJlbGF0aW9uc2hpcCDigJRcbiAgICogdGhlIG1vZGVsIG11c3QgYWxzbyBkZWNsYXJlIGBhY2NlcHRzTmVzdGVkQXR0cmlidXRlc0ZvcihuYW1lLFxuICAgKiB7YWxsb3dEZXN0cm95OiB0cnVlfSlgIGZvciB0aGUgZGVzdHJveSB0byBiZSBhcHBsaWVkLlxuICAgKlxuICAgKiBFeGFtcGxlOlxuICAgKlxuICAgKiAgIGNsYXNzIFByb2plY3RSZXNvdXJjZSBleHRlbmRzIEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2Uge1xuICAgKiAgICAgcGVybWl0dGVkUGFyYW1zKGFyZykge1xuICAgKiAgICAgICByZXR1cm4gW1xuICAgKiAgICAgICAgIFwibmFtZVwiLFxuICAgKiAgICAgICAgIFwiZGVzY3JpcHRpb25cIixcbiAgICogICAgICAgICB7dGFza3NBdHRyaWJ1dGVzOiBbXCJpZFwiLCBcIl9kZXN0cm95XCIsIFwibmFtZVwiLFxuICAgKiAgICAgICAgICAge3N1YnRhc2tzQXR0cmlidXRlczogW1wiaWRcIiwgXCJfZGVzdHJveVwiLCBcIm5hbWVcIl19XG4gICAqICAgICAgICAgXX1cbiAgICogICAgICAgXVxuICAgKiAgICAgfVxuICAgKiAgIH1cbiAgICpcbiAgICogRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIGBbXWAg4oCUIG5vdGhpbmcgcGVybWl0dGVkLiBTdWJjbGFzc2VzXG4gICAqIG11c3Qgb3ZlcnJpZGUgdG8gZW5hYmxlIHdyaXRlcy4gQSByZXNvdXJjZSB0aGF0IGRvZXMgbm90IGRlY2xhcmVcbiAgICogYHBlcm1pdHRlZFBhcmFtc2AgY2Fubm90IGFjY2VwdCBhbnkgd3JpdGUuXG4gICAqIEBwYXJhbSB7e2FjdGlvbj86IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiLCBwYXJhbXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBhYmlsaXR5PzogaW1wb3J0KFwiLi4vYXV0aG9yaXphdGlvbi9hYmlsaXR5LmpzXCIpLmRlZmF1bHQsIGxvY2Fscz86IFJlY29yZDxzdHJpbmcsIGFueT59fSBbYXJnXSAtIFJlcXVlc3QgY29udGV4dC5cbiAgICogQHJldHVybnMge0FycmF5PHN0cmluZyB8IFJlY29yZDxzdHJpbmcsIGFueT4+fSAtIFBlcm1pdCBzcGVjLlxuICAgKi9cbiAgcGVybWl0dGVkUGFyYW1zKGFyZykge1xuICAgIHZvaWQgYXJnXG5cbiAgICByZXR1cm4gW11cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7c3RyaW5nfSAtIFByaW1hcnkga2V5LiAqL1xuICBwcmltYXJ5S2V5KCkgeyByZXR1cm4gdGhpcy5tb2RlbENsYXNzKCkucHJpbWFyeUtleSgpIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtcImluZGV4XCIgfCBcImZpbmRcIiB8IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCIgfCBcImF0dGFjaFwiIHwgXCJkb3dubG9hZFwiIHwgXCJ1cmxcIn0gYWN0aW9uIC0gQWJpbGl0eSBhY3Rpb24uXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0PGFueT59IC0gQXV0aG9yaXplZCBxdWVyeS5cbiAgICovXG4gIGF1dGhvcml6ZWRRdWVyeShhY3Rpb24pIHtcbiAgICByZXR1cm4gdGhpcy50eXBlZENvbnRyb2xsZXJJbnN0YW5jZSgpLmZyb250ZW5kTW9kZWxBdXRob3JpemVkUXVlcnkoYWN0aW9uKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7XCJpbmRleFwiIHwgXCJmaW5kXCIgfCBcImNyZWF0ZVwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwiIHwgXCJhdHRhY2hcIiB8IFwiZG93bmxvYWRcIiB8IFwidXJsXCJ9IGFjdGlvbiAtIEFjdGlvbi5cbiAgICogQHJldHVybnMge2Jvb2xlYW4gfCBQcm9taXNlPGJvb2xlYW4+fSAtIFdoZXRoZXIgcGx1Y2sgaXMgc3VwcG9ydGVkLlxuICAgKi9cbiAgc3VwcG9ydHNQbHVjayhhY3Rpb24pIHtcbiAgICB2b2lkIGFjdGlvblxuXG4gICAgcmV0dXJuIE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKS5yZWNvcmRzID09PSBGcm9udGVuZE1vZGVsQmFzZVJlc291cmNlLnByb3RvdHlwZS5yZWNvcmRzXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtcImluZGV4XCIgfCBcImZpbmRcIiB8IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCIgfCBcImF0dGFjaFwiIHwgXCJkb3dubG9hZFwiIHwgXCJ1cmxcIn0gYWN0aW9uIC0gQWN0aW9uLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbiB8IFByb21pc2U8Ym9vbGVhbj59IC0gV2hldGhlciBjb3VudCBpcyBzdXBwb3J0ZWQuXG4gICAqL1xuICBzdXBwb3J0c0NvdW50KGFjdGlvbikge1xuICAgIHZvaWQgYWN0aW9uXG5cbiAgICByZXR1cm4gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpLnJlY29yZHMgPT09IEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2UucHJvdG90eXBlLnJlY29yZHMgfHxcbiAgICAgIE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKS5jb3VudCAhPT0gRnJvbnRlbmRNb2RlbEJhc2VSZXNvdXJjZS5wcm90b3R5cGUuY291bnRcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1wiaW5kZXhcIiB8IFwiZmluZFwiIHwgXCJjcmVhdGVcIiB8IFwidXBkYXRlXCIgfCBcImRlc3Ryb3lcIiB8IFwiYXR0YWNoXCIgfCBcImRvd25sb2FkXCIgfCBcInVybFwifSBhY3Rpb24gLSBBY3Rpb24uXG4gICAqIEByZXR1cm5zIHtib29sZWFuIHwgdm9pZCB8IFByb21pc2U8Ym9vbGVhbiB8IHZvaWQ+fSAtIENvbnRpbnVlIHByb2Nlc3NpbmcgdW5sZXNzIGZhbHNlLlxuICAgKi9cbiAgYmVmb3JlQWN0aW9uKGFjdGlvbikge1xuICAgIHZvaWQgYWN0aW9uXG5cbiAgICAvLyBOby1vcCBieSBkZWZhdWx0LlxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0W10+fSAtIFJlY29yZHMgZm9yIGluZGV4IGFjdGlvbi5cbiAgICovXG4gIGFzeW5jIHJlY29yZHMoKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMudHlwZWRDb250cm9sbGVySW5zdGFuY2UoKS5mcm9udGVuZE1vZGVsSW5kZXhRdWVyeSgpLnRvQXJyYXkoKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPG51bWJlcj59IC0gUmVjb3JkcyBjb3VudCBmb3IgaW5kZXggYWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgY291bnQoKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMudHlwZWRDb250cm9sbGVySW5zdGFuY2UoKS5mcm9udGVuZE1vZGVsSW5kZXhRdWVyeSgpLmNvdW50KClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1wiZmluZFwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwiIHwgXCJhdHRhY2hcIiB8IFwiZG93bmxvYWRcIiB8IFwidXJsXCJ9IGFjdGlvbiAtIEFjdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBudW1iZXJ9IGlkIC0gUmVjb3JkIGlkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCB8IG51bGw+fSAtIExvY2F0ZWQgbW9kZWwuXG4gICAqL1xuICBhc3luYyBmaW5kKGFjdGlvbiwgaWQpIHtcbiAgICBsZXQgcXVlcnkgPSB0aGlzLmF1dGhvcml6ZWRRdWVyeShhY3Rpb24pXG4gICAgY29uc3QgcHJlbG9hZCA9IGFjdGlvbiA9PT0gXCJmaW5kXCIgPyB0aGlzLnR5cGVkQ29udHJvbGxlckluc3RhbmNlKCkuZnJvbnRlbmRNb2RlbFByZWxvYWQoKSA6IG51bGxcblxuICAgIGlmIChwcmVsb2FkKSB7XG4gICAgICBxdWVyeSA9IHF1ZXJ5LnByZWxvYWQocHJlbG9hZClcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgcXVlcnkuZmluZEJ5KHtbdGhpcy5wcmltYXJ5S2V5KCldOiBpZH0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBhdHRyaWJ1dGVzIC0gQ3JlYXRlIGF0dHJpYnV0ZXMuXG4gICAqIEBwYXJhbSB7e2NvbnRyb2xsZXI/OiBhbnksIG5lc3RlZEF0dHJpYnV0ZXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHwgbnVsbH19IFtvcHRpb25zXSAtIFNhdmUgb3B0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQ+fSAtIENyZWF0ZWQgbW9kZWwuXG4gICAqL1xuICBhc3luYyBjcmVhdGUoYXR0cmlidXRlcywgb3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgcGVybWl0ID0gcGFyc2VQZXJtaXR0ZWRQYXJhbXModGhpcy5wZXJtaXR0ZWRQYXJhbXMoe2FjdGlvbjogXCJjcmVhdGVcIiwgYWJpbGl0eTogdGhpcy5hYmlsaXR5LCBsb2NhbHM6IHRoaXMubG9jYWxzLCBwYXJhbXM6IGF0dHJpYnV0ZXN9KSlcbiAgICBjb25zdCBmaWx0ZXJlZCA9IGZpbHRlcldyaXRhYmxlRnJvbnRlbmRNb2RlbEF0dHJpYnV0ZXModGhpcy5tb2RlbENsYXNzKCkucHJvdG90eXBlLCBhdHRyaWJ1dGVzLCB0aGlzLCBwZXJtaXQuYXR0cmlidXRlcylcbiAgICBjb25zdCBNb2RlbENsYXNzID0gdGhpcy5tb2RlbENsYXNzKClcbiAgICBjb25zdCBtb2RlbCA9IG5ldyBNb2RlbENsYXNzKClcblxuICAgIGF3YWl0IE1vZGVsQ2xhc3MudHJhbnNhY3Rpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgdGhpcy5fYXNzaWduV2l0aFZpcnR1YWxTZXR0ZXJzKG1vZGVsLCBmaWx0ZXJlZClcbiAgICAgIGF3YWl0IG1vZGVsLnNhdmUoKVxuXG4gICAgICBpZiAob3B0aW9ucy5uZXN0ZWRBdHRyaWJ1dGVzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuX2FwcGx5TmVzdGVkQXR0cmlidXRlcyhtb2RlbCwgb3B0aW9ucy5uZXN0ZWRBdHRyaWJ1dGVzLCBvcHRpb25zLmNvbnRyb2xsZXIgfHwgbnVsbCwgcGVybWl0KVxuICAgICAgfVxuICAgIH0pXG5cbiAgICBhd2FpdCB0aGlzLl9wcmVsb2FkTmVzdGVkV3JpdGFibGVSZWxhdGlvbnNoaXBzKG1vZGVsLCBwZXJtaXQpXG5cbiAgICByZXR1cm4gbW9kZWxcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbCAtIENyZWF0ZWQgbW9kZWwuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIENsZWFudXAgYWZ0ZXIgZmFpbGVkIGF1dGhvcml6YXRpb24uXG4gICAqL1xuICBhc3luYyBoYW5kbGVVbmF1dGhvcml6ZWRDcmVhdGVkTW9kZWwobW9kZWwpIHtcbiAgICBhd2FpdCBtb2RlbC5kZXN0cm95KClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbCAtIEV4aXN0aW5nIG1vZGVsLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IGF0dHJpYnV0ZXMgLSBVcGRhdGUgYXR0cmlidXRlcy5cbiAgICogQHBhcmFtIHt7Y29udHJvbGxlcj86IGFueSwgbmVzdGVkQXR0cmlidXRlcz86IFJlY29yZDxzdHJpbmcsIGFueT4gfCBudWxsfX0gW29wdGlvbnNdIC0gU2F2ZSBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdD59IC0gVXBkYXRlZCBtb2RlbC5cbiAgICovXG4gIGFzeW5jIHVwZGF0ZShtb2RlbCwgYXR0cmlidXRlcywgb3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgcGVybWl0ID0gcGFyc2VQZXJtaXR0ZWRQYXJhbXModGhpcy5wZXJtaXR0ZWRQYXJhbXMoe2FjdGlvbjogXCJ1cGRhdGVcIiwgYWJpbGl0eTogdGhpcy5hYmlsaXR5LCBsb2NhbHM6IHRoaXMubG9jYWxzLCBwYXJhbXM6IGF0dHJpYnV0ZXN9KSlcbiAgICBjb25zdCBmaWx0ZXJlZCA9IGZpbHRlcldyaXRhYmxlRnJvbnRlbmRNb2RlbEF0dHJpYnV0ZXMobW9kZWwsIGF0dHJpYnV0ZXMsIHRoaXMsIHBlcm1pdC5hdHRyaWJ1dGVzKVxuICAgIGNvbnN0IE1vZGVsQ2xhc3MgPSB0aGlzLm1vZGVsQ2xhc3MoKVxuXG4gICAgYXdhaXQgTW9kZWxDbGFzcy50cmFuc2FjdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0aGlzLl9hc3NpZ25XaXRoVmlydHVhbFNldHRlcnMobW9kZWwsIGZpbHRlcmVkKVxuICAgICAgYXdhaXQgbW9kZWwuc2F2ZSgpXG5cbiAgICAgIGlmIChvcHRpb25zLm5lc3RlZEF0dHJpYnV0ZXMpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5fYXBwbHlOZXN0ZWRBdHRyaWJ1dGVzKG1vZGVsLCBvcHRpb25zLm5lc3RlZEF0dHJpYnV0ZXMsIG9wdGlvbnMuY29udHJvbGxlciB8fCBudWxsLCBwZXJtaXQpXG4gICAgICB9XG4gICAgfSlcblxuICAgIGF3YWl0IHRoaXMuX3ByZWxvYWROZXN0ZWRXcml0YWJsZVJlbGF0aW9uc2hpcHMobW9kZWwsIHBlcm1pdClcblxuICAgIHJldHVybiBtb2RlbFxuICB9XG5cbiAgLyoqXG4gICAqIEFzc2lnbnMgYXR0cmlidXRlcyB0byBhIG1vZGVsLCB1c2luZyB2aXJ0dWFsIHNldHRlcnMgb24gdGhlIHJlc291cmNlIHdoZW4gYXZhaWxhYmxlLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbCAtIE1vZGVsIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IGF0dHJpYnV0ZXMgLSBBdHRyaWJ1dGVzIHRvIGFzc2lnbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBfYXNzaWduV2l0aFZpcnR1YWxTZXR0ZXJzKG1vZGVsLCBhdHRyaWJ1dGVzKSB7XG4gICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqL1xuICAgIGNvbnN0IGRpcmVjdEF0dHJpYnV0ZXMgPSB7fVxuICAgIGNvbnN0IHRyYW5zbGF0ZWRTZXQgPSBuZXcgU2V0KC8qKiBAdHlwZSB7dHlwZW9mIEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2V9ICovICh0aGlzLmNvbnN0cnVjdG9yKS50cmFuc2xhdGVkQXR0cmlidXRlcyB8fCBbXSlcblxuICAgIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhhdHRyaWJ1dGVzKSkge1xuICAgICAgY29uc3QgcmVzb3VyY2VTZXR0ZXJOYW1lID0gYHNldCR7aW5mbGVjdGlvbi5jYW1lbGl6ZShuYW1lKX1BdHRyaWJ1dGVgXG5cbiAgICAgIGlmICh0eXBlb2YgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAodGhpcykpW3Jlc291cmNlU2V0dGVyTmFtZV0gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBhd2FpdCAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovICgvKiogQHR5cGUge3Vua25vd259ICovICh0aGlzKSlbcmVzb3VyY2VTZXR0ZXJOYW1lXShtb2RlbCwgdmFsdWUpXG4gICAgICB9IGVsc2UgaWYgKHRyYW5zbGF0ZWRTZXQuaGFzKG5hbWUpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuX3NldFRyYW5zbGF0ZWRBdHRyaWJ1dGVPbk1vZGVsKG1vZGVsLCBuYW1lLCB2YWx1ZSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRpcmVjdEF0dHJpYnV0ZXNbbmFtZV0gPSB2YWx1ZVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChPYmplY3Qua2V5cyhkaXJlY3RBdHRyaWJ1dGVzKS5sZW5ndGggPiAwKSB7XG4gICAgICBtb2RlbC5hc3NpZ24oZGlyZWN0QXR0cmlidXRlcylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhIHRyYW5zbGF0ZWQgYXR0cmlidXRlIG9uIGEgbW9kZWwgdmlhIHRoZSB0cmFuc2xhdGlvbnMgcmVsYXRpb25zaGlwLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbCAtIE1vZGVsIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIEF0dHJpYnV0ZSBuYW1lLlxuICAgKiBAcGFyYW0ge2FueX0gdmFsdWUgLSBBdHRyaWJ1dGUgdmFsdWUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgX3NldFRyYW5zbGF0ZWRBdHRyaWJ1dGVPbk1vZGVsKG1vZGVsLCBuYW1lLCB2YWx1ZSkge1xuICAgIGNvbnN0IGxvY2FsZSA9IHRoaXMuY29udGV4dD8uY29uZmlndXJhdGlvbj8uZ2V0TG9jYWxlPy4oKSB8fCBcImVuXCJcbiAgICBjb25zdCBpbnN0YW5jZVJlbGF0aW9uc2hpcCA9IG1vZGVsLmdldFJlbGF0aW9uc2hpcEJ5TmFtZShcInRyYW5zbGF0aW9uc1wiKVxuXG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gKi9cbiAgICBsZXQgdHJhbnNsYXRpb25cblxuICAgIGlmIChtb2RlbC5pc05ld1JlY29yZCgpKSB7XG4gICAgICBjb25zdCBsb2FkZWQgPSBpbnN0YW5jZVJlbGF0aW9uc2hpcC5sb2FkZWQoKVxuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShsb2FkZWQpKSB7XG4gICAgICAgIHRyYW5zbGF0aW9uID0gbG9hZGVkLmZpbmQoKC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi8gdCkgPT4gdC5sb2NhbGUoKSA9PT0gbG9jYWxlKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoIWluc3RhbmNlUmVsYXRpb25zaGlwLmdldFByZWxvYWRlZCgpKSB7XG4gICAgICAgIGF3YWl0IG1vZGVsLmxvYWRSZWxhdGlvbnNoaXAoXCJ0cmFuc2xhdGlvbnNcIilcbiAgICAgIH1cblxuICAgICAgY29uc3QgbG9hZGVkID0gaW5zdGFuY2VSZWxhdGlvbnNoaXAubG9hZGVkKClcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkobG9hZGVkKSkge1xuICAgICAgICB0cmFuc2xhdGlvbiA9IGxvYWRlZC5maW5kKCgvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGFueT59ICovIHQpID0+IHQubG9jYWxlKCkgPT09IGxvY2FsZSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXRyYW5zbGF0aW9uKSB7XG4gICAgICB0cmFuc2xhdGlvbiA9IGluc3RhbmNlUmVsYXRpb25zaGlwLmJ1aWxkKHtsb2NhbGV9KVxuICAgIH1cblxuICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgYW55Pn0gKi9cbiAgICBjb25zdCBhc3NpZ25tZW50cyA9IHt9XG5cbiAgICBhc3NpZ25tZW50c1tuYW1lXSA9IHZhbHVlXG4gICAgdHJhbnNsYXRpb24uYXNzaWduKGFzc2lnbm1lbnRzKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IG1vZGVsIC0gRXhpc3RpbmcgbW9kZWwuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIGFzeW5jIGRlc3Ryb3kobW9kZWwpIHtcbiAgICBhd2FpdCBtb2RlbC5kZXN0cm95KClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbCAtIE1vZGVsIHRvIHNlcmlhbGl6ZS5cbiAgICogQHBhcmFtIHtcImluZGV4XCIgfCBcImZpbmRcIiB8IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwifSBbYWN0aW9uXSAtIEFjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgYW55Pj59IC0gU2VyaWFsaXplZCBtb2RlbCBwYXlsb2FkLlxuICAgKi9cbiAgYXN5bmMgc2VyaWFsaXplKG1vZGVsLCBhY3Rpb24pIHtcbiAgICB2b2lkIGFjdGlvblxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMudHlwZWRDb250cm9sbGVySW5zdGFuY2UoKS5zZXJpYWxpemVGcm9udGVuZE1vZGVsKG1vZGVsKVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgYSBgbmVzdGVkQXR0cmlidXRlc2AgcGF5bG9hZCB0byBhIGZyZXNobHktc2F2ZWQgcGFyZW50IG1vZGVsLFxuICAgKiBjYXNjYWRpbmcgY3JlYXRlL3VwZGF0ZS9kZXN0cm95IHdyaXRlcyBhY3Jvc3MgdGhlIGRlY2xhcmVkIHJlbGF0aW9uc2hpcHMuXG4gICAqXG4gICAqIEVhY2ggY2hpbGQgaXMgYXV0aG9yaXplZCBhZ2FpbnN0IGl0cyBvd24gcmVzb3VyY2UncyBhYmlsaXRpZXMgKG5ldmVyIHRoZVxuICAgKiBwYXJlbnQncykuIERlc3Ryb3lzIHJ1biBiZWZvcmUgdXBkYXRlcywgdXBkYXRlcyBiZWZvcmUgY3JlYXRlcywgdG8gYXZvaWRcbiAgICogdW5pcXVlLWNvbnN0cmFpbnQgY29uZmxpY3RzIHdoZW4gcmVwbGFjaW5nIGEgY2hpbGQgYXQgdGhlIHNhbWUgbmF0dXJhbCBrZXkuXG4gICAqXG4gICAqIEF0dHJpYnV0ZSBmaWx0ZXJpbmcgZm9yIG5lc3RlZCBjaGlsZHJlbiB1c2VzIHRoZSBwYXJlbnQgcmVzb3VyY2Unc1xuICAgKiBwZXJtaXQgc3BlYyBmb3IgdGhhdCByZWxhdGlvbnNoaXAg4oCUIGFwaV9tYWtlci1zdHlsZS4gUG9saWN5IG9wdGlvbnNcbiAgICogKGFsbG93RGVzdHJveSwgbGltaXQsIHJlamVjdElmKSBjb21lIGZyb20gdGhlIE1PREVMJ3NcbiAgICogYGFjY2VwdGVkTmVzdGVkQXR0cmlidXRlc0ZvcihuYW1lKWAgZGVjbGFyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IHBhcmVudCAtIFBhcmVudCBtb2RlbCBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSBuZXN0ZWRBdHRyaWJ1dGVzIC0gTmVzdGVkLWF0dHJpYnV0ZSBwYXlsb2FkIGtleWVkIGJ5IHJlbGF0aW9uc2hpcCBuYW1lLlxuICAgKiBAcGFyYW0ge2FueX0gY29udHJvbGxlciAtIENvbnRyb2xsZXIgaW5zdGFuY2UgZm9yIHJlc291cmNlIHJlc29sdXRpb24gYW5kIGF1dGhvcml6YXRpb24uXG4gICAqIEBwYXJhbSB7e2F0dHJpYnV0ZXM6IHN0cmluZ1tdLCBuZXN0ZWQ6IFJlY29yZDxzdHJpbmcsIGFueT59IHwgbnVsbH0gW3BhcmVudFBlcm1pdF0gLSBQYXJzZWQgcGFyZW50IHBlcm1pdCBzcGVjLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIF9hcHBseU5lc3RlZEF0dHJpYnV0ZXMocGFyZW50LCBuZXN0ZWRBdHRyaWJ1dGVzLCBjb250cm9sbGVyLCBwYXJlbnRQZXJtaXQgPSBudWxsKSB7XG4gICAgY29uc3QgcmVzb2x2ZWRQYXJlbnQgPSBwYXJlbnRQZXJtaXRcbiAgICAgIHx8IHBhcnNlUGVybWl0dGVkUGFyYW1zKHRoaXMucGVybWl0dGVkUGFyYW1zKHthY3Rpb246IFwidXBkYXRlXCIsIGFiaWxpdHk6IHRoaXMuYWJpbGl0eSwgbG9jYWxzOiB0aGlzLmxvY2FscywgcGFyYW1zOiB7fX0pKVxuXG4gICAgZm9yIChjb25zdCByZWxhdGlvbnNoaXBOYW1lIG9mIE9iamVjdC5rZXlzKG5lc3RlZEF0dHJpYnV0ZXMpKSB7XG4gICAgICBjb25zdCBjaGlsZFBlcm1pdCA9IHJlc29sdmVkUGFyZW50Lm5lc3RlZFtyZWxhdGlvbnNoaXBOYW1lXVxuXG4gICAgICBpZiAoIWNoaWxkUGVybWl0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTmVzdGVkIGF0dHJpYnV0ZXMgZm9yICcke3JlbGF0aW9uc2hpcE5hbWV9JyBhcmUgbm90IHBlcm1pdHRlZCBieSAke3RoaXMuY29uc3RydWN0b3IubmFtZX0ucGVybWl0dGVkUGFyYW1zKCkuIEluY2x1ZGUgeyR7cmVsYXRpb25zaGlwTmFtZX1BdHRyaWJ1dGVzOiBbLi4uXX0gaW4gdGhlIHJldHVybmVkIHBlcm1pdC5gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBlbnRyaWVzID0gbmVzdGVkQXR0cmlidXRlc1tyZWxhdGlvbnNoaXBOYW1lXVxuXG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkoZW50cmllcykpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBhcnJheSBmb3IgbmVzdGVkQXR0cmlidXRlc1snJHtyZWxhdGlvbnNoaXBOYW1lfSddIGJ1dCBnb3Q6ICR7dHlwZW9mIGVudHJpZXN9YClcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFyZW50TW9kZWxDbGFzcyA9IC8qKiBAdHlwZSB7YW55fSAqLyAocGFyZW50LmdldE1vZGVsQ2xhc3MoKSlcbiAgICAgIGNvbnN0IG1vZGVsQWNjZXB0YW5jZSA9IHBhcmVudE1vZGVsQ2xhc3MuYWNjZXB0ZWROZXN0ZWRBdHRyaWJ1dGVzRm9yPy4ocmVsYXRpb25zaGlwTmFtZSlcblxuICAgICAgaWYgKCFtb2RlbEFjY2VwdGFuY2UpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNb2RlbCAke3BhcmVudE1vZGVsQ2xhc3MubmFtZX0gZG9lcyBub3QgYWNjZXB0IG5lc3RlZCBhdHRyaWJ1dGVzIGZvciAnJHtyZWxhdGlvbnNoaXBOYW1lfScuIERlY2xhcmUgaXQgdmlhICR7cGFyZW50TW9kZWxDbGFzcy5uYW1lfS5hY2NlcHRzTmVzdGVkQXR0cmlidXRlc0ZvcignJHtyZWxhdGlvbnNoaXBOYW1lfScpLmApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRlc3Ryb3lQZXJtaXR0ZWQgPSBjaGlsZFBlcm1pdC5hdHRyaWJ1dGVzLmluY2x1ZGVzKFwiX2Rlc3Ryb3lcIilcblxuICAgICAgaWYgKGRlc3Ryb3lQZXJtaXR0ZWQgJiYgIW1vZGVsQWNjZXB0YW5jZS5hbGxvd0Rlc3Ryb3kpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBSZXNvdXJjZSBwZXJtaXRzIF9kZXN0cm95IG9uIG5lc3RlZEF0dHJpYnV0ZXNbJyR7cmVsYXRpb25zaGlwTmFtZX0nXSBidXQgdGhlIG1vZGVsICR7cGFyZW50TW9kZWxDbGFzcy5uYW1lfSBkb2VzIG5vdCBhbGxvdyBkZXN0cm95IGZvciB0aGF0IHJlbGF0aW9uc2hpcC4gU2V0IHthbGxvd0Rlc3Ryb3k6IHRydWV9IG9uICR7cGFyZW50TW9kZWxDbGFzcy5uYW1lfS5hY2NlcHRzTmVzdGVkQXR0cmlidXRlc0ZvcignJHtyZWxhdGlvbnNoaXBOYW1lfScsIC4uLikuYClcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBtb2RlbEFjY2VwdGFuY2UubGltaXQgPT09IFwibnVtYmVyXCIgJiYgZW50cmllcy5sZW5ndGggPiBtb2RlbEFjY2VwdGFuY2UubGltaXQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBuZXN0ZWRBdHRyaWJ1dGVzWycke3JlbGF0aW9uc2hpcE5hbWV9J10gZXhjZWVkcyBtb2RlbC1kZWNsYXJlZCBsaW1pdCBvZiAke21vZGVsQWNjZXB0YW5jZS5saW1pdH0uYClcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFyZW50UmVsYXRpb25zaGlwID0gcGFyZW50LmdldFJlbGF0aW9uc2hpcEJ5TmFtZShyZWxhdGlvbnNoaXBOYW1lKVxuICAgICAgY29uc3QgcmVsYXRpb25zaGlwRGVmaW5pdGlvbnMgPSBwYXJlbnRNb2RlbENsYXNzLnJlbGF0aW9uc2hpcHM/LigpIHx8IHt9XG4gICAgICBjb25zdCBkZWZpbml0aW9uID0gcmVsYXRpb25zaGlwRGVmaW5pdGlvbnNbcmVsYXRpb25zaGlwTmFtZV1cblxuICAgICAgaWYgKCFkZWZpbml0aW9uIHx8IGRlZmluaXRpb24udHlwZSAhPT0gXCJoYXNNYW55XCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBOZXN0ZWQgYXR0cmlidXRlcyBmb3IgJyR7cmVsYXRpb25zaGlwTmFtZX0nIHJlcXVpcmUgYSBoYXNNYW55IHJlbGF0aW9uc2hpcC4gdjEgZG9lcyBub3Qgc3VwcG9ydCAnJHtkZWZpbml0aW9uPy50eXBlfScuYClcbiAgICAgIH1cblxuICAgICAgY29uc3QgdGFyZ2V0TW9kZWxDbGFzcyA9IC8qKiBAdHlwZSB7YW55fSAqLyAocGFyZW50LmdldE1vZGVsQ2xhc3MoKSkucmVsYXRpb25zaGlwTW9kZWxDbGFzcz8uKHJlbGF0aW9uc2hpcE5hbWUpXG5cbiAgICAgIGlmICghdGFyZ2V0TW9kZWxDbGFzcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHRhcmdldCBtb2RlbCBjbGFzcyByZXNvbHZlZCBmb3IgcmVsYXRpb25zaGlwICcke3JlbGF0aW9uc2hpcE5hbWV9JyBvbiAke3BhcmVudC5nZXRNb2RlbENsYXNzKCkubmFtZX0uYClcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hpbGRSZXNvdXJjZUNvbmZpZyA9IGNvbnRyb2xsZXI/LmZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb25Gb3JNb2RlbENsYXNzPy4odGFyZ2V0TW9kZWxDbGFzcylcblxuICAgICAgaWYgKCFjaGlsZFJlc291cmNlQ29uZmlnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gZnJvbnRlbmQtbW9kZWwgcmVzb3VyY2UgcmVnaXN0ZXJlZCBmb3IgY2hpbGQgbW9kZWwgJyR7dGFyZ2V0TW9kZWxDbGFzcy5nZXRNb2RlbE5hbWU/LigpIHx8IHRhcmdldE1vZGVsQ2xhc3MubmFtZX0nIHVuZGVyIHJlbGF0aW9uc2hpcCAnJHtyZWxhdGlvbnNoaXBOYW1lfScuYClcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hpbGRSZXNvdXJjZSA9IG5ldyBjaGlsZFJlc291cmNlQ29uZmlnLnJlc291cmNlQ2xhc3Moe1xuICAgICAgICBhYmlsaXR5OiB0aGlzLmFiaWxpdHksXG4gICAgICAgIGNvbnRyb2xsZXIsXG4gICAgICAgIGNvbnRleHQ6IHRoaXMuY29udGV4dCB8fCB7fSxcbiAgICAgICAgbG9jYWxzOiB0aGlzLmxvY2FscyB8fCB7fSxcbiAgICAgICAgbW9kZWxDbGFzczogdGFyZ2V0TW9kZWxDbGFzcyxcbiAgICAgICAgbW9kZWxOYW1lOiBjaGlsZFJlc291cmNlQ29uZmlnLm1vZGVsTmFtZSxcbiAgICAgICAgcGFyYW1zOiBjb250cm9sbGVyPy5mcm9udGVuZE1vZGVsUGFyYW1zPy4oKSB8fCB7fSxcbiAgICAgICAgcmVzb3VyY2VDb25maWd1cmF0aW9uOiBjaGlsZFJlc291cmNlQ29uZmlnLnJlc291cmNlQ29uZmlndXJhdGlvblxuICAgICAgfSlcblxuICAgICAgY29uc3QgZm9yZWlnbktleSA9IGRlZmluaXRpb24uZm9yZWlnbktleSB8fCB0aGlzLl9pbmZlckZvcmVpZ25LZXkocGFyZW50LCBkZWZpbml0aW9uKVxuICAgICAgY29uc3QgYWJpbGl0eSA9IGNvbnRyb2xsZXI/LmN1cnJlbnRBYmlsaXR5Py4oKVxuXG4gICAgICBjb25zdCBkZXN0cm95RW50cmllcyA9IFtdXG4gICAgICBjb25zdCB1cGRhdGVFbnRyaWVzID0gW11cbiAgICAgIGNvbnN0IGNyZWF0ZUVudHJpZXMgPSBbXVxuXG4gICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBtb2RlbEFjY2VwdGFuY2UucmVqZWN0SWYgPT09IFwiZnVuY3Rpb25cIiAmJiBtb2RlbEFjY2VwdGFuY2UucmVqZWN0SWYoZW50cnk/LmF0dHJpYnV0ZXMgfHwge30pKSBjb250aW51ZVxuXG4gICAgICAgIGlmIChlbnRyeT8uX2Rlc3Ryb3kpIHtcbiAgICAgICAgICBpZiAoIWRlc3Ryb3lQZXJtaXR0ZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgbmVzdGVkQXR0cmlidXRlc1snJHtyZWxhdGlvbnNoaXBOYW1lfSddIGVudHJ5IHJlcXVlc3RlZCBfZGVzdHJveSBidXQgXCJfZGVzdHJveVwiIGlzIG5vdCBpbiB0aGUgcGVybWl0IGZvciB0aGlzIHJlbGF0aW9uc2hpcC5gKVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWVudHJ5LmlkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG5lc3RlZEF0dHJpYnV0ZXNbJyR7cmVsYXRpb25zaGlwTmFtZX0nXSBfZGVzdHJveSBlbnRyeSBpcyBtaXNzaW5nIGFuIGlkLmApXG4gICAgICAgICAgfVxuICAgICAgICAgIGRlc3Ryb3lFbnRyaWVzLnB1c2goZW50cnkpXG4gICAgICAgIH0gZWxzZSBpZiAoZW50cnk/LmlkKSB7XG4gICAgICAgICAgdXBkYXRlRW50cmllcy5wdXNoKGVudHJ5KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNyZWF0ZUVudHJpZXMucHVzaChlbnRyeSlcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBUaGUgcGVybWl0J3MgYXR0cmlidXRlIGxpc3QgZ292ZXJucyB3aGF0IGNoaWxkIGZpZWxkcyBjYW4gYmUgd3JpdHRlbi5cbiAgICAgIC8vIEV4Y2x1ZGUgYF9kZXN0cm95YCBmcm9tIHRoZSB3cml0YWJsZSBzZXQgc2luY2UgaXQncyBhIGNvbnRyb2wgZmxhZyxcbiAgICAgIC8vIG5vdCBhbiBhdHRyaWJ1dGUgb24gdGhlIHJlY29yZC5cbiAgICAgIGNvbnN0IGNoaWxkV3JpdGFibGVBdHRyaWJ1dGVzID0gLyoqIEB0eXBlIHtzdHJpbmdbXX0gKi8gKGNoaWxkUGVybWl0LmF0dHJpYnV0ZXMpLmZpbHRlcigobmFtZSkgPT4gbmFtZSAhPT0gXCJfZGVzdHJveVwiKVxuXG4gICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGRlc3Ryb3lFbnRyaWVzKSB7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgdGhpcy5fZmluZFNjb3BlZENoaWxkKHtcbiAgICAgICAgICBhYmlsaXR5LFxuICAgICAgICAgIGFjdGlvbjogXCJkZXN0cm95XCIsXG4gICAgICAgICAgY2hpbGRSZXNvdXJjZUNvbmZpZ3VyYXRpb246IGNoaWxkUmVzb3VyY2VDb25maWcucmVzb3VyY2VDb25maWd1cmF0aW9uLFxuICAgICAgICAgIGZvcmVpZ25LZXksXG4gICAgICAgICAgaWQ6IGVudHJ5LmlkLFxuICAgICAgICAgIHBhcmVudCxcbiAgICAgICAgICByZWxhdGlvbnNoaXBOYW1lLFxuICAgICAgICAgIHRhcmdldE1vZGVsQ2xhc3NcbiAgICAgICAgfSlcblxuICAgICAgICBhd2FpdCBjaGlsZFJlc291cmNlLmRlc3Ryb3koZXhpc3RpbmcpXG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgdXBkYXRlRW50cmllcykge1xuICAgICAgICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHRoaXMuX2ZpbmRTY29wZWRDaGlsZCh7XG4gICAgICAgICAgYWJpbGl0eSxcbiAgICAgICAgICBhY3Rpb246IFwidXBkYXRlXCIsXG4gICAgICAgICAgY2hpbGRSZXNvdXJjZUNvbmZpZ3VyYXRpb246IGNoaWxkUmVzb3VyY2VDb25maWcucmVzb3VyY2VDb25maWd1cmF0aW9uLFxuICAgICAgICAgIGZvcmVpZ25LZXksXG4gICAgICAgICAgaWQ6IGVudHJ5LmlkLFxuICAgICAgICAgIHBhcmVudCxcbiAgICAgICAgICByZWxhdGlvbnNoaXBOYW1lLFxuICAgICAgICAgIHRhcmdldE1vZGVsQ2xhc3NcbiAgICAgICAgfSlcblxuICAgICAgICBpZiAoZW50cnkuYXR0cmlidXRlcyAmJiB0eXBlb2YgZW50cnkuYXR0cmlidXRlcyA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgIGNvbnN0IGZpbHRlcmVkID0gZmlsdGVyV3JpdGFibGVGcm9udGVuZE1vZGVsQXR0cmlidXRlcyhleGlzdGluZywgZW50cnkuYXR0cmlidXRlcywgY2hpbGRSZXNvdXJjZSwgY2hpbGRXcml0YWJsZUF0dHJpYnV0ZXMpXG4gICAgICAgICAgYXdhaXQgLyoqIEB0eXBlIHthbnl9ICovIChjaGlsZFJlc291cmNlKS5fYXNzaWduV2l0aFZpcnR1YWxTZXR0ZXJzKGV4aXN0aW5nLCBmaWx0ZXJlZClcbiAgICAgICAgICBhd2FpdCBleGlzdGluZy5zYXZlKClcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbnRyeS5uZXN0ZWRBdHRyaWJ1dGVzKSB7XG4gICAgICAgICAgYXdhaXQgLyoqIEB0eXBlIHthbnl9ICovIChjaGlsZFJlc291cmNlKS5fYXBwbHlOZXN0ZWRBdHRyaWJ1dGVzKGV4aXN0aW5nLCBlbnRyeS5uZXN0ZWRBdHRyaWJ1dGVzLCBjb250cm9sbGVyLCBjaGlsZFBlcm1pdClcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGNyZWF0ZUVudHJpZXMpIHtcbiAgICAgICAgY29uc3QgY2hpbGRBdHRyaWJ1dGVzID0gZW50cnk/LmF0dHJpYnV0ZXMgJiYgdHlwZW9mIGVudHJ5LmF0dHJpYnV0ZXMgPT09IFwib2JqZWN0XCIgPyBlbnRyeS5hdHRyaWJ1dGVzIDoge31cblxuICAgICAgICBjb25zdCBjaGlsZCA9IHBhcmVudFJlbGF0aW9uc2hpcC5idWlsZCh7Li4uY2hpbGRBdHRyaWJ1dGVzLCBbZm9yZWlnbktleV06IHBhcmVudC5pZCgpfSlcblxuICAgICAgICBjb25zdCBmaWx0ZXJlZCA9IGZpbHRlcldyaXRhYmxlRnJvbnRlbmRNb2RlbEF0dHJpYnV0ZXMoY2hpbGQsIGNoaWxkQXR0cmlidXRlcywgY2hpbGRSZXNvdXJjZSwgY2hpbGRXcml0YWJsZUF0dHJpYnV0ZXMpXG5cbiAgICAgICAgYXdhaXQgLyoqIEB0eXBlIHthbnl9ICovIChjaGlsZFJlc291cmNlKS5fYXNzaWduV2l0aFZpcnR1YWxTZXR0ZXJzKGNoaWxkLCBmaWx0ZXJlZClcbiAgICAgICAgYXdhaXQgY2hpbGQuc2F2ZSgpXG5cbiAgICAgICAgYXdhaXQgdGhpcy5fYXV0aG9yaXplQ3JlYXRlZENoaWxkKHtcbiAgICAgICAgICBhYmlsaXR5LFxuICAgICAgICAgIGNoaWxkLFxuICAgICAgICAgIGNoaWxkUmVzb3VyY2VDb25maWd1cmF0aW9uOiBjaGlsZFJlc291cmNlQ29uZmlnLnJlc291cmNlQ29uZmlndXJhdGlvbixcbiAgICAgICAgICByZWxhdGlvbnNoaXBOYW1lLFxuICAgICAgICAgIHRhcmdldE1vZGVsQ2xhc3NcbiAgICAgICAgfSlcblxuICAgICAgICBpZiAoZW50cnkubmVzdGVkQXR0cmlidXRlcykge1xuICAgICAgICAgIGF3YWl0IC8qKiBAdHlwZSB7YW55fSAqLyAoY2hpbGRSZXNvdXJjZSkuX2FwcGx5TmVzdGVkQXR0cmlidXRlcyhjaGlsZCwgZW50cnkubmVzdGVkQXR0cmlidXRlcywgY29udHJvbGxlciwgY2hpbGRQZXJtaXQpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIGFiaWxpdHkgYWN0aW9uIGZvciBhIGNoaWxkIHJlc291cmNlIHVzaW5nIHRoZSBjaGlsZCdzIG93blxuICAgKiBgYWJpbGl0aWVzYCBtYXBwaW5nIOKAlCBuZXZlciB0aGUgcGFyZW50IGNvbnRyb2xsZXIncy4gVGhpcyBwcmVzZXJ2ZXNcbiAgICogY3VzdG9tIG1hcHBpbmdzIGxpa2UgYHt1cGRhdGU6IFwibWFuYWdlXCJ9YCBhbmQgY2F0Y2hlcyB1bm1hcHBlZCBhY3Rpb25zXG4gICAqIGluc3RlYWQgb2Ygc2lsZW50bHkgZGVmYXVsdGluZyB0byB0aGUgcmF3IGFjdGlvbiBuYW1lLlxuICAgKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbn0gY2hpbGRSZXNvdXJjZUNvbmZpZ3VyYXRpb24gLSBDaGlsZCByZXNvdXJjZSBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge1wiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCJ9IGFjdGlvbiAtIEZyb250ZW5kIGFjdGlvbi5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBBYmlsaXR5IGFjdGlvbiBmb3IgdGhlIGNoaWxkIHJlc291cmNlLlxuICAgKi9cbiAgX3Jlc29sdmVDaGlsZEFiaWxpdHlBY3Rpb24oY2hpbGRSZXNvdXJjZUNvbmZpZ3VyYXRpb24sIGFjdGlvbikge1xuICAgIGNvbnN0IGFiaWxpdGllcyA9IGNoaWxkUmVzb3VyY2VDb25maWd1cmF0aW9uPy5hYmlsaXRpZXNcblxuICAgIGlmICghYWJpbGl0aWVzIHx8IHR5cGVvZiBhYmlsaXRpZXMgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShhYmlsaXRpZXMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5lc3RlZCBjaGlsZCByZXNvdXJjZSBtdXN0IGRlZmluZSBhbiAnYWJpbGl0aWVzJyBvYmplY3QgdG8gYXV0aG9yaXplIG5lc3RlZCAke2FjdGlvbn0uYClcbiAgICB9XG5cbiAgICBjb25zdCBhYmlsaXR5QWN0aW9uID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+fSAqLyAoYWJpbGl0aWVzKVthY3Rpb25dXG5cbiAgICBpZiAodHlwZW9mIGFiaWxpdHlBY3Rpb24gIT09IFwic3RyaW5nXCIgfHwgYWJpbGl0eUFjdGlvbi5sZW5ndGggPCAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5lc3RlZCBjaGlsZCByZXNvdXJjZSBtdXN0IGRlZmluZSBhYmlsaXRpZXMuJHthY3Rpb259LmApXG4gICAgfVxuXG4gICAgcmV0dXJuIGFiaWxpdHlBY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kcyBhbiBleGlzdGluZyBjaGlsZCBmb3IgYSBuZXN0ZWQgdXBkYXRlL2Rlc3Ryb3ksIHNjb3BlZCB0byB0aGVcbiAgICogY2hpbGQncyBvd24gbW9kZWwgY2xhc3MsIHRoZSBwYXJlbnQncyBmb3JlaWduIGtleSwgQU5EIHRoZSBjaGlsZFxuICAgKiByZXNvdXJjZSdzIGFiaWxpdHkgbWFwcGluZyBmb3IgdGhlIHJlcXVlc3RlZCBhY3Rpb24uIFRocm93cyB3aGVuIHRoZVxuICAgKiBjaGlsZCBkb2VzIG5vdCBleGlzdCwgZG9lcyBub3QgYmVsb25nIHRvIHRoZSBjdXJyZW50IHBhcmVudCwgb3IgaXNcbiAgICogbm90IGF1dGhvcml6ZWQg4oCUIGFsbCBvZiB3aGljaCBtdXN0IHJvbGwgdGhlIHRyYW5zYWN0aW9uIGJhY2suXG4gICAqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gQXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2F1dGhvcml6YXRpb24vYWJpbGl0eS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfSBhcmdzLmFiaWxpdHkgLSBDdXJyZW50IGFiaWxpdHkuXG4gICAqIEBwYXJhbSB7XCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwifSBhcmdzLmFjdGlvbiAtIEZyb250ZW5kIGFjdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb259IGFyZ3MuY2hpbGRSZXNvdXJjZUNvbmZpZ3VyYXRpb24gLSBDaGlsZCByZXNvdXJjZSBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5mb3JlaWduS2V5IC0gRm9yZWlnbi1rZXkgYXR0cmlidXRlIG9uIHRoZSBjaGlsZCBwb2ludGluZyB0byB0aGUgcGFyZW50LlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlcn0gYXJncy5pZCAtIENoaWxkIGlkIGZyb20gdGhlIHBheWxvYWQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IGFyZ3MucGFyZW50IC0gUGFyZW50IG1vZGVsIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5yZWxhdGlvbnNoaXBOYW1lIC0gUGFyZW50J3MgcmVsYXRpb25zaGlwIG5hbWUgKGZvciBlcnJvciBtZXNzYWdlcykuXG4gICAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBhcmdzLnRhcmdldE1vZGVsQ2xhc3MgLSBDaGlsZCBtb2RlbCBjbGFzcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQ+fSAtIEF1dGhvcml6ZWQsIHBhcmVudC1saW5rZWQgY2hpbGQgbW9kZWwuXG4gICAqL1xuICBhc3luYyBfZmluZFNjb3BlZENoaWxkKHthYmlsaXR5LCBhY3Rpb24sIGNoaWxkUmVzb3VyY2VDb25maWd1cmF0aW9uLCBmb3JlaWduS2V5LCBpZCwgcGFyZW50LCByZWxhdGlvbnNoaXBOYW1lLCB0YXJnZXRNb2RlbENsYXNzfSkge1xuICAgIGNvbnN0IHByaW1hcnlLZXkgPSB0YXJnZXRNb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgIGNvbnN0IGxvb2t1cCA9IHtbcHJpbWFyeUtleV06IGlkLCBbZm9yZWlnbktleV06IHBhcmVudC5pZCgpfVxuICAgIGNvbnN0IHF1ZXJ5ID0gYWJpbGl0eVxuICAgICAgPyAvKiogQHR5cGUge2FueX0gKi8gKHRhcmdldE1vZGVsQ2xhc3MpLmFjY2Vzc2libGVGb3IodGhpcy5fcmVzb2x2ZUNoaWxkQWJpbGl0eUFjdGlvbihjaGlsZFJlc291cmNlQ29uZmlndXJhdGlvbiwgYWN0aW9uKSwgYWJpbGl0eSlcbiAgICAgIDogLyoqIEB0eXBlIHthbnl9ICovICh0YXJnZXRNb2RlbENsYXNzKS53aGVyZSh7fSlcblxuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgcXVlcnkuZmluZEJ5KGxvb2t1cClcblxuICAgIGlmICghZXhpc3RpbmcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90ICR7YWN0aW9ufSBuZXN0ZWQgJHtyZWxhdGlvbnNoaXBOYW1lfVtpZD0ke2lkfV06IHJlY29yZCBub3QgZm91bmQsIGRvZXMgbm90IGJlbG9uZyB0byBwYXJlbnQgJHtwYXJlbnQuZ2V0TW9kZWxDbGFzcygpLm5hbWV9W2lkPSR7cGFyZW50LmlkKCl9XSwgb3IgaXMgbm90IGF1dGhvcml6ZWQuYClcbiAgICB9XG5cbiAgICByZXR1cm4gZXhpc3RpbmdcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyBhbiBhbHJlYWR5LXNhdmVkIG5lc3RlZCBjaGlsZCBpcyBhdXRob3JpemVkIHVuZGVyIHRoZSBjaGlsZFxuICAgKiByZXNvdXJjZSdzIG93biBgY3JlYXRlYCBhYmlsaXR5LiBSb2xscyBiYWNrIHZpYSB0aHJvd24gZXJyb3Igd2hlbiBub3RcbiAgICogYXV0aG9yaXplZCBzbyB0aGUgb3V0ZXIgdHJhbnNhY3Rpb24gZGVzdHJveXMgdGhlIGluc2VydC5cbiAgICpcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBBcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vYXV0aG9yaXphdGlvbi9hYmlsaXR5LmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IGFyZ3MuYWJpbGl0eSAtIEN1cnJlbnQgYWJpbGl0eS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gYXJncy5jaGlsZCAtIENoaWxkIG1vZGVsIGluc3RhbmNlIGp1c3QgY3JlYXRlZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb259IGFyZ3MuY2hpbGRSZXNvdXJjZUNvbmZpZ3VyYXRpb24gLSBDaGlsZCByZXNvdXJjZSBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5yZWxhdGlvbnNoaXBOYW1lIC0gUGFyZW50J3MgcmVsYXRpb25zaGlwIG5hbWUgKGZvciBlcnJvciBtZXNzYWdlcykuXG4gICAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBhcmdzLnRhcmdldE1vZGVsQ2xhc3MgLSBDaGlsZCBtb2RlbCBjbGFzcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBfYXV0aG9yaXplQ3JlYXRlZENoaWxkKHthYmlsaXR5LCBjaGlsZCwgY2hpbGRSZXNvdXJjZUNvbmZpZ3VyYXRpb24sIHJlbGF0aW9uc2hpcE5hbWUsIHRhcmdldE1vZGVsQ2xhc3N9KSB7XG4gICAgaWYgKCFhYmlsaXR5KSByZXR1cm5cblxuICAgIGNvbnN0IGFiaWxpdHlBY3Rpb24gPSB0aGlzLl9yZXNvbHZlQ2hpbGRBYmlsaXR5QWN0aW9uKGNoaWxkUmVzb3VyY2VDb25maWd1cmF0aW9uLCBcImNyZWF0ZVwiKVxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSB0YXJnZXRNb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgIGNvbnN0IGF1dGhvcml6ZWRJZHMgPSBhd2FpdCAvKiogQHR5cGUge2FueX0gKi8gKHRhcmdldE1vZGVsQ2xhc3MpXG4gICAgICAuYWNjZXNzaWJsZUZvcihhYmlsaXR5QWN0aW9uLCBhYmlsaXR5KVxuICAgICAgLndoZXJlKHtbcHJpbWFyeUtleV06IGNoaWxkLnJlYWRBdHRyaWJ1dGUocHJpbWFyeUtleSl9KVxuICAgICAgLnBsdWNrKHByaW1hcnlLZXkpXG5cbiAgICBpZiAoYXV0aG9yaXplZElkcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTmVzdGVkIGNyZWF0ZSBvbiAke3JlbGF0aW9uc2hpcE5hbWV9WyR7dGFyZ2V0TW9kZWxDbGFzcy5uYW1lfV0gbm90IGF1dGhvcml6ZWQuYClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQmVzdC1lZmZvcnQgZm9yZWlnbi1rZXkgaW5mZXJlbmNlIGZvciByZWxhdGlvbnNoaXBzIHRoYXQgZG9uJ3QgZGVjbGFyZSBpdC5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gcGFyZW50IC0gUGFyZW50IG1vZGVsLlxuICAgKiBAcGFyYW0ge3tmb3JlaWduS2V5Pzogc3RyaW5nfX0gZGVmaW5pdGlvbiAtIFJlbGF0aW9uc2hpcCBkZWZpbml0aW9uLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIEZvcmVpZ24ta2V5IGF0dHJpYnV0ZSBuYW1lLlxuICAgKi9cbiAgX2luZmVyRm9yZWlnbktleShwYXJlbnQsIGRlZmluaXRpb24pIHtcbiAgICBpZiAoZGVmaW5pdGlvbi5mb3JlaWduS2V5KSByZXR1cm4gZGVmaW5pdGlvbi5mb3JlaWduS2V5XG5cbiAgICBjb25zdCBwYXJlbnRNb2RlbE5hbWUgPSBwYXJlbnQuZ2V0TW9kZWxDbGFzcygpLm5hbWUgfHwgXCJcIlxuICAgIGNvbnN0IHVuZGVyc2NvcmVkID0gcGFyZW50TW9kZWxOYW1lLnJlcGxhY2UoLyhbQS1aXSkvZywgKG1hdGNoLCBsZXR0ZXIsIGluZGV4KSA9PiAoaW5kZXggPT09IDAgPyBsZXR0ZXIudG9Mb3dlckNhc2UoKSA6IGBfJHtsZXR0ZXIudG9Mb3dlckNhc2UoKX1gKSlcblxuICAgIHJldHVybiBgJHtpbmZsZWN0aW9uLmNhbWVsaXplKHVuZGVyc2NvcmVkLCB0cnVlKX1JZGBcbiAgfVxuXG4gIC8qKlxuICAgKiBBZnRlciBuZXN0ZWQgd3JpdGVzLCBwcmVsb2FkIGV2ZXJ5IHJlbGF0aW9uc2hpcCBkZWNsYXJlZCBpbiB0aGVcbiAgICogcGFyZW50J3MgcGVybWl0IHNvIHRoZSBwb3N0LXNhdmUgc2VyaWFsaXplIHN0ZXAgZW1pdHMgdGhlbSBhbmQgdGhlXG4gICAqIGNsaWVudCBjYW4gcmVjb25jaWxlIGlkcy5cbiAgICpcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWwgLSBTYXZlZCBwYXJlbnQgbW9kZWwuXG4gICAqIEBwYXJhbSB7e2F0dHJpYnV0ZXM6IHN0cmluZ1tdLCBuZXN0ZWQ6IFJlY29yZDxzdHJpbmcsIGFueT59fSBwZXJtaXQgLSBQYXJzZWQgcGFyZW50IHBlcm1pdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBfcHJlbG9hZE5lc3RlZFdyaXRhYmxlUmVsYXRpb25zaGlwcyhtb2RlbCwgcGVybWl0KSB7XG4gICAgY29uc3QgcmVsYXRpb25zaGlwTmFtZXMgPSBPYmplY3Qua2V5cyhwZXJtaXQubmVzdGVkKVxuXG4gICAgaWYgKHJlbGF0aW9uc2hpcE5hbWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgICBmb3IgKGNvbnN0IHJlbGF0aW9uc2hpcE5hbWUgb2YgcmVsYXRpb25zaGlwTmFtZXMpIHtcbiAgICAgIGlmICh0eXBlb2YgLyoqIEB0eXBlIHthbnl9ICovIChtb2RlbCkubG9hZFJlbGF0aW9uc2hpcCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGF3YWl0IC8qKiBAdHlwZSB7YW55fSAqLyAobW9kZWwpLmxvYWRSZWxhdGlvbnNoaXAocmVsYXRpb25zaGlwTmFtZSlcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBQYXJzZXMgdGhlIFJhaWxzL2FwaV9tYWtlci1zdHlsZSBmbGF0IHBlcm1pdCBzcGVjIHJldHVybmVkIGZyb21cbiAqIGBwZXJtaXR0ZWRQYXJhbXMoYXJnKWAgaW50byBhIHN0cnVjdHVyZWQgc2hhcGUgdXNlZCBpbnRlcm5hbGx5IGJ5IHRoZVxuICogd3JpdGUgcGlwZWxpbmUuIFN0cmluZ3MgYmVjb21lIGF0dHJpYnV0ZSBwZXJtaXRzOyBvYmplY3RzIHdob3NlIGtleXNcbiAqIGVuZCBpbiBgQXR0cmlidXRlc2AgYmVjb21lIG5lc3RlZCBwZXJtaXRzICh0aGUga2V5IHByZWZpeCBuYW1lcyB0aGVcbiAqIHJlbGF0aW9uc2hpcCkuXG4gKlxuICogICBwYXJzZVBlcm1pdHRlZFBhcmFtcyhbXCJmaXJzdE5hbWVcIiwgXCJsYXN0TmFtZVwiLFxuICogICAgIHt0YXNrc0F0dHJpYnV0ZXM6IFtcImlkXCIsIFwiX2Rlc3Ryb3lcIiwgXCJuYW1lXCJdfVxuICogICBdKVxuICogICAvLyDihpIge1xuICogICAvLyAgIGF0dHJpYnV0ZXM6IFtcImZpcnN0TmFtZVwiLCBcImxhc3ROYW1lXCJdLFxuICogICAvLyAgIG5lc3RlZDoge1xuICogICAvLyAgICAgdGFza3M6IHthdHRyaWJ1dGVzOiBbXCJpZFwiLCBcIl9kZXN0cm95XCIsIFwibmFtZVwiXSwgbmVzdGVkOiB7fX1cbiAqICAgLy8gICB9XG4gKiAgIC8vIH1cbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nIHwgUmVjb3JkPHN0cmluZywgYW55Pj4gfCB1bmRlZmluZWR9IHBlcm1pdFNwZWMgLSBGbGF0IHBlcm1pdCBzcGVjLlxuICogQHJldHVybnMge3thdHRyaWJ1dGVzOiBzdHJpbmdbXSwgbmVzdGVkOiBSZWNvcmQ8c3RyaW5nLCB7YXR0cmlidXRlczogc3RyaW5nW10sIG5lc3RlZDogUmVjb3JkPHN0cmluZywgYW55Pn0+fX0gLSBQYXJzZWQgc3RydWN0dXJlLlxuICovXG5mdW5jdGlvbiBwYXJzZVBlcm1pdHRlZFBhcmFtcyhwZXJtaXRTcGVjKSB7XG4gIC8qKiBAdHlwZSB7c3RyaW5nW119ICovXG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSBbXVxuICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHthdHRyaWJ1dGVzOiBzdHJpbmdbXSwgbmVzdGVkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+fT59ICovXG4gIGNvbnN0IG5lc3RlZCA9IHt9XG5cbiAgaWYgKCFBcnJheS5pc0FycmF5KHBlcm1pdFNwZWMpKSByZXR1cm4ge2F0dHJpYnV0ZXMsIG5lc3RlZH1cblxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHBlcm1pdFNwZWMpIHtcbiAgICBpZiAodHlwZW9mIGVudHJ5ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBhdHRyaWJ1dGVzLnB1c2goZW50cnkpXG4gICAgfSBlbHNlIGlmIChlbnRyeSAmJiB0eXBlb2YgZW50cnkgPT09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoZW50cnkpKSB7XG4gICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhlbnRyeSkpIHtcbiAgICAgICAgaWYgKCFrZXkuZW5kc1dpdGgoXCJBdHRyaWJ1dGVzXCIpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHBlcm1pdHRlZFBhcmFtcyBlbnRyeTogbmVzdGVkIHJlbGF0aW9uc2hpcCBrZXlzIG11c3QgZW5kIGluIFwiQXR0cmlidXRlc1wiIChnb3QgXCIke2tleX1cIikuIFVzZSBcIiR7a2V5fUF0dHJpYnV0ZXNcIiBpbnN0ZWFkLmApXG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVsYXRpb25zaGlwTmFtZSA9IGtleS5zbGljZSgwLCAtXCJBdHRyaWJ1dGVzXCIubGVuZ3RoKVxuXG4gICAgICAgIGlmICghcmVsYXRpb25zaGlwTmFtZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBwZXJtaXR0ZWRQYXJhbXMgZW50cnk6IGVtcHR5IHJlbGF0aW9uc2hpcCBuYW1lIGluIGtleSBcIiR7a2V5fVwiLmApXG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBwZXJtaXR0ZWRQYXJhbXMgZW50cnkgZm9yIFwiJHtrZXl9XCI6IGV4cGVjdGVkIGFycmF5IHBlcm1pdCBzcGVjLCBnb3QgJHt0eXBlb2YgdmFsdWV9LmApXG4gICAgICAgIH1cblxuICAgICAgICBuZXN0ZWRbcmVsYXRpb25zaGlwTmFtZV0gPSBwYXJzZVBlcm1pdHRlZFBhcmFtcyh2YWx1ZSlcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHBlcm1pdHRlZFBhcmFtcyBlbnRyeTogZXhwZWN0ZWQgc3RyaW5nIG9yIG5lc3RlZC1hdHRyaWJ1dGVzIG9iamVjdCwgZ290ICR7dHlwZW9mIGVudHJ5fS5gKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7YXR0cmlidXRlcywgbmVzdGVkfVxufVxuXG4vKipcbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gcmVjZWl2ZXIgLSBNb2RlbCBpbnN0YW5jZSBvciBwcm90b3R5cGUuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IGF0dHJpYnV0ZXMgLSBJbmNvbWluZyBmcm9udGVuZC1tb2RlbCBhdHRyaWJ1dGVzLlxuICogQHBhcmFtIHtGcm9udGVuZE1vZGVsQmFzZVJlc291cmNlIHwgbnVsbH0gW3Jlc291cmNlXSAtIFJlc291cmNlIGluc3RhbmNlIGZvciB2aXJ0dWFsLXNldHRlciBkZXRlY3Rpb24uXG4gKiBAcGFyYW0ge3N0cmluZ1tdIHwgbnVsbH0gW3Blcm1pdHRlZEF0dHJpYnV0ZU5hbWVzXSAtIE9wdGlvbmFsIGV4cGxpY2l0IHBlcm1pdCBsaXN0LiBgbnVsbGAgZmFsbHMgYmFjayB0byBzZXR0ZXItZXhpc3RlbmNlIGNoZWNrcyBvbmx5LlxuICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIGFueT59IC0gV3JpdGFibGUgYXR0cmlidXRlcyBvbmx5LlxuICovXG5mdW5jdGlvbiBmaWx0ZXJXcml0YWJsZUZyb250ZW5kTW9kZWxBdHRyaWJ1dGVzKHJlY2VpdmVyLCBhdHRyaWJ1dGVzLCByZXNvdXJjZSA9IC8qKiBAdHlwZSB7RnJvbnRlbmRNb2RlbEJhc2VSZXNvdXJjZSB8IG51bGx9ICovIChudWxsKSwgcGVybWl0dGVkQXR0cmlidXRlTmFtZXMgPSBudWxsKSB7XG4gIC8vIEZyb250ZW5kLW1vZGVsIHdyaXRlcyBzaG91bGQgZmFpbCBmYXN0IHdoZW4gY2FsbGVycyBzdWJtaXQgcmVhZC1vbmx5IG9yIHVua25vd24gYXR0cnMuXG4gIC8vIFNpbGVudCBkcm9wcyBoaWRlIGNvbnRyYWN0IG1pc3Rha2VzIGluIGdlbmVyYXRlZCBtb2RlbHMgYW5kIGFwcC1zaWRlIHdyYXBwZXIgY29kZS5cbiAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqL1xuICBjb25zdCB3cml0YWJsZUF0dHJpYnV0ZXMgPSB7fVxuICAvKiogQHR5cGUge3N0cmluZ1tdfSAqL1xuICBjb25zdCBpbnZhbGlkQXR0cmlidXRlcyA9IFtdXG4gIC8qKiBAdHlwZSB7c3RyaW5nW119ICovXG4gIGNvbnN0IG5vdFBlcm1pdHRlZEF0dHJpYnV0ZXMgPSBbXVxuXG4gIGNvbnN0IHBlcm1pdFNldCA9IEFycmF5LmlzQXJyYXkocGVybWl0dGVkQXR0cmlidXRlTmFtZXMpID8gbmV3IFNldChwZXJtaXR0ZWRBdHRyaWJ1dGVOYW1lcykgOiBudWxsXG4gIGNvbnN0IHRyYW5zbGF0ZWRTZXQgPSByZXNvdXJjZSA/IG5ldyBTZXQoLyoqIEB0eXBlIHt0eXBlb2YgRnJvbnRlbmRNb2RlbEJhc2VSZXNvdXJjZX0gKi8gKHJlc291cmNlLmNvbnN0cnVjdG9yKS50cmFuc2xhdGVkQXR0cmlidXRlcyB8fCBbXSkgOiBuZXcgU2V0KClcblxuICBmb3IgKGNvbnN0IFthdHRyaWJ1dGVOYW1lLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoYXR0cmlidXRlcykpIHtcbiAgICBpZiAocGVybWl0U2V0ICYmICFwZXJtaXRTZXQuaGFzKGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgICBub3RQZXJtaXR0ZWRBdHRyaWJ1dGVzLnB1c2goYXR0cmlidXRlTmFtZSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgY29uc3Qgc2V0dGVyTmFtZSA9IGBzZXQke2luZmxlY3Rpb24uY2FtZWxpemUoYXR0cmlidXRlTmFtZSl9YFxuICAgIGNvbnN0IHJlc291cmNlU2V0dGVyTmFtZSA9IGAke3NldHRlck5hbWV9QXR0cmlidXRlYFxuXG4gICAgaWYgKHNldHRlck5hbWUgaW4gcmVjZWl2ZXIpIHtcbiAgICAgIHdyaXRhYmxlQXR0cmlidXRlc1thdHRyaWJ1dGVOYW1lXSA9IHZhbHVlXG4gICAgfSBlbHNlIGlmIChyZXNvdXJjZSAmJiB0eXBlb2YgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBhbnk+fSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAocmVzb3VyY2UpKVtyZXNvdXJjZVNldHRlck5hbWVdID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHdyaXRhYmxlQXR0cmlidXRlc1thdHRyaWJ1dGVOYW1lXSA9IHZhbHVlXG4gICAgfSBlbHNlIGlmICh0cmFuc2xhdGVkU2V0LmhhcyhhdHRyaWJ1dGVOYW1lKSkge1xuICAgICAgd3JpdGFibGVBdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdID0gdmFsdWVcbiAgICB9IGVsc2Uge1xuICAgICAgaW52YWxpZEF0dHJpYnV0ZXMucHVzaChhdHRyaWJ1dGVOYW1lKVxuICAgIH1cbiAgfVxuXG4gIGlmIChub3RQZXJtaXR0ZWRBdHRyaWJ1dGVzLmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEZyb250ZW5kIG1vZGVsIHdyaXRlIGF0dHJpYnV0ZXMgbm90IHBlcm1pdHRlZCBieSBwZXJtaXR0ZWRQYXJhbXMoKTogJHtub3RQZXJtaXR0ZWRBdHRyaWJ1dGVzLmpvaW4oXCIsIFwiKX1gKVxuICB9XG5cbiAgaWYgKGludmFsaWRBdHRyaWJ1dGVzLmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZnJvbnRlbmQgbW9kZWwgd3JpdGUgYXR0cmlidXRlczogJHtpbnZhbGlkQXR0cmlidXRlcy5qb2luKFwiLCBcIil9YClcbiAgfVxuXG4gIHJldHVybiB3cml0YWJsZUF0dHJpYnV0ZXNcbn1cbiJdfQ==
|
|
825
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1yZXNvdXJjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9mcm9udGVuZC1tb2RlbC1yZXNvdXJjZS9iYXNlLXJlc291cmNlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLHlCQUF5QixNQUFNLG1DQUFtQyxDQUFBO0FBQ3pFLE9BQU8sS0FBSyxVQUFVLE1BQU0sWUFBWSxDQUFBO0FBRXhDOzs7Ozs7OztHQVFHO0FBRUg7Ozs7Ozs7Ozs7R0FVRztBQUVIOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sT0FBTyx5QkFBMEIsU0FBUSx5QkFBeUI7SUFDOUU7O3lEQUVxRDtJQUNyRCxNQUFNLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQTtJQUM3Qjs7cUNBRWlDO0lBQ2pDLE1BQU0sQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFBO0lBQzVCOzs4Q0FFMEM7SUFDMUMsTUFBTSxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUE7SUFDOUI7O3FDQUVpQztJQUNqQyxNQUFNLENBQUMsa0JBQWtCLEdBQUcsU0FBUyxDQUFBO0lBQ3JDOztxQ0FFaUM7SUFDakMsTUFBTSxDQUFDLHlCQUF5QixHQUFHLFNBQVMsQ0FBQTtJQUM1Qzs7cUNBRWlDO0lBQ2pDLE1BQU0sQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFBO0lBQ2pDOztxQ0FFaUM7SUFDakMsTUFBTSxDQUFDLHFCQUFxQixHQUFHLFNBQVMsQ0FBQTtJQUN4Qzs7cUNBRWlDO0lBQ2pDLE1BQU0sQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFBO0lBQ2hDOztxQ0FFaUM7SUFDakMsTUFBTSxDQUFDLG9CQUFvQixHQUFHLFNBQVMsQ0FBQTtJQUV2Qzs7O09BR0c7SUFDSCxZQUFZLElBQUk7UUFDZCxLQUFLLENBQUM7WUFDSixPQUFPLEVBQUUsU0FBUyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUztZ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SUFFRCxPQUFPLGtCQUFrQixDQUFBO0FBQzNCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IEF1dGhvcml6YXRpb25CYXNlUmVzb3VyY2UgZnJvbSBcIi4uL2F1dGhvcml6YXRpb24vYmFzZS1yZXNvdXJjZS5qc1wiXG5pbXBvcnQgKiBhcyBpbmZsZWN0aW9uIGZyb20gXCJpbmZsZWN0aW9uXCJcblxuLyoqXG4gKiBGcm9udGVuZE1vZGVsUmVzb3VyY2VDb250cm9sbGVyQXJncyB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gRnJvbnRlbmRNb2RlbFJlc291cmNlQ29udHJvbGxlckFyZ3NcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29udHJvbGxlci5qc1wiKS5kZWZhdWx0fSBjb250cm9sbGVyIC0gRnJvbnRlbmQtbW9kZWwgY29udHJvbGxlciBpbnN0YW5jZS5cbiAqIEBwcm9wZXJ0eSB7dHlwZW9mIGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbENsYXNzIC0gQmFja2luZyBtb2RlbCBjbGFzcy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBtb2RlbE5hbWUgLSBNb2RlbCBuYW1lLlxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCA/Pn0gcGFyYW1zIC0gUmVxdWVzdCBwYXJhbXMuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuTm9ybWFsaXplZEZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb24gfCBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb259IHJlc291cmNlQ29uZmlndXJhdGlvbiAtIE5vcm1hbGl6ZWQgcmVzb3VyY2UgY29uZmlndXJhdGlvbiAob3IgcmF3IGlucHV0IHNoYXBlIGR1cmluZyBlYXJseSBib290c3RyYXApLlxuICovXG5cbi8qKlxuICogRnJvbnRlbmRNb2RlbFJlc291cmNlQWJpbGl0eUFyZ3MgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IEZyb250ZW5kTW9kZWxSZXNvdXJjZUFiaWxpdHlBcmdzXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2F1dGhvcml6YXRpb24vYWJpbGl0eS5qc1wiKS5kZWZhdWx0fSBbYWJpbGl0eV0gLSBBYmlsaXR5IGluc3RhbmNlIHdoZW4gdGhlIHJlc291cmNlIGlzIHVzZWQgZGlyZWN0bHkgZm9yIGF1dGhvcml6YXRpb24uXG4gKiBAcHJvcGVydHkge1JlY29yZDxzdHJpbmcsID8+fSBbY29udGV4dF0gLSBBYmlsaXR5IGNvbnRleHQuXG4gKiBAcHJvcGVydHkge1JlY29yZDxzdHJpbmcsID8+fSBbbG9jYWxzXSAtIEFiaWxpdHkgbG9jYWxzLlxuICogQHByb3BlcnR5IHt0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IFttb2RlbENsYXNzXSAtIE9wdGlvbmFsIGJhY2tpbmcgbW9kZWwgY2xhc3Mgb3ZlcnJpZGUuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW21vZGVsTmFtZV0gLSBPcHRpb25hbCBtb2RlbCBuYW1lIG92ZXJyaWRlLlxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCA/Pn0gW3BhcmFtc10gLSBPcHRpb25hbCBwYXJhbXMgb3ZlcnJpZGUuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuTm9ybWFsaXplZEZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb24gfCBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb259IFtyZXNvdXJjZUNvbmZpZ3VyYXRpb25dIC0gT3B0aW9uYWwgbm9ybWFsaXplZCByZXNvdXJjZSBjb25maWd1cmF0aW9uLlxuICovXG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgYmFja2VuZCBmcm9udGVuZC1tb2RlbCByZXNvdXJjZXMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2UgZXh0ZW5kcyBBdXRob3JpemF0aW9uQmFzZVJlc291cmNlIHtcbiAgLyoqXG4gICAqIEF0dHJpYnV0ZXMuXG4gICAgQHR5cGUge1JlY29yZDxzdHJpbmcsID8+IHwgc3RyaW5nW10gfCB1bmRlZmluZWR9ICovXG4gIHN0YXRpYyBhdHRyaWJ1dGVzID0gdW5kZWZpbmVkXG4gIC8qKlxuICAgKiBBYmlsaXRpZXMuXG4gICAgQHR5cGUge3N0cmluZ1tdIHwgdW5kZWZpbmVkfSAqL1xuICBzdGF0aWMgYWJpbGl0aWVzID0gdW5kZWZpbmVkXG4gIC8qKlxuICAgKiBBdHRhY2htZW50cy5cbiAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz4gfCB1bmRlZmluZWR9ICovXG4gIHN0YXRpYyBhdHRhY2htZW50cyA9IHVuZGVmaW5lZFxuICAvKipcbiAgICogQ29sbGVjdGlvbiBjb21tYW5kcy5cbiAgICBAdHlwZSB7c3RyaW5nW10gfCB1bmRlZmluZWR9ICovXG4gIHN0YXRpYyBjb2xsZWN0aW9uQ29tbWFuZHMgPSB1bmRlZmluZWRcbiAgLyoqXG4gICAqIEJ1aWx0IGluIGNvbGxlY3Rpb24gY29tbWFuZHMuXG4gICAgQHR5cGUge3N0cmluZ1tdIHwgdW5kZWZpbmVkfSAqL1xuICBzdGF0aWMgYnVpbHRJbkNvbGxlY3Rpb25Db21tYW5kcyA9IHVuZGVmaW5lZFxuICAvKipcbiAgICogTWVtYmVyIGNvbW1hbmRzLlxuICAgIEB0eXBlIHtzdHJpbmdbXSB8IHVuZGVmaW5lZH0gKi9cbiAgc3RhdGljIG1lbWJlckNvbW1hbmRzID0gdW5kZWZpbmVkXG4gIC8qKlxuICAgKiBCdWlsdCBpbiBtZW1iZXIgY29tbWFuZHMuXG4gICAgQHR5cGUge3N0cmluZ1tdIHwgdW5kZWZpbmVkfSAqL1xuICBzdGF0aWMgYnVpbHRJbk1lbWJlckNvbW1hbmRzID0gdW5kZWZpbmVkXG4gIC8qKlxuICAgKiBSZWxhdGlvbnNoaXBzLlxuICAgIEB0eXBlIHtzdHJpbmdbXSB8IHVuZGVmaW5lZH0gKi9cbiAgc3RhdGljIHJlbGF0aW9uc2hpcHMgPSB1bmRlZmluZWRcbiAgLyoqXG4gICAqIFRyYW5zbGF0ZWQgYXR0cmlidXRlcy5cbiAgICBAdHlwZSB7c3RyaW5nW10gfCB1bmRlZmluZWR9ICovXG4gIHN0YXRpYyB0cmFuc2xhdGVkQXR0cmlidXRlcyA9IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBSdW5zIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge0Zyb250ZW5kTW9kZWxSZXNvdXJjZUFiaWxpdHlBcmdzIHwgRnJvbnRlbmRNb2RlbFJlc291cmNlQ29udHJvbGxlckFyZ3N9IGFyZ3MgLSBSZXNvdXJjZSBhcmdzLlxuICAgKi9cbiAgY29uc3RydWN0b3IoYXJncykge1xuICAgIHN1cGVyKHtcbiAgICAgIGFiaWxpdHk6IFwiYWJpbGl0eVwiIGluIGFyZ3MgPyBhcmdzLmFiaWxpdHkgOiB1bmRlZmluZWQsXG4gICAgICBjb250ZXh0OiBcImNvbnRleHRcIiBpbiBhcmdzID8gYXJncy5jb250ZXh0IHx8IHt9IDoge30sXG4gICAgICBsb2NhbHM6IFwibG9jYWxzXCIgaW4gYXJncyA/IGFyZ3MubG9jYWxzIHx8IHt9IDoge31cbiAgICB9KVxuXG4gICAgdGhpcy5jb250cm9sbGVyID0gXCJjb250cm9sbGVyXCIgaW4gYXJncyA/IGFyZ3MuY29udHJvbGxlciA6IHVuZGVmaW5lZFxuICAgIHRoaXMubW9kZWxDbGFzc1ZhbHVlID0gXCJtb2RlbENsYXNzXCIgaW4gYXJncyA/IGFyZ3MubW9kZWxDbGFzcyA6IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge3R5cGVvZiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gKi8gKC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7dHlwZW9mIEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2V9ICovICh0aGlzLmNvbnN0cnVjdG9yKS5tb2RlbENsYXNzKCkpXG4gICAgdGhpcy5tb2RlbE5hbWVWYWx1ZSA9IFwibW9kZWxOYW1lXCIgaW4gYXJncyA/IGFyZ3MubW9kZWxOYW1lIDogKHRoaXMubW9kZWxDbGFzc1ZhbHVlPy5nZXRNb2RlbE5hbWUgPyB0aGlzLm1vZGVsQ2xhc3NWYWx1ZS5nZXRNb2RlbE5hbWUoKSA6IHRoaXMubW9kZWxDbGFzc1ZhbHVlPy5uYW1lIHx8IFwiXCIpXG4gICAgdGhpcy5wYXJhbXNWYWx1ZSA9IFwicGFyYW1zXCIgaW4gYXJncyA/IGFyZ3MucGFyYW1zIDogdW5kZWZpbmVkXG4gICAgdGhpcy5yZXNvdXJjZUNvbmZpZ3VyYXRpb25WYWx1ZSA9IFwicmVzb3VyY2VDb25maWd1cmF0aW9uXCIgaW4gYXJncyA/IGFyZ3MucmVzb3VyY2VDb25maWd1cmF0aW9uIDogLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Gcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9ufSAqLyAoe2F0dHJpYnV0ZXM6IFtdfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHR5cGVkIGNvbnRyb2xsZXIgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9jb250cm9sbGVyLmpzXCIpLmRlZmF1bHQgJiB7XG4gICAqICAgZnJvbnRlbmRNb2RlbEF1dGhvcml6ZWRRdWVyeTogKGFjdGlvbjogXCJpbmRleFwiIHwgXCJmaW5kXCIgfCBcImNyZWF0ZVwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwiIHwgXCJhdHRhY2hcIiB8IFwiZG93bmxvYWRcIiB8IFwidXJsXCIpID0+IGltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHQ8dW5rbm93bj4sXG4gICAqICAgZnJvbnRlbmRNb2RlbEluZGV4UXVlcnk6ICgpID0+IGltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L21vZGVsLWNsYXNzLXF1ZXJ5LmpzXCIpLmRlZmF1bHQ8dW5rbm93bj4sXG4gICAqICAgZnJvbnRlbmRNb2RlbFByZWxvYWQ6ICgpID0+IGltcG9ydChcIi4uL2RhdGFiYXNlL3F1ZXJ5L2luZGV4LmpzXCIpLk5lc3RlZFByZWxvYWRSZWNvcmQgfCBudWxsLFxuICAgKiAgIHNlcmlhbGl6ZUZyb250ZW5kTW9kZWw6IChtb2RlbDogaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQpID0+IFByb21pc2U8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+XG4gICAqIH19IC0gQ29udHJvbGxlciBpbnN0YW5jZSB3aXRoIGZyb250ZW5kLW1vZGVsIGhlbHBlcnMuXG4gICAqL1xuICB0eXBlZENvbnRyb2xsZXJJbnN0YW5jZSgpIHtcbiAgICByZXR1cm4gLyoqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS4gQHR5cGUgez99ICovICh0aGlzLmNvbnRyb2xsZXIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyByZXNvdXJjZSBjb25maWcuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb259IC0gU3RhdGljIHJlc291cmNlIGNvbmZpZyAocmF3IHVzZXIgaW5wdXQgc2hhcGU7IGNvbnN1bWVycyBub3JtYWxpemUpLlxuICAgKi9cbiAgc3RhdGljIHJlc291cmNlQ29uZmlnKCkge1xuICAgIC8qKlxuICAgICAqIENvbmZpZy5cbiAgICAgIEB0eXBlIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb259ICovXG4gICAgY29uc3QgY29uZmlnID0ge1xuICAgICAgYXR0cmlidXRlczogdGhpcy5hdHRyaWJ1dGVzIHx8IFtdXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuYWJpbGl0aWVzKSBjb25maWcuYWJpbGl0aWVzID0gdGhpcy5hYmlsaXRpZXNcbiAgICBpZiAodGhpcy5hdHRhY2htZW50cykgY29uZmlnLmF0dGFjaG1lbnRzID0gdGhpcy5hdHRhY2htZW50c1xuICAgIGlmICh0aGlzLmJ1aWx0SW5Db2xsZWN0aW9uQ29tbWFuZHMpIGNvbmZpZy5idWlsdEluQ29sbGVjdGlvbkNvbW1hbmRzID0gdGhpcy5idWlsdEluQ29sbGVjdGlvbkNvbW1hbmRzXG4gICAgaWYgKHRoaXMuYnVpbHRJbk1lbWJlckNvbW1hbmRzKSBjb25maWcuYnVpbHRJbk1lbWJlckNvbW1hbmRzID0gdGhpcy5idWlsdEluTWVtYmVyQ29tbWFuZHNcbiAgICBpZiAodGhpcy5jb2xsZWN0aW9uQ29tbWFuZHMpIGNvbmZpZy5jb2xsZWN0aW9uQ29tbWFuZHMgPSB0aGlzLmNvbGxlY3Rpb25Db21tYW5kc1xuICAgIGlmICh0aGlzLm1lbWJlckNvbW1hbmRzKSBjb25maWcubWVtYmVyQ29tbWFuZHMgPSB0aGlzLm1lbWJlckNvbW1hbmRzXG4gICAgaWYgKHRoaXMucmVsYXRpb25zaGlwcykgY29uZmlnLnJlbGF0aW9uc2hpcHMgPSB0aGlzLnJlbGF0aW9uc2hpcHNcblxuICAgIHJldHVybiBjb25maWdcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNvbnRyb2xsZXIgaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9jb250cm9sbGVyLmpzXCIpLmRlZmF1bHR9IC0gQ29udHJvbGxlciBpbnN0YW5jZS5cbiAgICovXG4gIGNvbnRyb2xsZXJJbnN0YW5jZSgpIHtcbiAgICBpZiAoIXRoaXMuY29udHJvbGxlcikgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gcmVxdWlyZXMgYSBjb250cm9sbGVyIGluc3RhbmNlLmApXG5cbiAgICByZXR1cm4gdGhpcy5jb250cm9sbGVyXG4gIH1cblxuICAvKipcbiAgICogUnVucyBtb2RlbCBjbGFzcy5cbiAgICogQHJldHVybnMge3R5cGVvZiBpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gLSBNb2RlbCBjbGFzcy5cbiAgICovXG4gIG1vZGVsQ2xhc3MoKSB7XG4gICAgaWYgKCF0aGlzLm1vZGVsQ2xhc3NWYWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gcmVxdWlyZXMgYSBtb2RlbCBjbGFzcy5gKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm1vZGVsQ2xhc3NWYWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbW9kZWwgbmFtZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBNb2RlbCBuYW1lLlxuICAgKi9cbiAgbW9kZWxOYW1lKCkge1xuICAgIGlmICghdGhpcy5tb2RlbE5hbWVWYWx1ZSkgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMuY29uc3RydWN0b3IubmFtZX0gcmVxdWlyZXMgYSBtb2RlbCBuYW1lLmApXG5cbiAgICByZXR1cm4gdGhpcy5tb2RlbE5hbWVWYWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcGFyYW1zLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz59IC0gUGFyYW1zLlxuICAgKi9cbiAgcGFyYW1zKCkgeyByZXR1cm4gdGhpcy5wYXJhbXNWYWx1ZSB8fCBzdXBlci5wYXJhbXMoKSB8fCB7fSB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVzb3VyY2UgY29uZmlndXJhdGlvbi5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuTm9ybWFsaXplZEZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb24gfCBpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb259IC0gUmVzb3VyY2UgY29uZmlnIChub3JtYWxpemVkIGF0IHJ1bnRpbWU7IHJhdyBkdXJpbmcgZWFybHkgYm9vdHN0cmFwKS5cbiAgICovXG4gIHJlc291cmNlQ29uZmlndXJhdGlvbigpIHtcbiAgICBpZiAoIXRoaXMucmVzb3VyY2VDb25maWd1cmF0aW9uVmFsdWUpIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IHJlcXVpcmVzIGEgcmVzb3VyY2UgY29uZmlndXJhdGlvbi5gKVxuXG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2VDb25maWd1cmF0aW9uVmFsdWVcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgUmFpbHMtc3Ryb25nLXBhcmFtcyAvIGFwaV9tYWtlci1zdHlsZSBwZXJtaXQgc3BlYyBkZWNsYXJpbmdcbiAgICogd2hpY2ggYXR0cmlidXRlcyBhbmQgbmVzdGVkIGF0dHJpYnV0ZXMgYXJlIHdyaXRhYmxlIGZvciB0aGUgY3VycmVudFxuICAgKiByZXF1ZXN0LiBTdWJtaXR0aW5nIGFuIGF0dHJpYnV0ZSBvciBuZXN0ZWQtcmVsYXRpb25zaGlwIGtleSB0aGF0IGlzXG4gICAqIG5vdCBwZXJtaXR0ZWQgcmFpc2VzIGFuIGVycm9yIGFuZCBmYWlscyB0aGUgd3JpdGUuXG4gICAqXG4gICAqIFRoZSByZXR1cm5lZCB2YWx1ZSBpcyBhIGZsYXQgYXJyYXkgdGhhdCBtaXhlczpcbiAgICogICAtIGBcImF0dHJpYnV0ZU5hbWVcImAgc3RyaW5ncyBmb3IgcGxhaW4gYXR0cmlidXRlIHdyaXRlc1xuICAgKiAgIC0gYHs8cmVsYXRpb25zaGlwTmFtZT5BdHRyaWJ1dGVzOiBbLi4uXX1gIG9iamVjdHMgd2hlcmUgdGhlIHZhbHVlXG4gICAqICAgICBpcyBpdHNlbGYgYSBwZXJtaXQgc3BlYyBmb3IgdGhlIG5lc3RlZCByZWxhdGlvbnNoaXBcbiAgICpcbiAgICogVGhpcyBtYXRjaGVzIFJhaWxzIHN0cm9uZ19wYXJhbXMgKGBwZXJtaXQoOmZpcnN0X25hbWUsIDpsYXN0X25hbWUsXG4gICAqIGNvbnRhY3RfYXR0cmlidXRlczogWzplbWFpbCwgZGV0YWlsc19hdHRyaWJ1dGVzOiBbOmRldGFpbF1dKWApIGFuZFxuICAgKiB0aGUgYXBpX21ha2VyIHNpc3RlciBwcm9qZWN0LiBJbmNsdWRlIGBcIl9kZXN0cm95XCJgIGluc2lkZSBhIG5lc3RlZFxuICAgKiBwZXJtaXQgdG8gYWxsb3cgYF9kZXN0cm95OiB0cnVlYCBlbnRyaWVzIGZvciB0aGF0IHJlbGF0aW9uc2hpcCDigJRcbiAgICogdGhlIG1vZGVsIG11c3QgYWxzbyBkZWNsYXJlIGBhY2NlcHRzTmVzdGVkQXR0cmlidXRlc0ZvcihuYW1lLFxuICAgKiB7YWxsb3dEZXN0cm95OiB0cnVlfSlgIGZvciB0aGUgZGVzdHJveSB0byBiZSBhcHBsaWVkLlxuICAgKlxuICAgKiBFeGFtcGxlOlxuICAgKlxuICAgKiAgIGNsYXNzIFByb2plY3RSZXNvdXJjZSBleHRlbmRzIEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2Uge1xuICAgKiAgICAgcGVybWl0dGVkUGFyYW1zKGFyZykge1xuICAgKiAgICAgICByZXR1cm4gW1xuICAgKiAgICAgICAgIFwibmFtZVwiLFxuICAgKiAgICAgICAgIFwiZGVzY3JpcHRpb25cIixcbiAgICogICAgICAgICB7dGFza3NBdHRyaWJ1dGVzOiBbXCJpZFwiLCBcIl9kZXN0cm95XCIsIFwibmFtZVwiLFxuICAgKiAgICAgICAgICAge3N1YnRhc2tzQXR0cmlidXRlczogW1wiaWRcIiwgXCJfZGVzdHJveVwiLCBcIm5hbWVcIl19XG4gICAqICAgICAgICAgXX1cbiAgICogICAgICAgXVxuICAgKiAgICAgfVxuICAgKiAgIH1cbiAgICpcbiAgICogRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5zIGBbXWAg4oCUIG5vdGhpbmcgcGVybWl0dGVkLiBTdWJjbGFzc2VzXG4gICAqIG11c3Qgb3ZlcnJpZGUgdG8gZW5hYmxlIHdyaXRlcy4gQSByZXNvdXJjZSB0aGF0IGRvZXMgbm90IGRlY2xhcmVcbiAgICogYHBlcm1pdHRlZFBhcmFtc2AgY2Fubm90IGFjY2VwdCBhbnkgd3JpdGUuXG4gICAqIEBwYXJhbSB7e2FjdGlvbj86IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiLCBwYXJhbXM/OiBSZWNvcmQ8c3RyaW5nLCA/PiwgYWJpbGl0eT86IGltcG9ydChcIi4uL2F1dGhvcml6YXRpb24vYWJpbGl0eS5qc1wiKS5kZWZhdWx0LCBsb2NhbHM/OiBSZWNvcmQ8c3RyaW5nLCA/Pn19IFthcmddIC0gUmVxdWVzdCBjb250ZXh0LlxuICAgKiBAcmV0dXJucyB7QXJyYXk8c3RyaW5nIHwgUmVjb3JkPHN0cmluZywgPz4+fSAtIFBlcm1pdCBzcGVjLlxuICAgKi9cbiAgcGVybWl0dGVkUGFyYW1zKGFyZykge1xuICAgIHZvaWQgYXJnXG5cbiAgICByZXR1cm4gW11cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHByaW1hcnkga2V5LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIFByaW1hcnkga2V5LlxuICAgKi9cbiAgcHJpbWFyeUtleSgpIHsgcmV0dXJuIHRoaXMubW9kZWxDbGFzcygpLnByaW1hcnlLZXkoKSB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYXV0aG9yaXplZCBxdWVyeS5cbiAgICogQHBhcmFtIHtcImluZGV4XCIgfCBcImZpbmRcIiB8IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCIgfCBcImF0dGFjaFwiIHwgXCJkb3dubG9hZFwiIHwgXCJ1cmxcIn0gYWN0aW9uIC0gQWJpbGl0eSBhY3Rpb24uXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9xdWVyeS9tb2RlbC1jbGFzcy1xdWVyeS5qc1wiKS5kZWZhdWx0PD8+fSAtIEF1dGhvcml6ZWQgcXVlcnkuXG4gICAqL1xuICBhdXRob3JpemVkUXVlcnkoYWN0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMudHlwZWRDb250cm9sbGVySW5zdGFuY2UoKS5mcm9udGVuZE1vZGVsQXV0aG9yaXplZFF1ZXJ5KGFjdGlvbilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHN1cHBvcnRzIHBsdWNrLlxuICAgKiBAcGFyYW0ge1wiaW5kZXhcIiB8IFwiZmluZFwiIHwgXCJjcmVhdGVcIiB8IFwidXBkYXRlXCIgfCBcImRlc3Ryb3lcIiB8IFwiYXR0YWNoXCIgfCBcImRvd25sb2FkXCIgfCBcInVybFwifSBhY3Rpb24gLSBBY3Rpb24uXG4gICAqIEByZXR1cm5zIHtib29sZWFuIHwgUHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIHBsdWNrIGlzIHN1cHBvcnRlZC5cbiAgICovXG4gIHN1cHBvcnRzUGx1Y2soYWN0aW9uKSB7XG4gICAgdm9pZCBhY3Rpb25cblxuICAgIHJldHVybiBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykucmVjb3JkcyA9PT0gRnJvbnRlbmRNb2RlbEJhc2VSZXNvdXJjZS5wcm90b3R5cGUucmVjb3Jkc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc3VwcG9ydHMgY291bnQuXG4gICAqIEBwYXJhbSB7XCJpbmRleFwiIHwgXCJmaW5kXCIgfCBcImNyZWF0ZVwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwiIHwgXCJhdHRhY2hcIiB8IFwiZG93bmxvYWRcIiB8IFwidXJsXCJ9IGFjdGlvbiAtIEFjdGlvbi5cbiAgICogQHJldHVybnMge2Jvb2xlYW4gfCBQcm9taXNlPGJvb2xlYW4+fSAtIFdoZXRoZXIgY291bnQgaXMgc3VwcG9ydGVkLlxuICAgKi9cbiAgc3VwcG9ydHNDb3VudChhY3Rpb24pIHtcbiAgICB2b2lkIGFjdGlvblxuXG4gICAgcmV0dXJuIE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKS5yZWNvcmRzID09PSBGcm9udGVuZE1vZGVsQmFzZVJlc291cmNlLnByb3RvdHlwZS5yZWNvcmRzIHx8XG4gICAgICBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykuY291bnQgIT09IEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2UucHJvdG90eXBlLmNvdW50XG4gIH1cblxuICAvKipcbiAgICogUnVucyBiZWZvcmUgYWN0aW9uLlxuICAgKiBAcGFyYW0ge1wiaW5kZXhcIiB8IFwiZmluZFwiIHwgXCJjcmVhdGVcIiB8IFwidXBkYXRlXCIgfCBcImRlc3Ryb3lcIiB8IFwiYXR0YWNoXCIgfCBcImRvd25sb2FkXCIgfCBcInVybFwifSBhY3Rpb24gLSBBY3Rpb24uXG4gICAqIEByZXR1cm5zIHtib29sZWFuIHwgdm9pZCB8IFByb21pc2U8Ym9vbGVhbiB8IHZvaWQ+fSAtIENvbnRpbnVlIHByb2Nlc3NpbmcgdW5sZXNzIGZhbHNlLlxuICAgKi9cbiAgYmVmb3JlQWN0aW9uKGFjdGlvbikge1xuICAgIHZvaWQgYWN0aW9uXG5cbiAgICAvLyBOby1vcCBieSBkZWZhdWx0LlxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgcmVjb3Jkcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHRbXT59IC0gUmVjb3JkcyBmb3IgaW5kZXggYWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgcmVjb3JkcygpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy50eXBlZENvbnRyb2xsZXJJbnN0YW5jZSgpLmZyb250ZW5kTW9kZWxJbmRleFF1ZXJ5KCkudG9BcnJheSgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjb3VudC5cbiAgICogQHJldHVybnMge1Byb21pc2U8bnVtYmVyPn0gLSBSZWNvcmRzIGNvdW50IGZvciBpbmRleCBhY3Rpb24uXG4gICAqL1xuICBhc3luYyBjb3VudCgpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy50eXBlZENvbnRyb2xsZXJJbnN0YW5jZSgpLmZyb250ZW5kTW9kZWxJbmRleFF1ZXJ5KCkuY291bnQoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZmluZC5cbiAgICogQHBhcmFtIHtcImZpbmRcIiB8IFwidXBkYXRlXCIgfCBcImRlc3Ryb3lcIiB8IFwiYXR0YWNoXCIgfCBcImRvd25sb2FkXCIgfCBcInVybFwifSBhY3Rpb24gLSBBY3Rpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyfSBpZCAtIFJlY29yZCBpZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQgfCBudWxsPn0gLSBMb2NhdGVkIG1vZGVsLlxuICAgKi9cbiAgYXN5bmMgZmluZChhY3Rpb24sIGlkKSB7XG4gICAgbGV0IHF1ZXJ5ID0gdGhpcy5hdXRob3JpemVkUXVlcnkoYWN0aW9uKVxuICAgIGNvbnN0IHByZWxvYWQgPSBhY3Rpb24gPT09IFwiZmluZFwiID8gdGhpcy50eXBlZENvbnRyb2xsZXJJbnN0YW5jZSgpLmZyb250ZW5kTW9kZWxQcmVsb2FkKCkgOiBudWxsXG5cbiAgICBpZiAocHJlbG9hZCkge1xuICAgICAgcXVlcnkgPSBxdWVyeS5wcmVsb2FkKHByZWxvYWQpXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHF1ZXJ5LmZpbmRCeSh7W3RoaXMucHJpbWFyeUtleSgpXTogaWR9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY3JlYXRlLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBhdHRyaWJ1dGVzIC0gQ3JlYXRlIGF0dHJpYnV0ZXMuXG4gICAqIEBwYXJhbSB7e2NvbnRyb2xsZXI/OiA/LCBuZXN0ZWRBdHRyaWJ1dGVzPzogUmVjb3JkPHN0cmluZywgPz4gfCBudWxsfX0gW29wdGlvbnNdIC0gU2F2ZSBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdD59IC0gQ3JlYXRlZCBtb2RlbC5cbiAgICovXG4gIGFzeW5jIGNyZWF0ZShhdHRyaWJ1dGVzLCBvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBwZXJtaXQgPSBwYXJzZVBlcm1pdHRlZFBhcmFtcyh0aGlzLnBlcm1pdHRlZFBhcmFtcyh7YWN0aW9uOiBcImNyZWF0ZVwiLCBhYmlsaXR5OiB0aGlzLmFiaWxpdHksIGxvY2FsczogdGhpcy5sb2NhbHMsIHBhcmFtczogYXR0cmlidXRlc30pKVxuICAgIGNvbnN0IGZpbHRlcmVkID0gZmlsdGVyV3JpdGFibGVGcm9udGVuZE1vZGVsQXR0cmlidXRlcyh0aGlzLm1vZGVsQ2xhc3MoKS5wcm90b3R5cGUsIGF0dHJpYnV0ZXMsIHRoaXMsIHBlcm1pdC5hdHRyaWJ1dGVzKVxuICAgIGNvbnN0IE1vZGVsQ2xhc3MgPSB0aGlzLm1vZGVsQ2xhc3MoKVxuICAgIGNvbnN0IG1vZGVsID0gbmV3IE1vZGVsQ2xhc3MoKVxuXG4gICAgYXdhaXQgTW9kZWxDbGFzcy50cmFuc2FjdGlvbihhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0aGlzLl9hc3NpZ25XaXRoVmlydHVhbFNldHRlcnMobW9kZWwsIGZpbHRlcmVkKVxuICAgICAgYXdhaXQgbW9kZWwuc2F2ZSgpXG5cbiAgICAgIGlmIChvcHRpb25zLm5lc3RlZEF0dHJpYnV0ZXMpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5fYXBwbHlOZXN0ZWRBdHRyaWJ1dGVzKG1vZGVsLCBvcHRpb25zLm5lc3RlZEF0dHJpYnV0ZXMsIG9wdGlvbnMuY29udHJvbGxlciB8fCBudWxsLCBwZXJtaXQpXG4gICAgICB9XG4gICAgfSlcblxuICAgIGF3YWl0IHRoaXMuX3ByZWxvYWROZXN0ZWRXcml0YWJsZVJlbGF0aW9uc2hpcHMobW9kZWwsIHBlcm1pdClcblxuICAgIHJldHVybiBtb2RlbFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFuZGxlIHVuYXV0aG9yaXplZCBjcmVhdGVkIG1vZGVsLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbCAtIENyZWF0ZWQgbW9kZWwuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIENsZWFudXAgYWZ0ZXIgZmFpbGVkIGF1dGhvcml6YXRpb24uXG4gICAqL1xuICBhc3luYyBoYW5kbGVVbmF1dGhvcml6ZWRDcmVhdGVkTW9kZWwobW9kZWwpIHtcbiAgICBhd2FpdCBtb2RlbC5kZXN0cm95KClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHVwZGF0ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWwgLSBFeGlzdGluZyBtb2RlbC5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gYXR0cmlidXRlcyAtIFVwZGF0ZSBhdHRyaWJ1dGVzLlxuICAgKiBAcGFyYW0ge3tjb250cm9sbGVyPzogPywgbmVzdGVkQXR0cmlidXRlcz86IFJlY29yZDxzdHJpbmcsID8+IHwgbnVsbH19IFtvcHRpb25zXSAtIFNhdmUgb3B0aW9ucy5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHQ+fSAtIFVwZGF0ZWQgbW9kZWwuXG4gICAqL1xuICBhc3luYyB1cGRhdGUobW9kZWwsIGF0dHJpYnV0ZXMsIG9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IHBlcm1pdCA9IHBhcnNlUGVybWl0dGVkUGFyYW1zKHRoaXMucGVybWl0dGVkUGFyYW1zKHthY3Rpb246IFwidXBkYXRlXCIsIGFiaWxpdHk6IHRoaXMuYWJpbGl0eSwgbG9jYWxzOiB0aGlzLmxvY2FscywgcGFyYW1zOiBhdHRyaWJ1dGVzfSkpXG4gICAgY29uc3QgZmlsdGVyZWQgPSBmaWx0ZXJXcml0YWJsZUZyb250ZW5kTW9kZWxBdHRyaWJ1dGVzKG1vZGVsLCBhdHRyaWJ1dGVzLCB0aGlzLCBwZXJtaXQuYXR0cmlidXRlcylcbiAgICBjb25zdCBNb2RlbENsYXNzID0gdGhpcy5tb2RlbENsYXNzKClcblxuICAgIGF3YWl0IE1vZGVsQ2xhc3MudHJhbnNhY3Rpb24oYXN5bmMgKCkgPT4ge1xuICAgICAgYXdhaXQgdGhpcy5fYXNzaWduV2l0aFZpcnR1YWxTZXR0ZXJzKG1vZGVsLCBmaWx0ZXJlZClcbiAgICAgIGF3YWl0IG1vZGVsLnNhdmUoKVxuXG4gICAgICBpZiAob3B0aW9ucy5uZXN0ZWRBdHRyaWJ1dGVzKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuX2FwcGx5TmVzdGVkQXR0cmlidXRlcyhtb2RlbCwgb3B0aW9ucy5uZXN0ZWRBdHRyaWJ1dGVzLCBvcHRpb25zLmNvbnRyb2xsZXIgfHwgbnVsbCwgcGVybWl0KVxuICAgICAgfVxuICAgIH0pXG5cbiAgICBhd2FpdCB0aGlzLl9wcmVsb2FkTmVzdGVkV3JpdGFibGVSZWxhdGlvbnNoaXBzKG1vZGVsLCBwZXJtaXQpXG5cbiAgICByZXR1cm4gbW9kZWxcbiAgfVxuXG4gIC8qKlxuICAgKiBBc3NpZ25zIGF0dHJpYnV0ZXMgdG8gYSBtb2RlbCwgdXNpbmcgdmlydHVhbCBzZXR0ZXJzIG9uIHRoZSByZXNvdXJjZSB3aGVuIGF2YWlsYWJsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWwgLSBNb2RlbCBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gYXR0cmlidXRlcyAtIEF0dHJpYnV0ZXMgdG8gYXNzaWduLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIF9hc3NpZ25XaXRoVmlydHVhbFNldHRlcnMobW9kZWwsIGF0dHJpYnV0ZXMpIHtcbiAgICAvKipcbiAgICAgKiBEaXJlY3QgYXR0cmlidXRlcy5cbiAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi9cbiAgICBjb25zdCBkaXJlY3RBdHRyaWJ1dGVzID0ge31cbiAgICBjb25zdCB0cmFuc2xhdGVkU2V0ID0gbmV3IFNldCgvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7dHlwZW9mIEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2V9ICovICh0aGlzLmNvbnN0cnVjdG9yKS50cmFuc2xhdGVkQXR0cmlidXRlcyB8fCBbXSlcblxuICAgIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhhdHRyaWJ1dGVzKSkge1xuICAgICAgY29uc3QgcmVzb3VyY2VTZXR0ZXJOYW1lID0gYHNldCR7aW5mbGVjdGlvbi5jYW1lbGl6ZShuYW1lKX1BdHRyaWJ1dGVgXG5cbiAgICAgIGlmICh0eXBlb2YgLyoqXG4gICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovICgvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKHRoaXMpKVtyZXNvdXJjZVNldHRlck5hbWVdID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgYXdhaXQgLyoqXG4gICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovICgvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKHRoaXMpKVtyZXNvdXJjZVNldHRlck5hbWVdKG1vZGVsLCB2YWx1ZSlcbiAgICAgIH0gZWxzZSBpZiAodHJhbnNsYXRlZFNldC5oYXMobmFtZSkpIHtcbiAgICAgICAgYXdhaXQgdGhpcy5fc2V0VHJhbnNsYXRlZEF0dHJpYnV0ZU9uTW9kZWwobW9kZWwsIG5hbWUsIHZhbHVlKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGlyZWN0QXR0cmlidXRlc1tuYW1lXSA9IHZhbHVlXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKE9iamVjdC5rZXlzKGRpcmVjdEF0dHJpYnV0ZXMpLmxlbmd0aCA+IDApIHtcbiAgICAgIG1vZGVsLmFzc2lnbihkaXJlY3RBdHRyaWJ1dGVzKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGEgdHJhbnNsYXRlZCBhdHRyaWJ1dGUgb24gYSBtb2RlbCB2aWEgdGhlIHRyYW5zbGF0aW9ucyByZWxhdGlvbnNoaXAuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IG1vZGVsIC0gTW9kZWwgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gQXR0cmlidXRlIG5hbWUuXG4gICAqIEBwYXJhbSB7P30gdmFsdWUgLSBBdHRyaWJ1dGUgdmFsdWUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgX3NldFRyYW5zbGF0ZWRBdHRyaWJ1dGVPbk1vZGVsKG1vZGVsLCBuYW1lLCB2YWx1ZSkge1xuICAgIGNvbnN0IGxvY2FsZSA9IHRoaXMuY29udGV4dD8uY29uZmlndXJhdGlvbj8uZ2V0TG9jYWxlPy4oKSB8fCBcImVuXCJcbiAgICBjb25zdCBpbnN0YW5jZVJlbGF0aW9uc2hpcCA9IG1vZGVsLmdldFJlbGF0aW9uc2hpcEJ5TmFtZShcInRyYW5zbGF0aW9uc1wiKVxuXG4gICAgLyoqXG4gICAgICogRGVmaW5lcyB0cmFuc2xhdGlvbi5cbiAgICAgIEB0eXBlIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gKi9cbiAgICBsZXQgdHJhbnNsYXRpb25cblxuICAgIGlmIChtb2RlbC5pc05ld1JlY29yZCgpKSB7XG4gICAgICBjb25zdCBsb2FkZWQgPSBpbnN0YW5jZVJlbGF0aW9uc2hpcC5sb2FkZWQoKVxuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShsb2FkZWQpKSB7XG4gICAgICAgIHRyYW5zbGF0aW9uID0gbG9hZGVkLmZpbmQoKC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyB0KSA9PiB0LmxvY2FsZSgpID09PSBsb2NhbGUpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghaW5zdGFuY2VSZWxhdGlvbnNoaXAuZ2V0UHJlbG9hZGVkKCkpIHtcbiAgICAgICAgYXdhaXQgbW9kZWwubG9hZFJlbGF0aW9uc2hpcChcInRyYW5zbGF0aW9uc1wiKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBsb2FkZWQgPSBpbnN0YW5jZVJlbGF0aW9uc2hpcC5sb2FkZWQoKVxuXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShsb2FkZWQpKSB7XG4gICAgICAgIHRyYW5zbGF0aW9uID0gbG9hZGVkLmZpbmQoKC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyB0KSA9PiB0LmxvY2FsZSgpID09PSBsb2NhbGUpXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCF0cmFuc2xhdGlvbikge1xuICAgICAgdHJhbnNsYXRpb24gPSBpbnN0YW5jZVJlbGF0aW9uc2hpcC5idWlsZCh7bG9jYWxlfSlcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBc3NpZ25tZW50cy5cbiAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi9cbiAgICBjb25zdCBhc3NpZ25tZW50cyA9IHt9XG5cbiAgICBhc3NpZ25tZW50c1tuYW1lXSA9IHZhbHVlXG4gICAgdHJhbnNsYXRpb24uYXNzaWduKGFzc2lnbm1lbnRzKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZGVzdHJveS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gbW9kZWwgLSBFeGlzdGluZyBtb2RlbC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgYXN5bmMgZGVzdHJveShtb2RlbCkge1xuICAgIGF3YWl0IG1vZGVsLmRlc3Ryb3koKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc2VyaWFsaXplLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbCAtIE1vZGVsIHRvIHNlcmlhbGl6ZS5cbiAgICogQHBhcmFtIHtcImluZGV4XCIgfCBcImZpbmRcIiB8IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwifSBbYWN0aW9uXSAtIEFjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgPz4+fSAtIFNlcmlhbGl6ZWQgbW9kZWwgcGF5bG9hZC5cbiAgICovXG4gIGFzeW5jIHNlcmlhbGl6ZShtb2RlbCwgYWN0aW9uKSB7XG4gICAgdm9pZCBhY3Rpb25cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnR5cGVkQ29udHJvbGxlckluc3RhbmNlKCkuc2VyaWFsaXplRnJvbnRlbmRNb2RlbChtb2RlbClcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBsaWVzIGEgYG5lc3RlZEF0dHJpYnV0ZXNgIHBheWxvYWQgdG8gYSBmcmVzaGx5LXNhdmVkIHBhcmVudCBtb2RlbCxcbiAgICogY2FzY2FkaW5nIGNyZWF0ZS91cGRhdGUvZGVzdHJveSB3cml0ZXMgYWNyb3NzIHRoZSBkZWNsYXJlZCByZWxhdGlvbnNoaXBzLlxuICAgKlxuICAgKiBFYWNoIGNoaWxkIGlzIGF1dGhvcml6ZWQgYWdhaW5zdCBpdHMgb3duIHJlc291cmNlJ3MgYWJpbGl0aWVzIChuZXZlciB0aGVcbiAgICogcGFyZW50J3MpLiBEZXN0cm95cyBydW4gYmVmb3JlIHVwZGF0ZXMsIHVwZGF0ZXMgYmVmb3JlIGNyZWF0ZXMsIHRvIGF2b2lkXG4gICAqIHVuaXF1ZS1jb25zdHJhaW50IGNvbmZsaWN0cyB3aGVuIHJlcGxhY2luZyBhIGNoaWxkIGF0IHRoZSBzYW1lIG5hdHVyYWwga2V5LlxuICAgKlxuICAgKiBBdHRyaWJ1dGUgZmlsdGVyaW5nIGZvciBuZXN0ZWQgY2hpbGRyZW4gdXNlcyB0aGUgcGFyZW50IHJlc291cmNlJ3NcbiAgICogcGVybWl0IHNwZWMgZm9yIHRoYXQgcmVsYXRpb25zaGlwIOKAlCBhcGlfbWFrZXItc3R5bGUuIFBvbGljeSBvcHRpb25zXG4gICAqIChhbGxvd0Rlc3Ryb3ksIGxpbWl0LCByZWplY3RJZikgY29tZSBmcm9tIHRoZSBNT0RFTCdzXG4gICAqIGBhY2NlcHRlZE5lc3RlZEF0dHJpYnV0ZXNGb3IobmFtZSlgIGRlY2xhcmF0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBwYXJlbnQgLSBQYXJlbnQgbW9kZWwgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz59IG5lc3RlZEF0dHJpYnV0ZXMgLSBOZXN0ZWQtYXR0cmlidXRlIHBheWxvYWQga2V5ZWQgYnkgcmVsYXRpb25zaGlwIG5hbWUuXG4gICAqIEBwYXJhbSB7P30gY29udHJvbGxlciAtIENvbnRyb2xsZXIgaW5zdGFuY2UgZm9yIHJlc291cmNlIHJlc29sdXRpb24gYW5kIGF1dGhvcml6YXRpb24uXG4gICAqIEBwYXJhbSB7e2F0dHJpYnV0ZXM6IHN0cmluZ1tdLCBuZXN0ZWQ6IFJlY29yZDxzdHJpbmcsID8+fSB8IG51bGx9IFtwYXJlbnRQZXJtaXRdIC0gUGFyc2VkIHBhcmVudCBwZXJtaXQgc3BlYy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBfYXBwbHlOZXN0ZWRBdHRyaWJ1dGVzKHBhcmVudCwgbmVzdGVkQXR0cmlidXRlcywgY29udHJvbGxlciwgcGFyZW50UGVybWl0ID0gbnVsbCkge1xuICAgIGNvbnN0IHJlc29sdmVkUGFyZW50ID0gcGFyZW50UGVybWl0XG4gICAgICB8fCBwYXJzZVBlcm1pdHRlZFBhcmFtcyh0aGlzLnBlcm1pdHRlZFBhcmFtcyh7YWN0aW9uOiBcInVwZGF0ZVwiLCBhYmlsaXR5OiB0aGlzLmFiaWxpdHksIGxvY2FsczogdGhpcy5sb2NhbHMsIHBhcmFtczoge319KSlcblxuICAgIGZvciAoY29uc3QgcmVsYXRpb25zaGlwTmFtZSBvZiBPYmplY3Qua2V5cyhuZXN0ZWRBdHRyaWJ1dGVzKSkge1xuICAgICAgY29uc3QgY2hpbGRQZXJtaXQgPSByZXNvbHZlZFBhcmVudC5uZXN0ZWRbcmVsYXRpb25zaGlwTmFtZV1cblxuICAgICAgaWYgKCFjaGlsZFBlcm1pdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5lc3RlZCBhdHRyaWJ1dGVzIGZvciAnJHtyZWxhdGlvbnNoaXBOYW1lfScgYXJlIG5vdCBwZXJtaXR0ZWQgYnkgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9LnBlcm1pdHRlZFBhcmFtcygpLiBJbmNsdWRlIHske3JlbGF0aW9uc2hpcE5hbWV9QXR0cmlidXRlczogWy4uLl19IGluIHRoZSByZXR1cm5lZCBwZXJtaXQuYClcbiAgICAgIH1cblxuICAgICAgY29uc3QgZW50cmllcyA9IG5lc3RlZEF0dHJpYnV0ZXNbcmVsYXRpb25zaGlwTmFtZV1cblxuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGVudHJpZXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgYXJyYXkgZm9yIG5lc3RlZEF0dHJpYnV0ZXNbJyR7cmVsYXRpb25zaGlwTmFtZX0nXSBidXQgZ290OiAke3R5cGVvZiBlbnRyaWVzfWApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhcmVudE1vZGVsQ2xhc3MgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKHBhcmVudC5nZXRNb2RlbENsYXNzKCkpXG4gICAgICBjb25zdCBtb2RlbEFjY2VwdGFuY2UgPSBwYXJlbnRNb2RlbENsYXNzLmFjY2VwdGVkTmVzdGVkQXR0cmlidXRlc0Zvcj8uKHJlbGF0aW9uc2hpcE5hbWUpXG5cbiAgICAgIGlmICghbW9kZWxBY2NlcHRhbmNlKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTW9kZWwgJHtwYXJlbnRNb2RlbENsYXNzLm5hbWV9IGRvZXMgbm90IGFjY2VwdCBuZXN0ZWQgYXR0cmlidXRlcyBmb3IgJyR7cmVsYXRpb25zaGlwTmFtZX0nLiBEZWNsYXJlIGl0IHZpYSAke3BhcmVudE1vZGVsQ2xhc3MubmFtZX0uYWNjZXB0c05lc3RlZEF0dHJpYnV0ZXNGb3IoJyR7cmVsYXRpb25zaGlwTmFtZX0nKS5gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCBkZXN0cm95UGVybWl0dGVkID0gY2hpbGRQZXJtaXQuYXR0cmlidXRlcy5pbmNsdWRlcyhcIl9kZXN0cm95XCIpXG5cbiAgICAgIGlmIChkZXN0cm95UGVybWl0dGVkICYmICFtb2RlbEFjY2VwdGFuY2UuYWxsb3dEZXN0cm95KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUmVzb3VyY2UgcGVybWl0cyBfZGVzdHJveSBvbiBuZXN0ZWRBdHRyaWJ1dGVzWycke3JlbGF0aW9uc2hpcE5hbWV9J10gYnV0IHRoZSBtb2RlbCAke3BhcmVudE1vZGVsQ2xhc3MubmFtZX0gZG9lcyBub3QgYWxsb3cgZGVzdHJveSBmb3IgdGhhdCByZWxhdGlvbnNoaXAuIFNldCB7YWxsb3dEZXN0cm95OiB0cnVlfSBvbiAke3BhcmVudE1vZGVsQ2xhc3MubmFtZX0uYWNjZXB0c05lc3RlZEF0dHJpYnV0ZXNGb3IoJyR7cmVsYXRpb25zaGlwTmFtZX0nLCAuLi4pLmApXG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgbW9kZWxBY2NlcHRhbmNlLmxpbWl0ID09PSBcIm51bWJlclwiICYmIGVudHJpZXMubGVuZ3RoID4gbW9kZWxBY2NlcHRhbmNlLmxpbWl0KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgbmVzdGVkQXR0cmlidXRlc1snJHtyZWxhdGlvbnNoaXBOYW1lfSddIGV4Y2VlZHMgbW9kZWwtZGVjbGFyZWQgbGltaXQgb2YgJHttb2RlbEFjY2VwdGFuY2UubGltaXR9LmApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhcmVudFJlbGF0aW9uc2hpcCA9IHBhcmVudC5nZXRSZWxhdGlvbnNoaXBCeU5hbWUocmVsYXRpb25zaGlwTmFtZSlcbiAgICAgIGNvbnN0IHJlbGF0aW9uc2hpcERlZmluaXRpb25zID0gcGFyZW50TW9kZWxDbGFzcy5yZWxhdGlvbnNoaXBzPy4oKSB8fCB7fVxuICAgICAgY29uc3QgZGVmaW5pdGlvbiA9IHJlbGF0aW9uc2hpcERlZmluaXRpb25zW3JlbGF0aW9uc2hpcE5hbWVdXG5cbiAgICAgIGlmICghZGVmaW5pdGlvbiB8fCBkZWZpbml0aW9uLnR5cGUgIT09IFwiaGFzTWFueVwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTmVzdGVkIGF0dHJpYnV0ZXMgZm9yICcke3JlbGF0aW9uc2hpcE5hbWV9JyByZXF1aXJlIGEgaGFzTWFueSByZWxhdGlvbnNoaXAuIHYxIGRvZXMgbm90IHN1cHBvcnQgJyR7ZGVmaW5pdGlvbj8udHlwZX0nLmApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRhcmdldE1vZGVsQ2xhc3MgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKHBhcmVudC5nZXRNb2RlbENsYXNzKCkpLnJlbGF0aW9uc2hpcE1vZGVsQ2xhc3M/LihyZWxhdGlvbnNoaXBOYW1lKVxuXG4gICAgICBpZiAoIXRhcmdldE1vZGVsQ2xhc3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyB0YXJnZXQgbW9kZWwgY2xhc3MgcmVzb2x2ZWQgZm9yIHJlbGF0aW9uc2hpcCAnJHtyZWxhdGlvbnNoaXBOYW1lfScgb24gJHtwYXJlbnQuZ2V0TW9kZWxDbGFzcygpLm5hbWV9LmApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNoaWxkUmVzb3VyY2VDb25maWcgPSBjb250cm9sbGVyPy5mcm9udGVuZE1vZGVsUmVzb3VyY2VDb25maWd1cmF0aW9uRm9yTW9kZWxDbGFzcz8uKHRhcmdldE1vZGVsQ2xhc3MpXG5cbiAgICAgIGlmICghY2hpbGRSZXNvdXJjZUNvbmZpZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIGZyb250ZW5kLW1vZGVsIHJlc291cmNlIHJlZ2lzdGVyZWQgZm9yIGNoaWxkIG1vZGVsICcke3RhcmdldE1vZGVsQ2xhc3MuZ2V0TW9kZWxOYW1lPy4oKSB8fCB0YXJnZXRNb2RlbENsYXNzLm5hbWV9JyB1bmRlciByZWxhdGlvbnNoaXAgJyR7cmVsYXRpb25zaGlwTmFtZX0nLmApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNoaWxkUmVzb3VyY2UgPSBuZXcgY2hpbGRSZXNvdXJjZUNvbmZpZy5yZXNvdXJjZUNsYXNzKHtcbiAgICAgICAgYWJpbGl0eTogdGhpcy5hYmlsaXR5LFxuICAgICAgICBjb250cm9sbGVyLFxuICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQgfHwge30sXG4gICAgICAgIGxvY2FsczogdGhpcy5sb2NhbHMgfHwge30sXG4gICAgICAgIG1vZGVsQ2xhc3M6IHRhcmdldE1vZGVsQ2xhc3MsXG4gICAgICAgIG1vZGVsTmFtZTogY2hpbGRSZXNvdXJjZUNvbmZpZy5tb2RlbE5hbWUsXG4gICAgICAgIHBhcmFtczogY29udHJvbGxlcj8uZnJvbnRlbmRNb2RlbFBhcmFtcz8uKCkgfHwge30sXG4gICAgICAgIHJlc291cmNlQ29uZmlndXJhdGlvbjogY2hpbGRSZXNvdXJjZUNvbmZpZy5yZXNvdXJjZUNvbmZpZ3VyYXRpb25cbiAgICAgIH0pXG5cbiAgICAgIGNvbnN0IGZvcmVpZ25LZXkgPSBkZWZpbml0aW9uLmZvcmVpZ25LZXkgfHwgdGhpcy5faW5mZXJGb3JlaWduS2V5KHBhcmVudCwgZGVmaW5pdGlvbilcbiAgICAgIGNvbnN0IGFiaWxpdHkgPSBjb250cm9sbGVyPy5jdXJyZW50QWJpbGl0eT8uKClcblxuICAgICAgY29uc3QgZGVzdHJveUVudHJpZXMgPSBbXVxuICAgICAgY29uc3QgdXBkYXRlRW50cmllcyA9IFtdXG4gICAgICBjb25zdCBjcmVhdGVFbnRyaWVzID0gW11cblxuICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbW9kZWxBY2NlcHRhbmNlLnJlamVjdElmID09PSBcImZ1bmN0aW9uXCIgJiYgbW9kZWxBY2NlcHRhbmNlLnJlamVjdElmKGVudHJ5Py5hdHRyaWJ1dGVzIHx8IHt9KSkgY29udGludWVcblxuICAgICAgICBpZiAoZW50cnk/Ll9kZXN0cm95KSB7XG4gICAgICAgICAgaWYgKCFkZXN0cm95UGVybWl0dGVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYG5lc3RlZEF0dHJpYnV0ZXNbJyR7cmVsYXRpb25zaGlwTmFtZX0nXSBlbnRyeSByZXF1ZXN0ZWQgX2Rlc3Ryb3kgYnV0IFwiX2Rlc3Ryb3lcIiBpcyBub3QgaW4gdGhlIHBlcm1pdCBmb3IgdGhpcyByZWxhdGlvbnNoaXAuYClcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFlbnRyeS5pZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBuZXN0ZWRBdHRyaWJ1dGVzWycke3JlbGF0aW9uc2hpcE5hbWV9J10gX2Rlc3Ryb3kgZW50cnkgaXMgbWlzc2luZyBhbiBpZC5gKVxuICAgICAgICAgIH1cbiAgICAgICAgICBkZXN0cm95RW50cmllcy5wdXNoKGVudHJ5KVxuICAgICAgICB9IGVsc2UgaWYgKGVudHJ5Py5pZCkge1xuICAgICAgICAgIHVwZGF0ZUVudHJpZXMucHVzaChlbnRyeSlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjcmVhdGVFbnRyaWVzLnB1c2goZW50cnkpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVGhlIHBlcm1pdCdzIGF0dHJpYnV0ZSBsaXN0IGdvdmVybnMgd2hhdCBjaGlsZCBmaWVsZHMgY2FuIGJlIHdyaXR0ZW4uXG4gICAgICAvLyBFeGNsdWRlIGBfZGVzdHJveWAgZnJvbSB0aGUgd3JpdGFibGUgc2V0IHNpbmNlIGl0J3MgYSBjb250cm9sIGZsYWcsXG4gICAgICAvLyBub3QgYW4gYXR0cmlidXRlIG9uIHRoZSByZWNvcmQuXG4gICAgICBjb25zdCBjaGlsZFdyaXRhYmxlQXR0cmlidXRlcyA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge3N0cmluZ1tdfSAqLyAoY2hpbGRQZXJtaXQuYXR0cmlidXRlcykuZmlsdGVyKChuYW1lKSA9PiBuYW1lICE9PSBcIl9kZXN0cm95XCIpXG5cbiAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgZGVzdHJveUVudHJpZXMpIHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCB0aGlzLl9maW5kU2NvcGVkQ2hpbGQoe1xuICAgICAgICAgIGFiaWxpdHksXG4gICAgICAgICAgYWN0aW9uOiBcImRlc3Ryb3lcIixcbiAgICAgICAgICBjaGlsZFJlc291cmNlQ29uZmlndXJhdGlvbjogY2hpbGRSZXNvdXJjZUNvbmZpZy5yZXNvdXJjZUNvbmZpZ3VyYXRpb24sXG4gICAgICAgICAgZm9yZWlnbktleSxcbiAgICAgICAgICBpZDogZW50cnkuaWQsXG4gICAgICAgICAgcGFyZW50LFxuICAgICAgICAgIHJlbGF0aW9uc2hpcE5hbWUsXG4gICAgICAgICAgdGFyZ2V0TW9kZWxDbGFzc1xuICAgICAgICB9KVxuXG4gICAgICAgIGF3YWl0IGNoaWxkUmVzb3VyY2UuZGVzdHJveShleGlzdGluZylcbiAgICAgIH1cblxuICAgICAgZm9yIChjb25zdCBlbnRyeSBvZiB1cGRhdGVFbnRyaWVzKSB7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgdGhpcy5fZmluZFNjb3BlZENoaWxkKHtcbiAgICAgICAgICBhYmlsaXR5LFxuICAgICAgICAgIGFjdGlvbjogXCJ1cGRhdGVcIixcbiAgICAgICAgICBjaGlsZFJlc291cmNlQ29uZmlndXJhdGlvbjogY2hpbGRSZXNvdXJjZUNvbmZpZy5yZXNvdXJjZUNvbmZpZ3VyYXRpb24sXG4gICAgICAgICAgZm9yZWlnbktleSxcbiAgICAgICAgICBpZDogZW50cnkuaWQsXG4gICAgICAgICAgcGFyZW50LFxuICAgICAgICAgIHJlbGF0aW9uc2hpcE5hbWUsXG4gICAgICAgICAgdGFyZ2V0TW9kZWxDbGFzc1xuICAgICAgICB9KVxuXG4gICAgICAgIGlmIChlbnRyeS5hdHRyaWJ1dGVzICYmIHR5cGVvZiBlbnRyeS5hdHRyaWJ1dGVzID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgY29uc3QgZmlsdGVyZWQgPSBmaWx0ZXJXcml0YWJsZUZyb250ZW5kTW9kZWxBdHRyaWJ1dGVzKGV4aXN0aW5nLCBlbnRyeS5hdHRyaWJ1dGVzLCBjaGlsZFJlc291cmNlLCBjaGlsZFdyaXRhYmxlQXR0cmlidXRlcylcbiAgICAgICAgICBhd2FpdCAvKipcbiAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKGNoaWxkUmVzb3VyY2UpLl9hc3NpZ25XaXRoVmlydHVhbFNldHRlcnMoZXhpc3RpbmcsIGZpbHRlcmVkKVxuICAgICAgICAgIGF3YWl0IGV4aXN0aW5nLnNhdmUoKVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVudHJ5Lm5lc3RlZEF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICBhd2FpdCAvKipcbiAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKGNoaWxkUmVzb3VyY2UpLl9hcHBseU5lc3RlZEF0dHJpYnV0ZXMoZXhpc3RpbmcsIGVudHJ5Lm5lc3RlZEF0dHJpYnV0ZXMsIGNvbnRyb2xsZXIsIGNoaWxkUGVybWl0KVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgY3JlYXRlRW50cmllcykge1xuICAgICAgICBjb25zdCBjaGlsZEF0dHJpYnV0ZXMgPSBlbnRyeT8uYXR0cmlidXRlcyAmJiB0eXBlb2YgZW50cnkuYXR0cmlidXRlcyA9PT0gXCJvYmplY3RcIiA/IGVudHJ5LmF0dHJpYnV0ZXMgOiB7fVxuXG4gICAgICAgIGNvbnN0IGNoaWxkID0gcGFyZW50UmVsYXRpb25zaGlwLmJ1aWxkKHsuLi5jaGlsZEF0dHJpYnV0ZXMsIFtmb3JlaWduS2V5XTogcGFyZW50LmlkKCl9KVxuXG4gICAgICAgIGNvbnN0IGZpbHRlcmVkID0gZmlsdGVyV3JpdGFibGVGcm9udGVuZE1vZGVsQXR0cmlidXRlcyhjaGlsZCwgY2hpbGRBdHRyaWJ1dGVzLCBjaGlsZFJlc291cmNlLCBjaGlsZFdyaXRhYmxlQXR0cmlidXRlcylcblxuICAgICAgICBhd2FpdCAvKipcbiAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgIEB0eXBlIHs/fSAqLyAoY2hpbGRSZXNvdXJjZSkuX2Fzc2lnbldpdGhWaXJ0dWFsU2V0dGVycyhjaGlsZCwgZmlsdGVyZWQpXG4gICAgICAgIGF3YWl0IGNoaWxkLnNhdmUoKVxuXG4gICAgICAgIGF3YWl0IHRoaXMuX2F1dGhvcml6ZUNyZWF0ZWRDaGlsZCh7XG4gICAgICAgICAgYWJpbGl0eSxcbiAgICAgICAgICBjaGlsZCxcbiAgICAgICAgICBjaGlsZFJlc291cmNlQ29uZmlndXJhdGlvbjogY2hpbGRSZXNvdXJjZUNvbmZpZy5yZXNvdXJjZUNvbmZpZ3VyYXRpb24sXG4gICAgICAgICAgcmVsYXRpb25zaGlwTmFtZSxcbiAgICAgICAgICB0YXJnZXRNb2RlbENsYXNzXG4gICAgICAgIH0pXG5cbiAgICAgICAgaWYgKGVudHJ5Lm5lc3RlZEF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICBhd2FpdCAvKipcbiAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKGNoaWxkUmVzb3VyY2UpLl9hcHBseU5lc3RlZEF0dHJpYnV0ZXMoY2hpbGQsIGVudHJ5Lm5lc3RlZEF0dHJpYnV0ZXMsIGNvbnRyb2xsZXIsIGNoaWxkUGVybWl0KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIHRoZSBhYmlsaXR5IGFjdGlvbiBmb3IgYSBjaGlsZCByZXNvdXJjZSB1c2luZyB0aGUgY2hpbGQncyBvd25cbiAgICogYGFiaWxpdGllc2AgbWFwcGluZyDigJQgbmV2ZXIgdGhlIHBhcmVudCBjb250cm9sbGVyJ3MuIFRoaXMgcHJlc2VydmVzXG4gICAqIGN1c3RvbSBtYXBwaW5ncyBsaWtlIGB7dXBkYXRlOiBcIm1hbmFnZVwifWAgYW5kIGNhdGNoZXMgdW5tYXBwZWQgYWN0aW9uc1xuICAgKiBpbnN0ZWFkIG9mIHNpbGVudGx5IGRlZmF1bHRpbmcgdG8gdGhlIHJhdyBhY3Rpb24gbmFtZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb259IGNoaWxkUmVzb3VyY2VDb25maWd1cmF0aW9uIC0gQ2hpbGQgcmVzb3VyY2UgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIHtcImNyZWF0ZVwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwifSBhY3Rpb24gLSBGcm9udGVuZCBhY3Rpb24uXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gQWJpbGl0eSBhY3Rpb24gZm9yIHRoZSBjaGlsZCByZXNvdXJjZS5cbiAgICovXG4gIF9yZXNvbHZlQ2hpbGRBYmlsaXR5QWN0aW9uKGNoaWxkUmVzb3VyY2VDb25maWd1cmF0aW9uLCBhY3Rpb24pIHtcbiAgICBjb25zdCBhYmlsaXRpZXMgPSBjaGlsZFJlc291cmNlQ29uZmlndXJhdGlvbj8uYWJpbGl0aWVzXG5cbiAgICBpZiAoIWFiaWxpdGllcyB8fCB0eXBlb2YgYWJpbGl0aWVzICE9PSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoYWJpbGl0aWVzKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBOZXN0ZWQgY2hpbGQgcmVzb3VyY2UgbXVzdCBkZWZpbmUgYW4gJ2FiaWxpdGllcycgb2JqZWN0IHRvIGF1dGhvcml6ZSBuZXN0ZWQgJHthY3Rpb259LmApXG4gICAgfVxuXG4gICAgY29uc3QgYWJpbGl0eUFjdGlvbiA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsIHN0cmluZz59ICovIChhYmlsaXRpZXMpW2FjdGlvbl1cblxuICAgIGlmICh0eXBlb2YgYWJpbGl0eUFjdGlvbiAhPT0gXCJzdHJpbmdcIiB8fCBhYmlsaXR5QWN0aW9uLmxlbmd0aCA8IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTmVzdGVkIGNoaWxkIHJlc291cmNlIG11c3QgZGVmaW5lIGFiaWxpdGllcy4ke2FjdGlvbn0uYClcbiAgICB9XG5cbiAgICByZXR1cm4gYWJpbGl0eUFjdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIEZpbmRzIGFuIGV4aXN0aW5nIGNoaWxkIGZvciBhIG5lc3RlZCB1cGRhdGUvZGVzdHJveSwgc2NvcGVkIHRvIHRoZVxuICAgKiBjaGlsZCdzIG93biBtb2RlbCBjbGFzcywgdGhlIHBhcmVudCdzIGZvcmVpZ24ga2V5LCBBTkQgdGhlIGNoaWxkXG4gICAqIHJlc291cmNlJ3MgYWJpbGl0eSBtYXBwaW5nIGZvciB0aGUgcmVxdWVzdGVkIGFjdGlvbi4gVGhyb3dzIHdoZW4gdGhlXG4gICAqIGNoaWxkIGRvZXMgbm90IGV4aXN0LCBkb2VzIG5vdCBiZWxvbmcgdG8gdGhlIGN1cnJlbnQgcGFyZW50LCBvciBpc1xuICAgKiBub3QgYXV0aG9yaXplZCDigJQgYWxsIG9mIHdoaWNoIG11c3Qgcm9sbCB0aGUgdHJhbnNhY3Rpb24gYmFjay5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBBcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vYXV0aG9yaXphdGlvbi9hYmlsaXR5LmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IGFyZ3MuYWJpbGl0eSAtIEN1cnJlbnQgYWJpbGl0eS5cbiAgICogQHBhcmFtIHtcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCJ9IGFyZ3MuYWN0aW9uIC0gRnJvbnRlbmQgYWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRnJvbnRlbmRNb2RlbFJlc291cmNlQ29uZmlndXJhdGlvbn0gYXJncy5jaGlsZFJlc291cmNlQ29uZmlndXJhdGlvbiAtIENoaWxkIHJlc291cmNlIGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmZvcmVpZ25LZXkgLSBGb3JlaWduLWtleSBhdHRyaWJ1dGUgb24gdGhlIGNoaWxkIHBvaW50aW5nIHRvIHRoZSBwYXJlbnQuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyfSBhcmdzLmlkIC0gQ2hpbGQgaWQgZnJvbSB0aGUgcGF5bG9hZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gYXJncy5wYXJlbnQgLSBQYXJlbnQgbW9kZWwgaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLnJlbGF0aW9uc2hpcE5hbWUgLSBQYXJlbnQncyByZWxhdGlvbnNoaXAgbmFtZSAoZm9yIGVycm9yIG1lc3NhZ2VzKS5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCIpLmRlZmF1bHR9IGFyZ3MudGFyZ2V0TW9kZWxDbGFzcyAtIENoaWxkIG1vZGVsIGNsYXNzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdD59IC0gQXV0aG9yaXplZCwgcGFyZW50LWxpbmtlZCBjaGlsZCBtb2RlbC5cbiAgICovXG4gIGFzeW5jIF9maW5kU2NvcGVkQ2hpbGQoe2FiaWxpdHksIGFjdGlvbiwgY2hpbGRSZXNvdXJjZUNvbmZpZ3VyYXRpb24sIGZvcmVpZ25LZXksIGlkLCBwYXJlbnQsIHJlbGF0aW9uc2hpcE5hbWUsIHRhcmdldE1vZGVsQ2xhc3N9KSB7XG4gICAgY29uc3QgcHJpbWFyeUtleSA9IHRhcmdldE1vZGVsQ2xhc3MucHJpbWFyeUtleSgpXG4gICAgY29uc3QgbG9va3VwID0ge1twcmltYXJ5S2V5XTogaWQsIFtmb3JlaWduS2V5XTogcGFyZW50LmlkKCl9XG4gICAgY29uc3QgcXVlcnkgPSBhYmlsaXR5XG4gICAgICA/IC8qKlxuICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgQHR5cGUgez99ICovICh0YXJnZXRNb2RlbENsYXNzKS5hY2Nlc3NpYmxlRm9yKHRoaXMuX3Jlc29sdmVDaGlsZEFiaWxpdHlBY3Rpb24oY2hpbGRSZXNvdXJjZUNvbmZpZ3VyYXRpb24sIGFjdGlvbiksIGFiaWxpdHkpXG4gICAgICA6IC8qKlxuICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgQHR5cGUgez99ICovICh0YXJnZXRNb2RlbENsYXNzKS53aGVyZSh7fSlcblxuICAgIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgcXVlcnkuZmluZEJ5KGxvb2t1cClcblxuICAgIGlmICghZXhpc3RpbmcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90ICR7YWN0aW9ufSBuZXN0ZWQgJHtyZWxhdGlvbnNoaXBOYW1lfVtpZD0ke2lkfV06IHJlY29yZCBub3QgZm91bmQsIGRvZXMgbm90IGJlbG9uZyB0byBwYXJlbnQgJHtwYXJlbnQuZ2V0TW9kZWxDbGFzcygpLm5hbWV9W2lkPSR7cGFyZW50LmlkKCl9XSwgb3IgaXMgbm90IGF1dGhvcml6ZWQuYClcbiAgICB9XG5cbiAgICByZXR1cm4gZXhpc3RpbmdcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZmllcyBhbiBhbHJlYWR5LXNhdmVkIG5lc3RlZCBjaGlsZCBpcyBhdXRob3JpemVkIHVuZGVyIHRoZSBjaGlsZFxuICAgKiByZXNvdXJjZSdzIG93biBgY3JlYXRlYCBhYmlsaXR5LiBSb2xscyBiYWNrIHZpYSB0aHJvd24gZXJyb3Igd2hlbiBub3RcbiAgICogYXV0aG9yaXplZCBzbyB0aGUgb3V0ZXIgdHJhbnNhY3Rpb24gZGVzdHJveXMgdGhlIGluc2VydC5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBBcmd1bWVudHMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vYXV0aG9yaXphdGlvbi9hYmlsaXR5LmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IGFyZ3MuYWJpbGl0eSAtIEN1cnJlbnQgYWJpbGl0eS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdH0gYXJncy5jaGlsZCAtIENoaWxkIG1vZGVsIGluc3RhbmNlIGp1c3QgY3JlYXRlZC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb259IGFyZ3MuY2hpbGRSZXNvdXJjZUNvbmZpZ3VyYXRpb24gLSBDaGlsZCByZXNvdXJjZSBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5yZWxhdGlvbnNoaXBOYW1lIC0gUGFyZW50J3MgcmVsYXRpb25zaGlwIG5hbWUgKGZvciBlcnJvciBtZXNzYWdlcykuXG4gICAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBhcmdzLnRhcmdldE1vZGVsQ2xhc3MgLSBDaGlsZCBtb2RlbCBjbGFzcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBfYXV0aG9yaXplQ3JlYXRlZENoaWxkKHthYmlsaXR5LCBjaGlsZCwgY2hpbGRSZXNvdXJjZUNvbmZpZ3VyYXRpb24sIHJlbGF0aW9uc2hpcE5hbWUsIHRhcmdldE1vZGVsQ2xhc3N9KSB7XG4gICAgaWYgKCFhYmlsaXR5KSByZXR1cm5cblxuICAgIGNvbnN0IGFiaWxpdHlBY3Rpb24gPSB0aGlzLl9yZXNvbHZlQ2hpbGRBYmlsaXR5QWN0aW9uKGNoaWxkUmVzb3VyY2VDb25maWd1cmF0aW9uLCBcImNyZWF0ZVwiKVxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSB0YXJnZXRNb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgIGNvbnN0IGF1dGhvcml6ZWRJZHMgPSBhd2FpdCAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHs/fSAqLyAodGFyZ2V0TW9kZWxDbGFzcylcbiAgICAgIC5hY2Nlc3NpYmxlRm9yKGFiaWxpdHlBY3Rpb24sIGFiaWxpdHkpXG4gICAgICAud2hlcmUoe1twcmltYXJ5S2V5XTogY2hpbGQucmVhZEF0dHJpYnV0ZShwcmltYXJ5S2V5KX0pXG4gICAgICAucGx1Y2socHJpbWFyeUtleSlcblxuICAgIGlmIChhdXRob3JpemVkSWRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBOZXN0ZWQgY3JlYXRlIG9uICR7cmVsYXRpb25zaGlwTmFtZX1bJHt0YXJnZXRNb2RlbENsYXNzLm5hbWV9XSBub3QgYXV0aG9yaXplZC5gKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCZXN0LWVmZm9ydCBmb3JlaWduLWtleSBpbmZlcmVuY2UgZm9yIHJlbGF0aW9uc2hpcHMgdGhhdCBkb24ndCBkZWNsYXJlIGl0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBwYXJlbnQgLSBQYXJlbnQgbW9kZWwuXG4gICAqIEBwYXJhbSB7e2ZvcmVpZ25LZXk/OiBzdHJpbmd9fSBkZWZpbml0aW9uIC0gUmVsYXRpb25zaGlwIGRlZmluaXRpb24uXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gRm9yZWlnbi1rZXkgYXR0cmlidXRlIG5hbWUuXG4gICAqL1xuICBfaW5mZXJGb3JlaWduS2V5KHBhcmVudCwgZGVmaW5pdGlvbikge1xuICAgIGlmIChkZWZpbml0aW9uLmZvcmVpZ25LZXkpIHJldHVybiBkZWZpbml0aW9uLmZvcmVpZ25LZXlcblxuICAgIGNvbnN0IHBhcmVudE1vZGVsTmFtZSA9IHBhcmVudC5nZXRNb2RlbENsYXNzKCkubmFtZSB8fCBcIlwiXG4gICAgY29uc3QgdW5kZXJzY29yZWQgPSBwYXJlbnRNb2RlbE5hbWUucmVwbGFjZSgvKFtBLVpdKS9nLCAobWF0Y2gsIGxldHRlciwgaW5kZXgpID0+IChpbmRleCA9PT0gMCA/IGxldHRlci50b0xvd2VyQ2FzZSgpIDogYF8ke2xldHRlci50b0xvd2VyQ2FzZSgpfWApKVxuXG4gICAgcmV0dXJuIGAke2luZmxlY3Rpb24uY2FtZWxpemUodW5kZXJzY29yZWQsIHRydWUpfUlkYFxuICB9XG5cbiAgLyoqXG4gICAqIEFmdGVyIG5lc3RlZCB3cml0ZXMsIHByZWxvYWQgZXZlcnkgcmVsYXRpb25zaGlwIGRlY2xhcmVkIGluIHRoZVxuICAgKiBwYXJlbnQncyBwZXJtaXQgc28gdGhlIHBvc3Qtc2F2ZSBzZXJpYWxpemUgc3RlcCBlbWl0cyB0aGVtIGFuZCB0aGVcbiAgICogY2xpZW50IGNhbiByZWNvbmNpbGUgaWRzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSBtb2RlbCAtIFNhdmVkIHBhcmVudCBtb2RlbC5cbiAgICogQHBhcmFtIHt7YXR0cmlidXRlczogc3RyaW5nW10sIG5lc3RlZDogUmVjb3JkPHN0cmluZywgPz59fSBwZXJtaXQgLSBQYXJzZWQgcGFyZW50IHBlcm1pdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBfcHJlbG9hZE5lc3RlZFdyaXRhYmxlUmVsYXRpb25zaGlwcyhtb2RlbCwgcGVybWl0KSB7XG4gICAgY29uc3QgcmVsYXRpb25zaGlwTmFtZXMgPSBPYmplY3Qua2V5cyhwZXJtaXQubmVzdGVkKVxuXG4gICAgaWYgKHJlbGF0aW9uc2hpcE5hbWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgICBmb3IgKGNvbnN0IHJlbGF0aW9uc2hpcE5hbWUgb2YgcmVsYXRpb25zaGlwTmFtZXMpIHtcbiAgICAgIGlmICh0eXBlb2YgLyoqXG4gICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKG1vZGVsKS5sb2FkUmVsYXRpb25zaGlwID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgYXdhaXQgLyoqXG4gICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKG1vZGVsKS5sb2FkUmVsYXRpb25zaGlwKHJlbGF0aW9uc2hpcE5hbWUpXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUGFyc2VzIHRoZSBSYWlscy9hcGlfbWFrZXItc3R5bGUgZmxhdCBwZXJtaXQgc3BlYyByZXR1cm5lZCBmcm9tXG4gKiBgcGVybWl0dGVkUGFyYW1zKGFyZylgIGludG8gYSBzdHJ1Y3R1cmVkIHNoYXBlIHVzZWQgaW50ZXJuYWxseSBieSB0aGVcbiAqIHdyaXRlIHBpcGVsaW5lLiBTdHJpbmdzIGJlY29tZSBhdHRyaWJ1dGUgcGVybWl0czsgb2JqZWN0cyB3aG9zZSBrZXlzXG4gKiBlbmQgaW4gYEF0dHJpYnV0ZXNgIGJlY29tZSBuZXN0ZWQgcGVybWl0cyAodGhlIGtleSBwcmVmaXggbmFtZXMgdGhlXG4gKiByZWxhdGlvbnNoaXApLlxuICpcbiAqICAgcGFyc2VQZXJtaXR0ZWRQYXJhbXMoW1wiZmlyc3ROYW1lXCIsIFwibGFzdE5hbWVcIixcbiAqICAgICB7dGFza3NBdHRyaWJ1dGVzOiBbXCJpZFwiLCBcIl9kZXN0cm95XCIsIFwibmFtZVwiXX1cbiAqICAgXSlcbiAqICAgLy8g4oaSIHtcbiAqICAgLy8gICBhdHRyaWJ1dGVzOiBbXCJmaXJzdE5hbWVcIiwgXCJsYXN0TmFtZVwiXSxcbiAqICAgLy8gICBuZXN0ZWQ6IHtcbiAqICAgLy8gICAgIHRhc2tzOiB7YXR0cmlidXRlczogW1wiaWRcIiwgXCJfZGVzdHJveVwiLCBcIm5hbWVcIl0sIG5lc3RlZDoge319XG4gKiAgIC8vICAgfVxuICogICAvLyB9XG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZyB8IFJlY29yZDxzdHJpbmcsID8+PiB8IHVuZGVmaW5lZH0gcGVybWl0U3BlYyAtIEZsYXQgcGVybWl0IHNwZWMuXG4gKiBAcmV0dXJucyB7e2F0dHJpYnV0ZXM6IHN0cmluZ1tdLCBuZXN0ZWQ6IFJlY29yZDxzdHJpbmcsIHthdHRyaWJ1dGVzOiBzdHJpbmdbXSwgbmVzdGVkOiBSZWNvcmQ8c3RyaW5nLCA/Pn0+fX0gLSBQYXJzZWQgc3RydWN0dXJlLlxuICovXG5mdW5jdGlvbiBwYXJzZVBlcm1pdHRlZFBhcmFtcyhwZXJtaXRTcGVjKSB7XG4gIC8qKlxuICAgKiBBdHRyaWJ1dGVzLlxuICAgIEB0eXBlIHtzdHJpbmdbXX0gKi9cbiAgY29uc3QgYXR0cmlidXRlcyA9IFtdXG4gIC8qKlxuICAgKiBOZXN0ZWQuXG4gICAgQHR5cGUge1JlY29yZDxzdHJpbmcsIHthdHRyaWJ1dGVzOiBzdHJpbmdbXSwgbmVzdGVkOiBSZWNvcmQ8c3RyaW5nLCA/Pn0+fSAqL1xuICBjb25zdCBuZXN0ZWQgPSB7fVxuXG4gIGlmICghQXJyYXkuaXNBcnJheShwZXJtaXRTcGVjKSkgcmV0dXJuIHthdHRyaWJ1dGVzLCBuZXN0ZWR9XG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiBwZXJtaXRTcGVjKSB7XG4gICAgaWYgKHR5cGVvZiBlbnRyeSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgYXR0cmlidXRlcy5wdXNoKGVudHJ5KVxuICAgIH0gZWxzZSBpZiAoZW50cnkgJiYgdHlwZW9mIGVudHJ5ID09PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KGVudHJ5KSkge1xuICAgICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoZW50cnkpKSB7XG4gICAgICAgIGlmICgha2V5LmVuZHNXaXRoKFwiQXR0cmlidXRlc1wiKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBwZXJtaXR0ZWRQYXJhbXMgZW50cnk6IG5lc3RlZCByZWxhdGlvbnNoaXAga2V5cyBtdXN0IGVuZCBpbiBcIkF0dHJpYnV0ZXNcIiAoZ290IFwiJHtrZXl9XCIpLiBVc2UgXCIke2tleX1BdHRyaWJ1dGVzXCIgaW5zdGVhZC5gKVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHJlbGF0aW9uc2hpcE5hbWUgPSBrZXkuc2xpY2UoMCwgLVwiQXR0cmlidXRlc1wiLmxlbmd0aClcblxuICAgICAgICBpZiAoIXJlbGF0aW9uc2hpcE5hbWUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcGVybWl0dGVkUGFyYW1zIGVudHJ5OiBlbXB0eSByZWxhdGlvbnNoaXAgbmFtZSBpbiBrZXkgXCIke2tleX1cIi5gKVxuICAgICAgICB9XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcGVybWl0dGVkUGFyYW1zIGVudHJ5IGZvciBcIiR7a2V5fVwiOiBleHBlY3RlZCBhcnJheSBwZXJtaXQgc3BlYywgZ290ICR7dHlwZW9mIHZhbHVlfS5gKVxuICAgICAgICB9XG5cbiAgICAgICAgbmVzdGVkW3JlbGF0aW9uc2hpcE5hbWVdID0gcGFyc2VQZXJtaXR0ZWRQYXJhbXModmFsdWUpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBwZXJtaXR0ZWRQYXJhbXMgZW50cnk6IGV4cGVjdGVkIHN0cmluZyBvciBuZXN0ZWQtYXR0cmlidXRlcyBvYmplY3QsIGdvdCAke3R5cGVvZiBlbnRyeX0uYClcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge2F0dHJpYnV0ZXMsIG5lc3RlZH1cbn1cblxuLyoqXG4gKiBSdW5zIGZpbHRlciB3cml0YWJsZSBmcm9udGVuZCBtb2RlbCBhdHRyaWJ1dGVzLlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gcmVjZWl2ZXIgLSBNb2RlbCBpbnN0YW5jZSBvciBwcm90b3R5cGUuXG4gKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBhdHRyaWJ1dGVzIC0gSW5jb21pbmcgZnJvbnRlbmQtbW9kZWwgYXR0cmlidXRlcy5cbiAqIEBwYXJhbSB7RnJvbnRlbmRNb2RlbEJhc2VSZXNvdXJjZSB8IG51bGx9IFtyZXNvdXJjZV0gLSBSZXNvdXJjZSBpbnN0YW5jZSBmb3IgdmlydHVhbC1zZXR0ZXIgZGV0ZWN0aW9uLlxuICogQHBhcmFtIHtzdHJpbmdbXSB8IG51bGx9IFtwZXJtaXR0ZWRBdHRyaWJ1dGVOYW1lc10gLSBPcHRpb25hbCBleHBsaWNpdCBwZXJtaXQgbGlzdC4gYG51bGxgIGZhbGxzIGJhY2sgdG8gc2V0dGVyLWV4aXN0ZW5jZSBjaGVja3Mgb25seS5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gLSBXcml0YWJsZSBhdHRyaWJ1dGVzIG9ubHkuXG4gKi9cbmZ1bmN0aW9uIGZpbHRlcldyaXRhYmxlRnJvbnRlbmRNb2RlbEF0dHJpYnV0ZXMocmVjZWl2ZXIsIGF0dHJpYnV0ZXMsIHJlc291cmNlID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7RnJvbnRlbmRNb2RlbEJhc2VSZXNvdXJjZSB8IG51bGx9ICovIChudWxsKSwgcGVybWl0dGVkQXR0cmlidXRlTmFtZXMgPSBudWxsKSB7XG4gIC8vIEZyb250ZW5kLW1vZGVsIHdyaXRlcyBzaG91bGQgZmFpbCBmYXN0IHdoZW4gY2FsbGVycyBzdWJtaXQgcmVhZC1vbmx5IG9yIHVua25vd24gYXR0cnMuXG4gIC8vIFNpbGVudCBkcm9wcyBoaWRlIGNvbnRyYWN0IG1pc3Rha2VzIGluIGdlbmVyYXRlZCBtb2RlbHMgYW5kIGFwcC1zaWRlIHdyYXBwZXIgY29kZS5cbiAgLyoqXG4gICAqIFdyaXRhYmxlIGF0dHJpYnV0ZXMuXG4gICAgQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqL1xuICBjb25zdCB3cml0YWJsZUF0dHJpYnV0ZXMgPSB7fVxuICAvKipcbiAgICogSW52YWxpZCBhdHRyaWJ1dGVzLlxuICAgIEB0eXBlIHtzdHJpbmdbXX0gKi9cbiAgY29uc3QgaW52YWxpZEF0dHJpYnV0ZXMgPSBbXVxuICAvKipcbiAgICogTm90IHBlcm1pdHRlZCBhdHRyaWJ1dGVzLlxuICAgIEB0eXBlIHtzdHJpbmdbXX0gKi9cbiAgY29uc3Qgbm90UGVybWl0dGVkQXR0cmlidXRlcyA9IFtdXG5cbiAgY29uc3QgcGVybWl0U2V0ID0gQXJyYXkuaXNBcnJheShwZXJtaXR0ZWRBdHRyaWJ1dGVOYW1lcykgPyBuZXcgU2V0KHBlcm1pdHRlZEF0dHJpYnV0ZU5hbWVzKSA6IG51bGxcbiAgY29uc3QgdHJhbnNsYXRlZFNldCA9IHJlc291cmNlID8gbmV3IFNldCgvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7dHlwZW9mIEZyb250ZW5kTW9kZWxCYXNlUmVzb3VyY2V9ICovIChyZXNvdXJjZS5jb25zdHJ1Y3RvcikudHJhbnNsYXRlZEF0dHJpYnV0ZXMgfHwgW10pIDogbmV3IFNldCgpXG5cbiAgZm9yIChjb25zdCBbYXR0cmlidXRlTmFtZSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGF0dHJpYnV0ZXMpKSB7XG4gICAgaWYgKHBlcm1pdFNldCAmJiAhcGVybWl0U2V0LmhhcyhhdHRyaWJ1dGVOYW1lKSkge1xuICAgICAgbm90UGVybWl0dGVkQXR0cmlidXRlcy5wdXNoKGF0dHJpYnV0ZU5hbWUpXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGNvbnN0IHNldHRlck5hbWUgPSBgc2V0JHtpbmZsZWN0aW9uLmNhbWVsaXplKGF0dHJpYnV0ZU5hbWUpfWBcbiAgICBjb25zdCByZXNvdXJjZVNldHRlck5hbWUgPSBgJHtzZXR0ZXJOYW1lfUF0dHJpYnV0ZWBcblxuICAgIGlmIChzZXR0ZXJOYW1lIGluIHJlY2VpdmVyKSB7XG4gICAgICB3cml0YWJsZUF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV0gPSB2YWx1ZVxuICAgIH0gZWxzZSBpZiAocmVzb3VyY2UgJiYgdHlwZW9mIC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7P30gKi8gKHJlc291cmNlKSlbcmVzb3VyY2VTZXR0ZXJOYW1lXSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICB3cml0YWJsZUF0dHJpYnV0ZXNbYXR0cmlidXRlTmFtZV0gPSB2YWx1ZVxuICAgIH0gZWxzZSBpZiAodHJhbnNsYXRlZFNldC5oYXMoYXR0cmlidXRlTmFtZSkpIHtcbiAgICAgIHdyaXRhYmxlQXR0cmlidXRlc1thdHRyaWJ1dGVOYW1lXSA9IHZhbHVlXG4gICAgfSBlbHNlIHtcbiAgICAgIGludmFsaWRBdHRyaWJ1dGVzLnB1c2goYXR0cmlidXRlTmFtZSlcbiAgICB9XG4gIH1cblxuICBpZiAobm90UGVybWl0dGVkQXR0cmlidXRlcy5sZW5ndGggPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBGcm9udGVuZCBtb2RlbCB3cml0ZSBhdHRyaWJ1dGVzIG5vdCBwZXJtaXR0ZWQgYnkgcGVybWl0dGVkUGFyYW1zKCk6ICR7bm90UGVybWl0dGVkQXR0cmlidXRlcy5qb2luKFwiLCBcIil9YClcbiAgfVxuXG4gIGlmIChpbnZhbGlkQXR0cmlidXRlcy5sZW5ndGggPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGZyb250ZW5kIG1vZGVsIHdyaXRlIGF0dHJpYnV0ZXM6ICR7aW52YWxpZEF0dHJpYnV0ZXMuam9pbihcIiwgXCIpfWApXG4gIH1cblxuICByZXR1cm4gd3JpdGFibGVBdHRyaWJ1dGVzXG59XG4iXX0=
|