@appconda/nextjs 1.0.112 → 1.0.113

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.
Files changed (307) hide show
  1. package/package.json +3 -3
  2. package/dist/actions/actionClient.d.ts +0 -10
  3. package/dist/actions/actionClient.js +0 -38
  4. package/dist/actions/auth.d.ts +0 -1
  5. package/dist/actions/auth.js +0 -6
  6. package/dist/actions/authOptions.d.ts +0 -5
  7. package/dist/actions/authOptions.js +0 -235
  8. package/dist/actions/index.d.ts +0 -3
  9. package/dist/actions/index.js +0 -4
  10. package/dist/actions/nextAuthHandler.d.ts +0 -1
  11. package/dist/actions/nextAuthHandler.js +0 -6
  12. package/dist/actions/nodes.d.ts +0 -4
  13. package/dist/actions/nodes.js +0 -15
  14. package/dist/client.d.ts +0 -141
  15. package/dist/client.js +0 -335
  16. package/dist/decorators/Cache.d.ts +0 -1
  17. package/dist/decorators/Cache.js +0 -79
  18. package/dist/decorators/CacheKey.d.ts +0 -1
  19. package/dist/decorators/CacheKey.js +0 -9
  20. package/dist/decorators/Invalidate.d.ts +0 -1
  21. package/dist/decorators/Invalidate.js +0 -47
  22. package/dist/enums/api-service.d.ts +0 -13
  23. package/dist/enums/api-service.js +0 -15
  24. package/dist/enums/api.d.ts +0 -5
  25. package/dist/enums/api.js +0 -7
  26. package/dist/enums/auth-method.d.ts +0 -9
  27. package/dist/enums/auth-method.js +0 -11
  28. package/dist/enums/authentication-factor.d.ts +0 -6
  29. package/dist/enums/authentication-factor.js +0 -7
  30. package/dist/enums/authenticator-type.d.ts +0 -3
  31. package/dist/enums/authenticator-type.js +0 -4
  32. package/dist/enums/browser.d.ts +0 -16
  33. package/dist/enums/browser.js +0 -18
  34. package/dist/enums/compression.d.ts +0 -5
  35. package/dist/enums/compression.js +0 -7
  36. package/dist/enums/credit-card.d.ts +0 -18
  37. package/dist/enums/credit-card.js +0 -20
  38. package/dist/enums/database-usage-range.d.ts +0 -5
  39. package/dist/enums/database-usage-range.js +0 -7
  40. package/dist/enums/email-template-locale.d.ts +0 -133
  41. package/dist/enums/email-template-locale.js +0 -135
  42. package/dist/enums/email-template-type.d.ts +0 -9
  43. package/dist/enums/email-template-type.js +0 -11
  44. package/dist/enums/entities/EntityLimitType.d.ts +0 -4
  45. package/dist/enums/entities/EntityLimitType.js +0 -6
  46. package/dist/enums/entities/PropertyAttributeName.d.ts +0 -27
  47. package/dist/enums/entities/PropertyAttributeName.js +0 -29
  48. package/dist/enums/entities/PropertyCondition.d.ts +0 -7
  49. package/dist/enums/entities/PropertyCondition.js +0 -10
  50. package/dist/enums/entities/PropertyType.d.ts +0 -12
  51. package/dist/enums/entities/PropertyType.js +0 -18
  52. package/dist/enums/entities/PropertyValueType.d.ts +0 -6
  53. package/dist/enums/entities/PropertyValueType.js +0 -8
  54. package/dist/enums/entities/RowAccess.d.ts +0 -2
  55. package/dist/enums/entities/RowAccess.js +0 -2
  56. package/dist/enums/entities/ViewFilterCondition.d.ts +0 -12
  57. package/dist/enums/entities/ViewFilterCondition.js +0 -14
  58. package/dist/enums/execution-method.d.ts +0 -8
  59. package/dist/enums/execution-method.js +0 -10
  60. package/dist/enums/flag.d.ts +0 -197
  61. package/dist/enums/flag.js +0 -199
  62. package/dist/enums/function-usage-range.d.ts +0 -5
  63. package/dist/enums/function-usage-range.js +0 -7
  64. package/dist/enums/image-format.d.ts +0 -7
  65. package/dist/enums/image-format.js +0 -9
  66. package/dist/enums/image-gravity.d.ts +0 -11
  67. package/dist/enums/image-gravity.js +0 -13
  68. package/dist/enums/index-type.d.ts +0 -5
  69. package/dist/enums/index-type.js +0 -7
  70. package/dist/enums/messaging-provider-type.d.ts +0 -5
  71. package/dist/enums/messaging-provider-type.js +0 -7
  72. package/dist/enums/name.d.ts +0 -14
  73. package/dist/enums/name.js +0 -16
  74. package/dist/enums/o-auth-provider copy.d.ts +0 -41
  75. package/dist/enums/o-auth-provider copy.js +0 -43
  76. package/dist/enums/o-auth-provider.d.ts +0 -41
  77. package/dist/enums/o-auth-provider.js +0 -42
  78. package/dist/enums/password-hash.d.ts +0 -13
  79. package/dist/enums/password-hash.js +0 -15
  80. package/dist/enums/platform-type.d.ts +0 -17
  81. package/dist/enums/platform-type.js +0 -19
  82. package/dist/enums/project-usage-range.d.ts +0 -4
  83. package/dist/enums/project-usage-range.js +0 -6
  84. package/dist/enums/region.d.ts +0 -4
  85. package/dist/enums/region.js +0 -6
  86. package/dist/enums/relation-mutate.d.ts +0 -5
  87. package/dist/enums/relation-mutate.js +0 -7
  88. package/dist/enums/relationship-type.d.ts +0 -6
  89. package/dist/enums/relationship-type.js +0 -8
  90. package/dist/enums/resource-type.d.ts +0 -4
  91. package/dist/enums/resource-type.js +0 -6
  92. package/dist/enums/runtime.d.ts +0 -48
  93. package/dist/enums/runtime.js +0 -50
  94. package/dist/enums/s-m-t-p-secure.d.ts +0 -3
  95. package/dist/enums/s-m-t-p-secure.js +0 -5
  96. package/dist/enums/shared/ApplicationLayout.d.ts +0 -4
  97. package/dist/enums/shared/ApplicationLayout.js +0 -6
  98. package/dist/enums/shared/Colors.d.ts +0 -24
  99. package/dist/enums/shared/Colors.js +0 -26
  100. package/dist/enums/shared/InputType.d.ts +0 -6
  101. package/dist/enums/shared/InputType.js +0 -8
  102. package/dist/enums/shared/Periodicity.d.ts +0 -7
  103. package/dist/enums/shared/Periodicity.js +0 -9
  104. package/dist/enums/shared/SvgIcon.d.ts +0 -37
  105. package/dist/enums/shared/SvgIcon.js +0 -39
  106. package/dist/enums/shared/Theme.d.ts +0 -4
  107. package/dist/enums/shared/Theme.js +0 -6
  108. package/dist/enums/sms-template-locale.d.ts +0 -133
  109. package/dist/enums/sms-template-locale.js +0 -135
  110. package/dist/enums/sms-template-type.d.ts +0 -6
  111. package/dist/enums/sms-template-type.js +0 -8
  112. package/dist/enums/smtp-encryption.d.ts +0 -5
  113. package/dist/enums/smtp-encryption.js +0 -7
  114. package/dist/enums/storage-usage-range.d.ts +0 -5
  115. package/dist/enums/storage-usage-range.js +0 -7
  116. package/dist/enums/subscriptions/PricingModel.d.ts +0 -11
  117. package/dist/enums/subscriptions/PricingModel.js +0 -12
  118. package/dist/enums/subscriptions/SubscriptionBillingPeriod.d.ts +0 -10
  119. package/dist/enums/subscriptions/SubscriptionBillingPeriod.js +0 -11
  120. package/dist/enums/subscriptions/SubscriptionFeatureLimitType.d.ts +0 -10
  121. package/dist/enums/subscriptions/SubscriptionFeatureLimitType.js +0 -13
  122. package/dist/enums/subscriptions/SubscriptionPriceType.d.ts +0 -7
  123. package/dist/enums/subscriptions/SubscriptionPriceType.js +0 -8
  124. package/dist/enums/tenants/LinkedAccountStatus.d.ts +0 -5
  125. package/dist/enums/tenants/LinkedAccountStatus.js +0 -7
  126. package/dist/enums/tenants/TenantUserJoined.d.ts +0 -6
  127. package/dist/enums/tenants/TenantUserJoined.js +0 -8
  128. package/dist/enums/tenants/TenantUserStatus.d.ts +0 -6
  129. package/dist/enums/tenants/TenantUserStatus.js +0 -8
  130. package/dist/enums/tenants/TenantUserType.d.ts +0 -5
  131. package/dist/enums/tenants/TenantUserType.js +0 -7
  132. package/dist/enums/user-usage-range.d.ts +0 -5
  133. package/dist/enums/user-usage-range.js +0 -7
  134. package/dist/getAppcondaClient.d.ts +0 -2
  135. package/dist/getAppcondaClient.js +0 -44
  136. package/dist/getSDKForCurrentUser.d.ts +0 -43
  137. package/dist/getSDKForCurrentUser.js +0 -76
  138. package/dist/getSDKForService.d.ts +0 -6
  139. package/dist/getSDKForService.js +0 -51
  140. package/dist/getSDKForTenant.d.ts +0 -20
  141. package/dist/getSDKForTenant.js +0 -44
  142. package/dist/id.d.ts +0 -20
  143. package/dist/id.js +0 -45
  144. package/dist/index.d.ts +0 -44
  145. package/dist/index.js +0 -42
  146. package/dist/inputFile.d.ts +0 -6
  147. package/dist/inputFile.js +0 -17
  148. package/dist/lib/Cache/Adapter.d.ts +0 -10
  149. package/dist/lib/Cache/Adapter.js +0 -2
  150. package/dist/lib/Cache/Adapters/Filesystem.d.ts +0 -16
  151. package/dist/lib/Cache/Adapters/Filesystem.js +0 -103
  152. package/dist/lib/Cache/Adapters/Memory.d.ts +0 -18
  153. package/dist/lib/Cache/Adapters/Memory.js +0 -47
  154. package/dist/lib/Cache/Adapters/None.d.ts +0 -12
  155. package/dist/lib/Cache/Adapters/None.js +0 -28
  156. package/dist/lib/Cache/Adapters/Sharding.d.ts +0 -17
  157. package/dist/lib/Cache/Adapters/Sharding.js +0 -73
  158. package/dist/lib/Cache/Cache.d.ts +0 -16
  159. package/dist/lib/Cache/Cache.js +0 -52
  160. package/dist/lib/Cache/index.d.ts +0 -4
  161. package/dist/lib/Cache/index.js +0 -5
  162. package/dist/lib/Cache/test.d.ts +0 -0
  163. package/dist/lib/Cache/test.js +0 -1
  164. package/dist/lib/Registry/Registry.d.ts +0 -38
  165. package/dist/lib/Registry/Registry.js +0 -56
  166. package/dist/lib/Registry/index.d.ts +0 -1
  167. package/dist/lib/Registry/index.js +0 -2
  168. package/dist/lib/Services.d.ts +0 -6
  169. package/dist/lib/Services.js +0 -14
  170. package/dist/lib/crypto.d.ts +0 -23
  171. package/dist/lib/crypto.js +0 -78
  172. package/dist/lib/env.d.ts +0 -1
  173. package/dist/lib/env.js +0 -137
  174. package/dist/lib/errors.d.ts +0 -70
  175. package/dist/lib/errors.js +0 -76
  176. package/dist/lib/index.d.ts +0 -2
  177. package/dist/lib/index.js +0 -3
  178. package/dist/lib/jwt.d.ts +0 -12
  179. package/dist/lib/jwt.js +0 -103
  180. package/dist/models.d.ts +0 -3272
  181. package/dist/models.js +0 -2
  182. package/dist/modules/account/actions.d.ts +0 -25
  183. package/dist/modules/account/actions.js +0 -18
  184. package/dist/modules/account/enums/authentication-factor.d.ts +0 -6
  185. package/dist/modules/account/enums/authentication-factor.js +0 -8
  186. package/dist/modules/account/enums/authenticator-type.d.ts +0 -3
  187. package/dist/modules/account/enums/authenticator-type.js +0 -5
  188. package/dist/modules/account/enums/o-auth-provider.d.ts +0 -41
  189. package/dist/modules/account/enums/o-auth-provider.js +0 -43
  190. package/dist/modules/account/index.d.ts +0 -3
  191. package/dist/modules/account/index.js +0 -4
  192. package/dist/modules/account/schema.d.ts +0 -17
  193. package/dist/modules/account/schema.js +0 -8
  194. package/dist/modules/account/service.d.ts +0 -530
  195. package/dist/modules/account/service.js +0 -1260
  196. package/dist/modules/account/types.d.ts +0 -411
  197. package/dist/modules/account/types.js +0 -2
  198. package/dist/modules/acl/service.d.ts +0 -26
  199. package/dist/modules/acl/service.js +0 -27
  200. package/dist/modules/agent/action.d.ts +0 -53
  201. package/dist/modules/agent/action.js +0 -64
  202. package/dist/modules/agent/index.d.ts +0 -4
  203. package/dist/modules/agent/index.js +0 -5
  204. package/dist/modules/agent/schema.d.ts +0 -48
  205. package/dist/modules/agent/schema.js +0 -21
  206. package/dist/modules/agent/service.d.ts +0 -12
  207. package/dist/modules/agent/service.js +0 -22
  208. package/dist/modules/agent/types.d.ts +0 -11
  209. package/dist/modules/agent/types.js +0 -2
  210. package/dist/modules/ai/index.d.ts +0 -1
  211. package/dist/modules/ai/index.js +0 -2
  212. package/dist/modules/ai/node/actions.d.ts +0 -4
  213. package/dist/modules/ai/node/actions.js +0 -16
  214. package/dist/modules/ai/node/index.d.ts +0 -2
  215. package/dist/modules/ai/node/index.js +0 -3
  216. package/dist/modules/ai/node/service.d.ts +0 -5
  217. package/dist/modules/ai/node/service.js +0 -12
  218. package/dist/modules/index.d.ts +0 -6
  219. package/dist/modules/index.js +0 -7
  220. package/dist/modules/task/action.d.ts +0 -168
  221. package/dist/modules/task/action.js +0 -163
  222. package/dist/modules/task/index.d.ts +0 -4
  223. package/dist/modules/task/index.js +0 -5
  224. package/dist/modules/task/schema.d.ts +0 -107
  225. package/dist/modules/task/schema.js +0 -44
  226. package/dist/modules/task/service.d.ts +0 -19
  227. package/dist/modules/task/service.js +0 -43
  228. package/dist/modules/task/types.d.ts +0 -84
  229. package/dist/modules/task/types.js +0 -2
  230. package/dist/modules/tenant/actions.d.ts +0 -45
  231. package/dist/modules/tenant/actions.js +0 -38
  232. package/dist/modules/tenant/index.d.ts +0 -3
  233. package/dist/modules/tenant/index.js +0 -4
  234. package/dist/modules/tenant/tenant.d.ts +0 -32
  235. package/dist/modules/tenant/tenant.js +0 -125
  236. package/dist/modules/tenant/types.d.ts +0 -11
  237. package/dist/modules/tenant/types.js +0 -2
  238. package/dist/modules/waitlist/action.d.ts +0 -69
  239. package/dist/modules/waitlist/action.js +0 -78
  240. package/dist/modules/waitlist/index.d.ts +0 -4
  241. package/dist/modules/waitlist/index.js +0 -5
  242. package/dist/modules/waitlist/schema.d.ts +0 -39
  243. package/dist/modules/waitlist/schema.js +0 -18
  244. package/dist/modules/waitlist/service.d.ts +0 -13
  245. package/dist/modules/waitlist/service.js +0 -28
  246. package/dist/modules/waitlist/types.d.ts +0 -14
  247. package/dist/modules/waitlist/types.js +0 -2
  248. package/dist/permission.d.ts +0 -43
  249. package/dist/permission.js +0 -54
  250. package/dist/query.d.ts +0 -194
  251. package/dist/query.js +0 -204
  252. package/dist/role.d.ts +0 -70
  253. package/dist/role.js +0 -94
  254. package/dist/schemas/nodes.d.ts +0 -0
  255. package/dist/schemas/nodes.js +0 -1
  256. package/dist/service-client.d.ts +0 -7
  257. package/dist/service-client.js +0 -14
  258. package/dist/service.d.ts +0 -11
  259. package/dist/service.js +0 -23
  260. package/dist/services/account.d.ts +0 -530
  261. package/dist/services/account.js +0 -1259
  262. package/dist/services/applets.d.ts +0 -9
  263. package/dist/services/applets.js +0 -40
  264. package/dist/services/avatars.d.ts +0 -115
  265. package/dist/services/avatars.js +0 -251
  266. package/dist/services/chat-flow.d.ts +0 -7
  267. package/dist/services/chat-flow.js +0 -26
  268. package/dist/services/community.d.ts +0 -19
  269. package/dist/services/community.js +0 -69
  270. package/dist/services/configuration.d.ts +0 -5
  271. package/dist/services/configuration.js +0 -11
  272. package/dist/services/databases.d.ts +0 -613
  273. package/dist/services/databases.js +0 -1736
  274. package/dist/services/functions.d.ts +0 -319
  275. package/dist/services/functions.js +0 -810
  276. package/dist/services/graphql.d.ts +0 -25
  277. package/dist/services/graphql.js +0 -57
  278. package/dist/services/health.d.ts +0 -231
  279. package/dist/services/health.js +0 -463
  280. package/dist/services/locale.d.ts +0 -80
  281. package/dist/services/locale.js +0 -144
  282. package/dist/services/messaging.d.ts +0 -685
  283. package/dist/services/messaging.js +0 -1920
  284. package/dist/services/node.d.ts +0 -5
  285. package/dist/services/node.js +0 -11
  286. package/dist/services/permissions.d.ts +0 -20
  287. package/dist/services/permissions.js +0 -90
  288. package/dist/services/pricing.d.ts +0 -15
  289. package/dist/services/pricing.js +0 -21
  290. package/dist/services/projects.d.ts +0 -542
  291. package/dist/services/projects.js +0 -1526
  292. package/dist/services/roles.d.ts +0 -19
  293. package/dist/services/roles.js +0 -72
  294. package/dist/services/schema.d.ts +0 -17
  295. package/dist/services/schema.js +0 -48
  296. package/dist/services/storage.d.ts +0 -189
  297. package/dist/services/storage.js +0 -474
  298. package/dist/services/subscription.d.ts +0 -15
  299. package/dist/services/subscription.js +0 -30
  300. package/dist/services/teams.d.ts +0 -167
  301. package/dist/services/teams.js +0 -395
  302. package/dist/services/tenant-subscription.d.ts +0 -12
  303. package/dist/services/tenant-subscription.js +0 -52
  304. package/dist/services/tenant.d.ts +0 -32
  305. package/dist/services/tenant.js +0 -124
  306. package/dist/services/users.d.ts +0 -499
  307. package/dist/services/users.js +0 -1283
@@ -1,1283 +0,0 @@
1
- import { AppcondaException } from '../client';
2
- export class Users {
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- /**
7
- * List users
8
- *
9
- * Get a list of all the project's users. You can use the query params to filter your results.
10
- *
11
- * @param {string[]} queries
12
- * @param {string} search
13
- * @throws {AppcondaException}
14
- * @returns {Promise<Models.UserList<Preferences>>}
15
- */
16
- async list(queries, search) {
17
- const apiPath = '/users';
18
- const payload = {};
19
- if (typeof queries !== 'undefined') {
20
- payload['queries'] = queries;
21
- }
22
- if (typeof search !== 'undefined') {
23
- payload['search'] = search;
24
- }
25
- const uri = new URL(this.client.config.endpoint + apiPath);
26
- const apiHeaders = {
27
- 'content-type': 'application/json',
28
- };
29
- return await this.client.call('get', uri, apiHeaders, payload);
30
- }
31
- /**
32
- * Create user
33
- *
34
- * Create a new user.
35
- *
36
- * @param {string} userId
37
- * @param {string} email
38
- * @param {string} phone
39
- * @param {string} password
40
- * @param {string} name
41
- * @throws {AppcondaException}
42
- * @returns {Promise<Models.User<Preferences>>}
43
- */
44
- async create(userId, email, phone, password, name) {
45
- if (typeof userId === 'undefined') {
46
- throw new AppcondaException('Missing required parameter: "userId"');
47
- }
48
- const apiPath = '/users';
49
- const payload = {};
50
- if (typeof userId !== 'undefined') {
51
- payload['userId'] = userId;
52
- }
53
- if (typeof email !== 'undefined') {
54
- payload['email'] = email;
55
- }
56
- if (typeof phone !== 'undefined') {
57
- payload['phone'] = phone;
58
- }
59
- if (typeof password !== 'undefined') {
60
- payload['password'] = password;
61
- }
62
- if (typeof name !== 'undefined') {
63
- payload['name'] = name;
64
- }
65
- const uri = new URL(this.client.config.endpoint + apiPath);
66
- const apiHeaders = {
67
- 'content-type': 'application/json',
68
- };
69
- return await this.client.call('post', uri, apiHeaders, payload);
70
- }
71
- /**
72
- * Create user with Argon2 password
73
- *
74
- * Create a new user. Password provided must be hashed with the [Argon2](https://en.wikipedia.org/wiki/Argon2) algorithm. Use the [POST /users](https://appconda.io/docs/server/users#usersCreate) endpoint to create users with a plain text password.
75
- *
76
- * @param {string} userId
77
- * @param {string} email
78
- * @param {string} password
79
- * @param {string} name
80
- * @throws {AppcondaException}
81
- * @returns {Promise<Models.User<Preferences>>}
82
- */
83
- async createArgon2User(userId, email, password, name) {
84
- if (typeof userId === 'undefined') {
85
- throw new AppcondaException('Missing required parameter: "userId"');
86
- }
87
- if (typeof email === 'undefined') {
88
- throw new AppcondaException('Missing required parameter: "email"');
89
- }
90
- if (typeof password === 'undefined') {
91
- throw new AppcondaException('Missing required parameter: "password"');
92
- }
93
- const apiPath = '/users/argon2';
94
- const payload = {};
95
- if (typeof userId !== 'undefined') {
96
- payload['userId'] = userId;
97
- }
98
- if (typeof email !== 'undefined') {
99
- payload['email'] = email;
100
- }
101
- if (typeof password !== 'undefined') {
102
- payload['password'] = password;
103
- }
104
- if (typeof name !== 'undefined') {
105
- payload['name'] = name;
106
- }
107
- const uri = new URL(this.client.config.endpoint + apiPath);
108
- const apiHeaders = {
109
- 'content-type': 'application/json',
110
- };
111
- return await this.client.call('post', uri, apiHeaders, payload);
112
- }
113
- /**
114
- * Create user with bcrypt password
115
- *
116
- * Create a new user. Password provided must be hashed with the [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt) algorithm. Use the [POST /users](https://appconda.io/docs/server/users#usersCreate) endpoint to create users with a plain text password.
117
- *
118
- * @param {string} userId
119
- * @param {string} email
120
- * @param {string} password
121
- * @param {string} name
122
- * @throws {AppcondaException}
123
- * @returns {Promise<Models.User<Preferences>>}
124
- */
125
- async createBcryptUser(userId, email, password, name) {
126
- if (typeof userId === 'undefined') {
127
- throw new AppcondaException('Missing required parameter: "userId"');
128
- }
129
- if (typeof email === 'undefined') {
130
- throw new AppcondaException('Missing required parameter: "email"');
131
- }
132
- if (typeof password === 'undefined') {
133
- throw new AppcondaException('Missing required parameter: "password"');
134
- }
135
- const apiPath = '/users/bcrypt';
136
- const payload = {};
137
- if (typeof userId !== 'undefined') {
138
- payload['userId'] = userId;
139
- }
140
- if (typeof email !== 'undefined') {
141
- payload['email'] = email;
142
- }
143
- if (typeof password !== 'undefined') {
144
- payload['password'] = password;
145
- }
146
- if (typeof name !== 'undefined') {
147
- payload['name'] = name;
148
- }
149
- const uri = new URL(this.client.config.endpoint + apiPath);
150
- const apiHeaders = {
151
- 'content-type': 'application/json',
152
- };
153
- return await this.client.call('post', uri, apiHeaders, payload);
154
- }
155
- /**
156
- * List Identities
157
- *
158
- * Get identities for all users.
159
- *
160
- * @param {string[]} queries
161
- * @param {string} search
162
- * @throws {AppcondaException}
163
- * @returns {Promise<Models.IdentityList>}
164
- */
165
- async listIdentities(queries, search) {
166
- const apiPath = '/users/identities';
167
- const payload = {};
168
- if (typeof queries !== 'undefined') {
169
- payload['queries'] = queries;
170
- }
171
- if (typeof search !== 'undefined') {
172
- payload['search'] = search;
173
- }
174
- const uri = new URL(this.client.config.endpoint + apiPath);
175
- const apiHeaders = {
176
- 'content-type': 'application/json',
177
- };
178
- return await this.client.call('get', uri, apiHeaders, payload);
179
- }
180
- /**
181
- * Delete identity
182
- *
183
- * Delete an identity by its unique ID.
184
- *
185
- * @param {string} identityId
186
- * @throws {AppcondaException}
187
- * @returns {Promise<{}>}
188
- */
189
- async deleteIdentity(identityId) {
190
- if (typeof identityId === 'undefined') {
191
- throw new AppcondaException('Missing required parameter: "identityId"');
192
- }
193
- const apiPath = '/users/identities/{identityId}'.replace('{identityId}', identityId);
194
- const payload = {};
195
- const uri = new URL(this.client.config.endpoint + apiPath);
196
- const apiHeaders = {
197
- 'content-type': 'application/json',
198
- };
199
- return await this.client.call('delete', uri, apiHeaders, payload);
200
- }
201
- /**
202
- * Create user with MD5 password
203
- *
204
- * Create a new user. Password provided must be hashed with the [MD5](https://en.wikipedia.org/wiki/MD5) algorithm. Use the [POST /users](https://appconda.io/docs/server/users#usersCreate) endpoint to create users with a plain text password.
205
- *
206
- * @param {string} userId
207
- * @param {string} email
208
- * @param {string} password
209
- * @param {string} name
210
- * @throws {AppcondaException}
211
- * @returns {Promise<Models.User<Preferences>>}
212
- */
213
- async createMD5User(userId, email, password, name) {
214
- if (typeof userId === 'undefined') {
215
- throw new AppcondaException('Missing required parameter: "userId"');
216
- }
217
- if (typeof email === 'undefined') {
218
- throw new AppcondaException('Missing required parameter: "email"');
219
- }
220
- if (typeof password === 'undefined') {
221
- throw new AppcondaException('Missing required parameter: "password"');
222
- }
223
- const apiPath = '/users/md5';
224
- const payload = {};
225
- if (typeof userId !== 'undefined') {
226
- payload['userId'] = userId;
227
- }
228
- if (typeof email !== 'undefined') {
229
- payload['email'] = email;
230
- }
231
- if (typeof password !== 'undefined') {
232
- payload['password'] = password;
233
- }
234
- if (typeof name !== 'undefined') {
235
- payload['name'] = name;
236
- }
237
- const uri = new URL(this.client.config.endpoint + apiPath);
238
- const apiHeaders = {
239
- 'content-type': 'application/json',
240
- };
241
- return await this.client.call('post', uri, apiHeaders, payload);
242
- }
243
- /**
244
- * Create user with PHPass password
245
- *
246
- * Create a new user. Password provided must be hashed with the [PHPass](https://www.openwall.com/phpass/) algorithm. Use the [POST /users](https://appconda.io/docs/server/users#usersCreate) endpoint to create users with a plain text password.
247
- *
248
- * @param {string} userId
249
- * @param {string} email
250
- * @param {string} password
251
- * @param {string} name
252
- * @throws {AppcondaException}
253
- * @returns {Promise<Models.User<Preferences>>}
254
- */
255
- async createPHPassUser(userId, email, password, name) {
256
- if (typeof userId === 'undefined') {
257
- throw new AppcondaException('Missing required parameter: "userId"');
258
- }
259
- if (typeof email === 'undefined') {
260
- throw new AppcondaException('Missing required parameter: "email"');
261
- }
262
- if (typeof password === 'undefined') {
263
- throw new AppcondaException('Missing required parameter: "password"');
264
- }
265
- const apiPath = '/users/phpass';
266
- const payload = {};
267
- if (typeof userId !== 'undefined') {
268
- payload['userId'] = userId;
269
- }
270
- if (typeof email !== 'undefined') {
271
- payload['email'] = email;
272
- }
273
- if (typeof password !== 'undefined') {
274
- payload['password'] = password;
275
- }
276
- if (typeof name !== 'undefined') {
277
- payload['name'] = name;
278
- }
279
- const uri = new URL(this.client.config.endpoint + apiPath);
280
- const apiHeaders = {
281
- 'content-type': 'application/json',
282
- };
283
- return await this.client.call('post', uri, apiHeaders, payload);
284
- }
285
- /**
286
- * Create user with Scrypt password
287
- *
288
- * Create a new user. Password provided must be hashed with the [Scrypt](https://github.com/Tarsnap/scrypt) algorithm. Use the [POST /users](https://appconda.io/docs/server/users#usersCreate) endpoint to create users with a plain text password.
289
- *
290
- * @param {string} userId
291
- * @param {string} email
292
- * @param {string} password
293
- * @param {string} passwordSalt
294
- * @param {number} passwordCpu
295
- * @param {number} passwordMemory
296
- * @param {number} passwordParallel
297
- * @param {number} passwordLength
298
- * @param {string} name
299
- * @throws {AppcondaException}
300
- * @returns {Promise<Models.User<Preferences>>}
301
- */
302
- async createScryptUser(userId, email, password, passwordSalt, passwordCpu, passwordMemory, passwordParallel, passwordLength, name) {
303
- if (typeof userId === 'undefined') {
304
- throw new AppcondaException('Missing required parameter: "userId"');
305
- }
306
- if (typeof email === 'undefined') {
307
- throw new AppcondaException('Missing required parameter: "email"');
308
- }
309
- if (typeof password === 'undefined') {
310
- throw new AppcondaException('Missing required parameter: "password"');
311
- }
312
- if (typeof passwordSalt === 'undefined') {
313
- throw new AppcondaException('Missing required parameter: "passwordSalt"');
314
- }
315
- if (typeof passwordCpu === 'undefined') {
316
- throw new AppcondaException('Missing required parameter: "passwordCpu"');
317
- }
318
- if (typeof passwordMemory === 'undefined') {
319
- throw new AppcondaException('Missing required parameter: "passwordMemory"');
320
- }
321
- if (typeof passwordParallel === 'undefined') {
322
- throw new AppcondaException('Missing required parameter: "passwordParallel"');
323
- }
324
- if (typeof passwordLength === 'undefined') {
325
- throw new AppcondaException('Missing required parameter: "passwordLength"');
326
- }
327
- const apiPath = '/users/scrypt';
328
- const payload = {};
329
- if (typeof userId !== 'undefined') {
330
- payload['userId'] = userId;
331
- }
332
- if (typeof email !== 'undefined') {
333
- payload['email'] = email;
334
- }
335
- if (typeof password !== 'undefined') {
336
- payload['password'] = password;
337
- }
338
- if (typeof passwordSalt !== 'undefined') {
339
- payload['passwordSalt'] = passwordSalt;
340
- }
341
- if (typeof passwordCpu !== 'undefined') {
342
- payload['passwordCpu'] = passwordCpu;
343
- }
344
- if (typeof passwordMemory !== 'undefined') {
345
- payload['passwordMemory'] = passwordMemory;
346
- }
347
- if (typeof passwordParallel !== 'undefined') {
348
- payload['passwordParallel'] = passwordParallel;
349
- }
350
- if (typeof passwordLength !== 'undefined') {
351
- payload['passwordLength'] = passwordLength;
352
- }
353
- if (typeof name !== 'undefined') {
354
- payload['name'] = name;
355
- }
356
- const uri = new URL(this.client.config.endpoint + apiPath);
357
- const apiHeaders = {
358
- 'content-type': 'application/json',
359
- };
360
- return await this.client.call('post', uri, apiHeaders, payload);
361
- }
362
- /**
363
- * Create user with Scrypt modified password
364
- *
365
- * Create a new user. Password provided must be hashed with the [Scrypt Modified](https://gist.github.com/Meldiron/eecf84a0225eccb5a378d45bb27462cc) algorithm. Use the [POST /users](https://appconda.io/docs/server/users#usersCreate) endpoint to create users with a plain text password.
366
- *
367
- * @param {string} userId
368
- * @param {string} email
369
- * @param {string} password
370
- * @param {string} passwordSalt
371
- * @param {string} passwordSaltSeparator
372
- * @param {string} passwordSignerKey
373
- * @param {string} name
374
- * @throws {AppcondaException}
375
- * @returns {Promise<Models.User<Preferences>>}
376
- */
377
- async createScryptModifiedUser(userId, email, password, passwordSalt, passwordSaltSeparator, passwordSignerKey, name) {
378
- if (typeof userId === 'undefined') {
379
- throw new AppcondaException('Missing required parameter: "userId"');
380
- }
381
- if (typeof email === 'undefined') {
382
- throw new AppcondaException('Missing required parameter: "email"');
383
- }
384
- if (typeof password === 'undefined') {
385
- throw new AppcondaException('Missing required parameter: "password"');
386
- }
387
- if (typeof passwordSalt === 'undefined') {
388
- throw new AppcondaException('Missing required parameter: "passwordSalt"');
389
- }
390
- if (typeof passwordSaltSeparator === 'undefined') {
391
- throw new AppcondaException('Missing required parameter: "passwordSaltSeparator"');
392
- }
393
- if (typeof passwordSignerKey === 'undefined') {
394
- throw new AppcondaException('Missing required parameter: "passwordSignerKey"');
395
- }
396
- const apiPath = '/users/scrypt-modified';
397
- const payload = {};
398
- if (typeof userId !== 'undefined') {
399
- payload['userId'] = userId;
400
- }
401
- if (typeof email !== 'undefined') {
402
- payload['email'] = email;
403
- }
404
- if (typeof password !== 'undefined') {
405
- payload['password'] = password;
406
- }
407
- if (typeof passwordSalt !== 'undefined') {
408
- payload['passwordSalt'] = passwordSalt;
409
- }
410
- if (typeof passwordSaltSeparator !== 'undefined') {
411
- payload['passwordSaltSeparator'] = passwordSaltSeparator;
412
- }
413
- if (typeof passwordSignerKey !== 'undefined') {
414
- payload['passwordSignerKey'] = passwordSignerKey;
415
- }
416
- if (typeof name !== 'undefined') {
417
- payload['name'] = name;
418
- }
419
- const uri = new URL(this.client.config.endpoint + apiPath);
420
- const apiHeaders = {
421
- 'content-type': 'application/json',
422
- };
423
- return await this.client.call('post', uri, apiHeaders, payload);
424
- }
425
- /**
426
- * Create user with SHA password
427
- *
428
- * Create a new user. Password provided must be hashed with the [SHA](https://en.wikipedia.org/wiki/Secure_Hash_Algorithm) algorithm. Use the [POST /users](https://appconda.io/docs/server/users#usersCreate) endpoint to create users with a plain text password.
429
- *
430
- * @param {string} userId
431
- * @param {string} email
432
- * @param {string} password
433
- * @param {PasswordHash} passwordVersion
434
- * @param {string} name
435
- * @throws {AppcondaException}
436
- * @returns {Promise<Models.User<Preferences>>}
437
- */
438
- async createSHAUser(userId, email, password, passwordVersion, name) {
439
- if (typeof userId === 'undefined') {
440
- throw new AppcondaException('Missing required parameter: "userId"');
441
- }
442
- if (typeof email === 'undefined') {
443
- throw new AppcondaException('Missing required parameter: "email"');
444
- }
445
- if (typeof password === 'undefined') {
446
- throw new AppcondaException('Missing required parameter: "password"');
447
- }
448
- const apiPath = '/users/sha';
449
- const payload = {};
450
- if (typeof userId !== 'undefined') {
451
- payload['userId'] = userId;
452
- }
453
- if (typeof email !== 'undefined') {
454
- payload['email'] = email;
455
- }
456
- if (typeof password !== 'undefined') {
457
- payload['password'] = password;
458
- }
459
- if (typeof passwordVersion !== 'undefined') {
460
- payload['passwordVersion'] = passwordVersion;
461
- }
462
- if (typeof name !== 'undefined') {
463
- payload['name'] = name;
464
- }
465
- const uri = new URL(this.client.config.endpoint + apiPath);
466
- const apiHeaders = {
467
- 'content-type': 'application/json',
468
- };
469
- return await this.client.call('post', uri, apiHeaders, payload);
470
- }
471
- /**
472
- * Get user
473
- *
474
- * Get a user by its unique ID.
475
- *
476
- * @param {string} userId
477
- * @throws {AppcondaException}
478
- * @returns {Promise<Models.User<Preferences>>}
479
- */
480
- async get(userId) {
481
- if (typeof userId === 'undefined') {
482
- throw new AppcondaException('Missing required parameter: "userId"');
483
- }
484
- const apiPath = '/users/{userId}'.replace('{userId}', userId);
485
- const payload = {};
486
- const uri = new URL(this.client.config.endpoint + apiPath);
487
- const apiHeaders = {
488
- 'content-type': 'application/json',
489
- };
490
- return await this.client.call('get', uri, apiHeaders, payload);
491
- }
492
- /**
493
- * Delete user
494
- *
495
- * Delete a user by its unique ID, thereby releasing it&#039;s ID. Since ID is released and can be reused, all user-related resources like documents or storage files should be deleted before user deletion. If you want to keep ID reserved, use the [updateStatus](https://appconda.io/docs/server/users#usersUpdateStatus) endpoint instead.
496
- *
497
- * @param {string} userId
498
- * @throws {AppcondaException}
499
- * @returns {Promise<{}>}
500
- */
501
- async delete(userId) {
502
- if (typeof userId === 'undefined') {
503
- throw new AppcondaException('Missing required parameter: "userId"');
504
- }
505
- const apiPath = '/users/{userId}'.replace('{userId}', userId);
506
- const payload = {};
507
- const uri = new URL(this.client.config.endpoint + apiPath);
508
- const apiHeaders = {
509
- 'content-type': 'application/json',
510
- };
511
- return await this.client.call('delete', uri, apiHeaders, payload);
512
- }
513
- /**
514
- * Update email
515
- *
516
- * Update the user email by its unique ID.
517
- *
518
- * @param {string} userId
519
- * @param {string} email
520
- * @throws {AppcondaException}
521
- * @returns {Promise<Models.User<Preferences>>}
522
- */
523
- async updateEmail(userId, email) {
524
- if (typeof userId === 'undefined') {
525
- throw new AppcondaException('Missing required parameter: "userId"');
526
- }
527
- if (typeof email === 'undefined') {
528
- throw new AppcondaException('Missing required parameter: "email"');
529
- }
530
- const apiPath = '/users/{userId}/email'.replace('{userId}', userId);
531
- const payload = {};
532
- if (typeof email !== 'undefined') {
533
- payload['email'] = email;
534
- }
535
- const uri = new URL(this.client.config.endpoint + apiPath);
536
- const apiHeaders = {
537
- 'content-type': 'application/json',
538
- };
539
- return await this.client.call('patch', uri, apiHeaders, payload);
540
- }
541
- /**
542
- * Create user JWT
543
- *
544
- * Use this endpoint to create a JSON Web Token for user by its unique ID. You can use the resulting JWT to authenticate on behalf of the user. The JWT secret will become invalid if the session it uses gets deleted.
545
- *
546
- * @param {string} userId
547
- * @param {string} sessionId
548
- * @param {number} duration
549
- * @throws {AppcondaException}
550
- * @returns {Promise<Models.Jwt>}
551
- */
552
- async createJWT(userId, sessionId, duration) {
553
- if (typeof userId === 'undefined') {
554
- throw new AppcondaException('Missing required parameter: "userId"');
555
- }
556
- const apiPath = '/users/{userId}/jwts'.replace('{userId}', userId);
557
- const payload = {};
558
- if (typeof sessionId !== 'undefined') {
559
- payload['sessionId'] = sessionId;
560
- }
561
- if (typeof duration !== 'undefined') {
562
- payload['duration'] = duration;
563
- }
564
- const uri = new URL(this.client.config.endpoint + apiPath);
565
- const apiHeaders = {
566
- 'content-type': 'application/json',
567
- };
568
- return await this.client.call('post', uri, apiHeaders, payload);
569
- }
570
- /**
571
- * Update user labels
572
- *
573
- * Update the user labels by its unique ID.
574
-
575
- Labels can be used to grant access to resources. While teams are a way for user&#039;s to share access to a resource, labels can be defined by the developer to grant access without an invitation. See the [Permissions docs](https://appconda.io/docs/permissions) for more info.
576
- *
577
- * @param {string} userId
578
- * @param {string[]} labels
579
- * @throws {AppcondaException}
580
- * @returns {Promise<Models.User<Preferences>>}
581
- */
582
- async updateLabels(userId, labels) {
583
- if (typeof userId === 'undefined') {
584
- throw new AppcondaException('Missing required parameter: "userId"');
585
- }
586
- if (typeof labels === 'undefined') {
587
- throw new AppcondaException('Missing required parameter: "labels"');
588
- }
589
- const apiPath = '/users/{userId}/labels'.replace('{userId}', userId);
590
- const payload = {};
591
- if (typeof labels !== 'undefined') {
592
- payload['labels'] = labels;
593
- }
594
- const uri = new URL(this.client.config.endpoint + apiPath);
595
- const apiHeaders = {
596
- 'content-type': 'application/json',
597
- };
598
- return await this.client.call('put', uri, apiHeaders, payload);
599
- }
600
- /**
601
- * List user logs
602
- *
603
- * Get the user activity logs list by its unique ID.
604
- *
605
- * @param {string} userId
606
- * @param {string[]} queries
607
- * @throws {AppcondaException}
608
- * @returns {Promise<Models.LogList>}
609
- */
610
- async listLogs(userId, queries) {
611
- if (typeof userId === 'undefined') {
612
- throw new AppcondaException('Missing required parameter: "userId"');
613
- }
614
- const apiPath = '/users/{userId}/logs'.replace('{userId}', userId);
615
- const payload = {};
616
- if (typeof queries !== 'undefined') {
617
- payload['queries'] = queries;
618
- }
619
- const uri = new URL(this.client.config.endpoint + apiPath);
620
- const apiHeaders = {
621
- 'content-type': 'application/json',
622
- };
623
- return await this.client.call('get', uri, apiHeaders, payload);
624
- }
625
- /**
626
- * List user memberships
627
- *
628
- * Get the user membership list by its unique ID.
629
- *
630
- * @param {string} userId
631
- * @throws {AppcondaException}
632
- * @returns {Promise<Models.MembershipList>}
633
- */
634
- async listMemberships(userId) {
635
- if (typeof userId === 'undefined') {
636
- throw new AppcondaException('Missing required parameter: "userId"');
637
- }
638
- const apiPath = '/users/{userId}/memberships'.replace('{userId}', userId);
639
- const payload = {};
640
- const uri = new URL(this.client.config.endpoint + apiPath);
641
- const apiHeaders = {
642
- 'content-type': 'application/json',
643
- };
644
- return await this.client.call('get', uri, apiHeaders, payload);
645
- }
646
- /**
647
- * Update MFA
648
- *
649
- * Enable or disable MFA on a user account.
650
- *
651
- * @param {string} userId
652
- * @param {boolean} mfa
653
- * @throws {AppcondaException}
654
- * @returns {Promise<Models.User<Preferences>>}
655
- */
656
- async updateMfa(userId, mfa) {
657
- if (typeof userId === 'undefined') {
658
- throw new AppcondaException('Missing required parameter: "userId"');
659
- }
660
- if (typeof mfa === 'undefined') {
661
- throw new AppcondaException('Missing required parameter: "mfa"');
662
- }
663
- const apiPath = '/users/{userId}/mfa'.replace('{userId}', userId);
664
- const payload = {};
665
- if (typeof mfa !== 'undefined') {
666
- payload['mfa'] = mfa;
667
- }
668
- const uri = new URL(this.client.config.endpoint + apiPath);
669
- const apiHeaders = {
670
- 'content-type': 'application/json',
671
- };
672
- return await this.client.call('patch', uri, apiHeaders, payload);
673
- }
674
- /**
675
- * Delete Authenticator
676
- *
677
- * Delete an authenticator app.
678
- *
679
- * @param {string} userId
680
- * @param {AuthenticatorType} type
681
- * @throws {AppcondaException}
682
- * @returns {Promise<Models.User<Preferences>>}
683
- */
684
- async deleteMfaAuthenticator(userId, type) {
685
- if (typeof userId === 'undefined') {
686
- throw new AppcondaException('Missing required parameter: "userId"');
687
- }
688
- if (typeof type === 'undefined') {
689
- throw new AppcondaException('Missing required parameter: "type"');
690
- }
691
- const apiPath = '/users/{userId}/mfa/authenticators/{type}'.replace('{userId}', userId).replace('{type}', type);
692
- const payload = {};
693
- const uri = new URL(this.client.config.endpoint + apiPath);
694
- const apiHeaders = {
695
- 'content-type': 'application/json',
696
- };
697
- return await this.client.call('delete', uri, apiHeaders, payload);
698
- }
699
- /**
700
- * List Factors
701
- *
702
- * List the factors available on the account to be used as a MFA challange.
703
- *
704
- * @param {string} userId
705
- * @throws {AppcondaException}
706
- * @returns {Promise<Models.MfaFactors>}
707
- */
708
- async listMfaFactors(userId) {
709
- if (typeof userId === 'undefined') {
710
- throw new AppcondaException('Missing required parameter: "userId"');
711
- }
712
- const apiPath = '/users/{userId}/mfa/factors'.replace('{userId}', userId);
713
- const payload = {};
714
- const uri = new URL(this.client.config.endpoint + apiPath);
715
- const apiHeaders = {
716
- 'content-type': 'application/json',
717
- };
718
- return await this.client.call('get', uri, apiHeaders, payload);
719
- }
720
- /**
721
- * Get MFA Recovery Codes
722
- *
723
- * Get recovery codes that can be used as backup for MFA flow by User ID. Before getting codes, they must be generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method.
724
- *
725
- * @param {string} userId
726
- * @throws {AppcondaException}
727
- * @returns {Promise<Models.MfaRecoveryCodes>}
728
- */
729
- async getMfaRecoveryCodes(userId) {
730
- if (typeof userId === 'undefined') {
731
- throw new AppcondaException('Missing required parameter: "userId"');
732
- }
733
- const apiPath = '/users/{userId}/mfa/recovery-codes'.replace('{userId}', userId);
734
- const payload = {};
735
- const uri = new URL(this.client.config.endpoint + apiPath);
736
- const apiHeaders = {
737
- 'content-type': 'application/json',
738
- };
739
- return await this.client.call('get', uri, apiHeaders, payload);
740
- }
741
- /**
742
- * Regenerate MFA Recovery Codes
743
- *
744
- * Regenerate recovery codes that can be used as backup for MFA flow by User ID. Before regenerating codes, they must be first generated using [createMfaRecoveryCodes](/docs/references/cloud/client-web/account#createMfaRecoveryCodes) method.
745
- *
746
- * @param {string} userId
747
- * @throws {AppcondaException}
748
- * @returns {Promise<Models.MfaRecoveryCodes>}
749
- */
750
- async updateMfaRecoveryCodes(userId) {
751
- if (typeof userId === 'undefined') {
752
- throw new AppcondaException('Missing required parameter: "userId"');
753
- }
754
- const apiPath = '/users/{userId}/mfa/recovery-codes'.replace('{userId}', userId);
755
- const payload = {};
756
- const uri = new URL(this.client.config.endpoint + apiPath);
757
- const apiHeaders = {
758
- 'content-type': 'application/json',
759
- };
760
- return await this.client.call('put', uri, apiHeaders, payload);
761
- }
762
- /**
763
- * Create MFA Recovery Codes
764
- *
765
- * Generate recovery codes used as backup for MFA flow for User ID. Recovery codes can be used as a MFA verification type in [createMfaChallenge](/docs/references/cloud/client-web/account#createMfaChallenge) method by client SDK.
766
- *
767
- * @param {string} userId
768
- * @throws {AppcondaException}
769
- * @returns {Promise<Models.MfaRecoveryCodes>}
770
- */
771
- async createMfaRecoveryCodes(userId) {
772
- if (typeof userId === 'undefined') {
773
- throw new AppcondaException('Missing required parameter: "userId"');
774
- }
775
- const apiPath = '/users/{userId}/mfa/recovery-codes'.replace('{userId}', userId);
776
- const payload = {};
777
- const uri = new URL(this.client.config.endpoint + apiPath);
778
- const apiHeaders = {
779
- 'content-type': 'application/json',
780
- };
781
- return await this.client.call('patch', uri, apiHeaders, payload);
782
- }
783
- /**
784
- * Update name
785
- *
786
- * Update the user name by its unique ID.
787
- *
788
- * @param {string} userId
789
- * @param {string} name
790
- * @throws {AppcondaException}
791
- * @returns {Promise<Models.User<Preferences>>}
792
- */
793
- async updateName(userId, name) {
794
- if (typeof userId === 'undefined') {
795
- throw new AppcondaException('Missing required parameter: "userId"');
796
- }
797
- if (typeof name === 'undefined') {
798
- throw new AppcondaException('Missing required parameter: "name"');
799
- }
800
- const apiPath = '/users/{userId}/name'.replace('{userId}', userId);
801
- const payload = {};
802
- if (typeof name !== 'undefined') {
803
- payload['name'] = name;
804
- }
805
- const uri = new URL(this.client.config.endpoint + apiPath);
806
- const apiHeaders = {
807
- 'content-type': 'application/json',
808
- };
809
- return await this.client.call('patch', uri, apiHeaders, payload);
810
- }
811
- /**
812
- * Update password
813
- *
814
- * Update the user password by its unique ID.
815
- *
816
- * @param {string} userId
817
- * @param {string} password
818
- * @throws {AppcondaException}
819
- * @returns {Promise<Models.User<Preferences>>}
820
- */
821
- async updatePassword(userId, password) {
822
- if (typeof userId === 'undefined') {
823
- throw new AppcondaException('Missing required parameter: "userId"');
824
- }
825
- if (typeof password === 'undefined') {
826
- throw new AppcondaException('Missing required parameter: "password"');
827
- }
828
- const apiPath = '/users/{userId}/password'.replace('{userId}', userId);
829
- const payload = {};
830
- if (typeof password !== 'undefined') {
831
- payload['password'] = password;
832
- }
833
- const uri = new URL(this.client.config.endpoint + apiPath);
834
- const apiHeaders = {
835
- 'content-type': 'application/json',
836
- };
837
- return await this.client.call('patch', uri, apiHeaders, payload);
838
- }
839
- /**
840
- * Update phone
841
- *
842
- * Update the user phone by its unique ID.
843
- *
844
- * @param {string} userId
845
- * @param {string} number
846
- * @throws {AppcondaException}
847
- * @returns {Promise<Models.User<Preferences>>}
848
- */
849
- async updatePhone(userId, number) {
850
- if (typeof userId === 'undefined') {
851
- throw new AppcondaException('Missing required parameter: "userId"');
852
- }
853
- if (typeof number === 'undefined') {
854
- throw new AppcondaException('Missing required parameter: "number"');
855
- }
856
- const apiPath = '/users/{userId}/phone'.replace('{userId}', userId);
857
- const payload = {};
858
- if (typeof number !== 'undefined') {
859
- payload['number'] = number;
860
- }
861
- const uri = new URL(this.client.config.endpoint + apiPath);
862
- const apiHeaders = {
863
- 'content-type': 'application/json',
864
- };
865
- return await this.client.call('patch', uri, apiHeaders, payload);
866
- }
867
- /**
868
- * Get user preferences
869
- *
870
- * Get the user preferences by its unique ID.
871
- *
872
- * @param {string} userId
873
- * @throws {AppcondaException}
874
- * @returns {Promise<Preferences>}
875
- */
876
- async getPrefs(userId) {
877
- if (typeof userId === 'undefined') {
878
- throw new AppcondaException('Missing required parameter: "userId"');
879
- }
880
- const apiPath = '/users/{userId}/prefs'.replace('{userId}', userId);
881
- const payload = {};
882
- const uri = new URL(this.client.config.endpoint + apiPath);
883
- const apiHeaders = {
884
- 'content-type': 'application/json',
885
- };
886
- return await this.client.call('get', uri, apiHeaders, payload);
887
- }
888
- /**
889
- * Update user preferences
890
- *
891
- * Update the user preferences by its unique ID. The object you pass is stored as is, and replaces any previous value. The maximum allowed prefs size is 64kB and throws error if exceeded.
892
- *
893
- * @param {string} userId
894
- * @param {object} prefs
895
- * @throws {AppcondaException}
896
- * @returns {Promise<Preferences>}
897
- */
898
- async updatePrefs(userId, prefs) {
899
- if (typeof userId === 'undefined') {
900
- throw new AppcondaException('Missing required parameter: "userId"');
901
- }
902
- if (typeof prefs === 'undefined') {
903
- throw new AppcondaException('Missing required parameter: "prefs"');
904
- }
905
- const apiPath = '/users/{userId}/prefs'.replace('{userId}', userId);
906
- const payload = {};
907
- if (typeof prefs !== 'undefined') {
908
- payload['prefs'] = prefs;
909
- }
910
- const uri = new URL(this.client.config.endpoint + apiPath);
911
- const apiHeaders = {
912
- 'content-type': 'application/json',
913
- };
914
- return await this.client.call('patch', uri, apiHeaders, payload);
915
- }
916
- /**
917
- * List user sessions
918
- *
919
- * Get the user sessions list by its unique ID.
920
- *
921
- * @param {string} userId
922
- * @throws {AppcondaException}
923
- * @returns {Promise<Models.SessionList>}
924
- */
925
- async listSessions(userId) {
926
- if (typeof userId === 'undefined') {
927
- throw new AppcondaException('Missing required parameter: "userId"');
928
- }
929
- const apiPath = '/users/{userId}/sessions'.replace('{userId}', userId);
930
- const payload = {};
931
- const uri = new URL(this.client.config.endpoint + apiPath);
932
- const apiHeaders = {
933
- 'content-type': 'application/json',
934
- };
935
- return await this.client.call('get', uri, apiHeaders, payload);
936
- }
937
- /**
938
- * Create session
939
- *
940
- * Creates a session for a user. Returns an immediately usable session object.
941
-
942
- If you want to generate a token for a custom authentication flow, use the [POST /users/{userId}/tokens](https://appconda.io/docs/server/users#createToken) endpoint.
943
- *
944
- * @param {string} userId
945
- * @throws {AppcondaException}
946
- * @returns {Promise<Models.Session>}
947
- */
948
- async createSession(userId) {
949
- if (typeof userId === 'undefined') {
950
- throw new AppcondaException('Missing required parameter: "userId"');
951
- }
952
- const apiPath = '/users/{userId}/sessions'.replace('{userId}', userId);
953
- const payload = {};
954
- const uri = new URL(this.client.config.endpoint + apiPath);
955
- const apiHeaders = {
956
- 'content-type': 'application/json',
957
- };
958
- return await this.client.call('post', uri, apiHeaders, payload);
959
- }
960
- /**
961
- * Delete user sessions
962
- *
963
- * Delete all user&#039;s sessions by using the user&#039;s unique ID.
964
- *
965
- * @param {string} userId
966
- * @throws {AppcondaException}
967
- * @returns {Promise<{}>}
968
- */
969
- async deleteSessions(userId) {
970
- if (typeof userId === 'undefined') {
971
- throw new AppcondaException('Missing required parameter: "userId"');
972
- }
973
- const apiPath = '/users/{userId}/sessions'.replace('{userId}', userId);
974
- const payload = {};
975
- const uri = new URL(this.client.config.endpoint + apiPath);
976
- const apiHeaders = {
977
- 'content-type': 'application/json',
978
- };
979
- return await this.client.call('delete', uri, apiHeaders, payload);
980
- }
981
- /**
982
- * Delete user session
983
- *
984
- * Delete a user sessions by its unique ID.
985
- *
986
- * @param {string} userId
987
- * @param {string} sessionId
988
- * @throws {AppcondaException}
989
- * @returns {Promise<{}>}
990
- */
991
- async deleteSession(userId, sessionId) {
992
- if (typeof userId === 'undefined') {
993
- throw new AppcondaException('Missing required parameter: "userId"');
994
- }
995
- if (typeof sessionId === 'undefined') {
996
- throw new AppcondaException('Missing required parameter: "sessionId"');
997
- }
998
- const apiPath = '/users/{userId}/sessions/{sessionId}'.replace('{userId}', userId).replace('{sessionId}', sessionId);
999
- const payload = {};
1000
- const uri = new URL(this.client.config.endpoint + apiPath);
1001
- const apiHeaders = {
1002
- 'content-type': 'application/json',
1003
- };
1004
- return await this.client.call('delete', uri, apiHeaders, payload);
1005
- }
1006
- /**
1007
- * Update user status
1008
- *
1009
- * Update the user status by its unique ID. Use this endpoint as an alternative to deleting a user if you want to keep user&#039;s ID reserved.
1010
- *
1011
- * @param {string} userId
1012
- * @param {boolean} status
1013
- * @throws {AppcondaException}
1014
- * @returns {Promise<Models.User<Preferences>>}
1015
- */
1016
- async updateStatus(userId, status) {
1017
- if (typeof userId === 'undefined') {
1018
- throw new AppcondaException('Missing required parameter: "userId"');
1019
- }
1020
- if (typeof status === 'undefined') {
1021
- throw new AppcondaException('Missing required parameter: "status"');
1022
- }
1023
- const apiPath = '/users/{userId}/status'.replace('{userId}', userId);
1024
- const payload = {};
1025
- if (typeof status !== 'undefined') {
1026
- payload['status'] = status;
1027
- }
1028
- const uri = new URL(this.client.config.endpoint + apiPath);
1029
- const apiHeaders = {
1030
- 'content-type': 'application/json',
1031
- };
1032
- return await this.client.call('patch', uri, apiHeaders, payload);
1033
- }
1034
- /**
1035
- * List User Targets
1036
- *
1037
- * List the messaging targets that are associated with a user.
1038
- *
1039
- * @param {string} userId
1040
- * @param {string[]} queries
1041
- * @throws {AppcondaException}
1042
- * @returns {Promise<Models.TargetList>}
1043
- */
1044
- async listTargets(userId, queries) {
1045
- if (typeof userId === 'undefined') {
1046
- throw new AppcondaException('Missing required parameter: "userId"');
1047
- }
1048
- const apiPath = '/users/{userId}/targets'.replace('{userId}', userId);
1049
- const payload = {};
1050
- if (typeof queries !== 'undefined') {
1051
- payload['queries'] = queries;
1052
- }
1053
- const uri = new URL(this.client.config.endpoint + apiPath);
1054
- const apiHeaders = {
1055
- 'content-type': 'application/json',
1056
- };
1057
- return await this.client.call('get', uri, apiHeaders, payload);
1058
- }
1059
- /**
1060
- * Create User Target
1061
- *
1062
- * Create a messaging target.
1063
- *
1064
- * @param {string} userId
1065
- * @param {string} targetId
1066
- * @param {MessagingProviderType} providerType
1067
- * @param {string} identifier
1068
- * @param {string} providerId
1069
- * @param {string} name
1070
- * @throws {AppcondaException}
1071
- * @returns {Promise<Models.Target>}
1072
- */
1073
- async createTarget(userId, targetId, providerType, identifier, providerId, name) {
1074
- if (typeof userId === 'undefined') {
1075
- throw new AppcondaException('Missing required parameter: "userId"');
1076
- }
1077
- if (typeof targetId === 'undefined') {
1078
- throw new AppcondaException('Missing required parameter: "targetId"');
1079
- }
1080
- if (typeof providerType === 'undefined') {
1081
- throw new AppcondaException('Missing required parameter: "providerType"');
1082
- }
1083
- if (typeof identifier === 'undefined') {
1084
- throw new AppcondaException('Missing required parameter: "identifier"');
1085
- }
1086
- const apiPath = '/users/{userId}/targets'.replace('{userId}', userId);
1087
- const payload = {};
1088
- if (typeof targetId !== 'undefined') {
1089
- payload['targetId'] = targetId;
1090
- }
1091
- if (typeof providerType !== 'undefined') {
1092
- payload['providerType'] = providerType;
1093
- }
1094
- if (typeof identifier !== 'undefined') {
1095
- payload['identifier'] = identifier;
1096
- }
1097
- if (typeof providerId !== 'undefined') {
1098
- payload['providerId'] = providerId;
1099
- }
1100
- if (typeof name !== 'undefined') {
1101
- payload['name'] = name;
1102
- }
1103
- const uri = new URL(this.client.config.endpoint + apiPath);
1104
- const apiHeaders = {
1105
- 'content-type': 'application/json',
1106
- };
1107
- return await this.client.call('post', uri, apiHeaders, payload);
1108
- }
1109
- /**
1110
- * Get User Target
1111
- *
1112
- * Get a user&#039;s push notification target by ID.
1113
- *
1114
- * @param {string} userId
1115
- * @param {string} targetId
1116
- * @throws {AppcondaException}
1117
- * @returns {Promise<Models.Target>}
1118
- */
1119
- async getTarget(userId, targetId) {
1120
- if (typeof userId === 'undefined') {
1121
- throw new AppcondaException('Missing required parameter: "userId"');
1122
- }
1123
- if (typeof targetId === 'undefined') {
1124
- throw new AppcondaException('Missing required parameter: "targetId"');
1125
- }
1126
- const apiPath = '/users/{userId}/targets/{targetId}'.replace('{userId}', userId).replace('{targetId}', targetId);
1127
- const payload = {};
1128
- const uri = new URL(this.client.config.endpoint + apiPath);
1129
- const apiHeaders = {
1130
- 'content-type': 'application/json',
1131
- };
1132
- return await this.client.call('get', uri, apiHeaders, payload);
1133
- }
1134
- /**
1135
- * Update User target
1136
- *
1137
- * Update a messaging target.
1138
- *
1139
- * @param {string} userId
1140
- * @param {string} targetId
1141
- * @param {string} identifier
1142
- * @param {string} providerId
1143
- * @param {string} name
1144
- * @throws {AppcondaException}
1145
- * @returns {Promise<Models.Target>}
1146
- */
1147
- async updateTarget(userId, targetId, identifier, providerId, name) {
1148
- if (typeof userId === 'undefined') {
1149
- throw new AppcondaException('Missing required parameter: "userId"');
1150
- }
1151
- if (typeof targetId === 'undefined') {
1152
- throw new AppcondaException('Missing required parameter: "targetId"');
1153
- }
1154
- const apiPath = '/users/{userId}/targets/{targetId}'.replace('{userId}', userId).replace('{targetId}', targetId);
1155
- const payload = {};
1156
- if (typeof identifier !== 'undefined') {
1157
- payload['identifier'] = identifier;
1158
- }
1159
- if (typeof providerId !== 'undefined') {
1160
- payload['providerId'] = providerId;
1161
- }
1162
- if (typeof name !== 'undefined') {
1163
- payload['name'] = name;
1164
- }
1165
- const uri = new URL(this.client.config.endpoint + apiPath);
1166
- const apiHeaders = {
1167
- 'content-type': 'application/json',
1168
- };
1169
- return await this.client.call('patch', uri, apiHeaders, payload);
1170
- }
1171
- /**
1172
- * Delete user target
1173
- *
1174
- * Delete a messaging target.
1175
- *
1176
- * @param {string} userId
1177
- * @param {string} targetId
1178
- * @throws {AppcondaException}
1179
- * @returns {Promise<{}>}
1180
- */
1181
- async deleteTarget(userId, targetId) {
1182
- if (typeof userId === 'undefined') {
1183
- throw new AppcondaException('Missing required parameter: "userId"');
1184
- }
1185
- if (typeof targetId === 'undefined') {
1186
- throw new AppcondaException('Missing required parameter: "targetId"');
1187
- }
1188
- const apiPath = '/users/{userId}/targets/{targetId}'.replace('{userId}', userId).replace('{targetId}', targetId);
1189
- const payload = {};
1190
- const uri = new URL(this.client.config.endpoint + apiPath);
1191
- const apiHeaders = {
1192
- 'content-type': 'application/json',
1193
- };
1194
- return await this.client.call('delete', uri, apiHeaders, payload);
1195
- }
1196
- /**
1197
- * Create token
1198
- *
1199
- * Returns a token with a secret key for creating a session. Use the user ID and secret and submit a request to the [PUT /account/sessions/token](https://appconda.io/docs/references/cloud/client-web/account#createSession) endpoint to complete the login process.
1200
-
1201
- *
1202
- * @param {string} userId
1203
- * @param {number} length
1204
- * @param {number} expire
1205
- * @throws {AppcondaException}
1206
- * @returns {Promise<Models.Token>}
1207
- */
1208
- async createToken(userId, length, expire) {
1209
- if (typeof userId === 'undefined') {
1210
- throw new AppcondaException('Missing required parameter: "userId"');
1211
- }
1212
- const apiPath = '/users/{userId}/tokens'.replace('{userId}', userId);
1213
- const payload = {};
1214
- if (typeof length !== 'undefined') {
1215
- payload['length'] = length;
1216
- }
1217
- if (typeof expire !== 'undefined') {
1218
- payload['expire'] = expire;
1219
- }
1220
- const uri = new URL(this.client.config.endpoint + apiPath);
1221
- const apiHeaders = {
1222
- 'content-type': 'application/json',
1223
- };
1224
- return await this.client.call('post', uri, apiHeaders, payload);
1225
- }
1226
- /**
1227
- * Update email verification
1228
- *
1229
- * Update the user email verification status by its unique ID.
1230
- *
1231
- * @param {string} userId
1232
- * @param {boolean} emailVerification
1233
- * @throws {AppcondaException}
1234
- * @returns {Promise<Models.User<Preferences>>}
1235
- */
1236
- async updateEmailVerification(userId, emailVerification) {
1237
- if (typeof userId === 'undefined') {
1238
- throw new AppcondaException('Missing required parameter: "userId"');
1239
- }
1240
- if (typeof emailVerification === 'undefined') {
1241
- throw new AppcondaException('Missing required parameter: "emailVerification"');
1242
- }
1243
- const apiPath = '/users/{userId}/verification'.replace('{userId}', userId);
1244
- const payload = {};
1245
- if (typeof emailVerification !== 'undefined') {
1246
- payload['emailVerification'] = emailVerification;
1247
- }
1248
- const uri = new URL(this.client.config.endpoint + apiPath);
1249
- const apiHeaders = {
1250
- 'content-type': 'application/json',
1251
- };
1252
- return await this.client.call('patch', uri, apiHeaders, payload);
1253
- }
1254
- /**
1255
- * Update phone verification
1256
- *
1257
- * Update the user phone verification status by its unique ID.
1258
- *
1259
- * @param {string} userId
1260
- * @param {boolean} phoneVerification
1261
- * @throws {AppcondaException}
1262
- * @returns {Promise<Models.User<Preferences>>}
1263
- */
1264
- async updatePhoneVerification(userId, phoneVerification) {
1265
- if (typeof userId === 'undefined') {
1266
- throw new AppcondaException('Missing required parameter: "userId"');
1267
- }
1268
- if (typeof phoneVerification === 'undefined') {
1269
- throw new AppcondaException('Missing required parameter: "phoneVerification"');
1270
- }
1271
- const apiPath = '/users/{userId}/verification/phone'.replace('{userId}', userId);
1272
- const payload = {};
1273
- if (typeof phoneVerification !== 'undefined') {
1274
- payload['phoneVerification'] = phoneVerification;
1275
- }
1276
- const uri = new URL(this.client.config.endpoint + apiPath);
1277
- const apiHeaders = {
1278
- 'content-type': 'application/json',
1279
- };
1280
- return await this.client.call('patch', uri, apiHeaders, payload);
1281
- }
1282
- }
1283
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VydmljZXMvdXNlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGlCQUFpQixFQUF3QyxNQUFNLFdBQVcsQ0FBQztBQU1wRixNQUFNLE9BQU8sS0FBSztJQUdkLFlBQVksTUFBYztRQUN0QixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztJQUN6QixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0gsS0FBSyxDQUFDLElBQUksQ0FBeUMsT0FBa0IsRUFBRSxNQUFlO1FBQ2xGLE1BQU0sT0FBTyxHQUFHLFFBQVEsQ0FBQztRQUN6QixNQUFNLE9BQU8sR0FBWSxFQUFFLENBQUM7UUFDNUIsSUFBSSxPQUFPLE9BQU8sS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNqQyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsT0FBTyxDQUFDO1FBQ2pDLENBQUM7UUFDRCxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUM7UUFDL0IsQ0FBQztRQUNELE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixLQUFLLEVBQ0wsR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSCxLQUFLLENBQUMsTUFBTSxDQUF5QyxNQUFjLEVBQUUsS0FBYyxFQUFFLEtBQWMsRUFBRSxRQUFpQixFQUFFLElBQWE7UUFDakksSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNoQyxNQUFNLElBQUksaUJBQWlCLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUM7UUFDL0IsQ0FBQztRQUNELElBQUksT0FBTyxLQUFLLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDL0IsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEtBQUssQ0FBQztRQUM3QixDQUFDO1FBQ0QsSUFBSSxPQUFPLEtBQUssS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMvQixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQzdCLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxRQUFRLENBQUM7UUFDbkMsQ0FBQztRQUNELElBQUksT0FBTyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDOUIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQztRQUMzQixDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLE1BQU0sRUFDTixHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7Ozs7OztPQVdHO0lBQ0gsS0FBSyxDQUFDLGdCQUFnQixDQUF5QyxNQUFjLEVBQUUsS0FBYSxFQUFFLFFBQWdCLEVBQUUsSUFBYTtRQUN6SCxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQzFFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUM7UUFDaEMsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUMvQixDQUFDO1FBQ0QsSUFBSSxPQUFPLEtBQUssS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMvQixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQzdCLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxRQUFRLENBQUM7UUFDbkMsQ0FBQztRQUNELElBQUksT0FBTyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDOUIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQztRQUMzQixDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLE1BQU0sRUFDTixHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7Ozs7OztPQVdHO0lBQ0gsS0FBSyxDQUFDLGdCQUFnQixDQUF5QyxNQUFjLEVBQUUsS0FBYSxFQUFFLFFBQWdCLEVBQUUsSUFBYTtRQUN6SCxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQzFFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUM7UUFDaEMsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUMvQixDQUFDO1FBQ0QsSUFBSSxPQUFPLEtBQUssS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMvQixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQzdCLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxRQUFRLENBQUM7UUFDbkMsQ0FBQztRQUNELElBQUksT0FBTyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDOUIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQztRQUMzQixDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLE1BQU0sRUFDTixHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7Ozs7T0FTRztJQUNILEtBQUssQ0FBQyxjQUFjLENBQUMsT0FBa0IsRUFBRSxNQUFlO1FBQ3BELE1BQU0sT0FBTyxHQUFHLG1CQUFtQixDQUFDO1FBQ3BDLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixJQUFJLE9BQU8sT0FBTyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2pDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxPQUFPLENBQUM7UUFDakMsQ0FBQztRQUNELElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUMvQixDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLEtBQUssRUFDTCxHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLGNBQWMsQ0FBQyxVQUFrQjtRQUNuQyxJQUFJLE9BQU8sVUFBVSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQywwQ0FBMEMsQ0FBQyxDQUFDO1FBQzVFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxnQ0FBZ0MsQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ3JGLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsUUFBUSxFQUNSLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7Ozs7O09BV0c7SUFDSCxLQUFLLENBQUMsYUFBYSxDQUF5QyxNQUFjLEVBQUUsS0FBYSxFQUFFLFFBQWdCLEVBQUUsSUFBYTtRQUN0SCxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQzFFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUM7UUFDN0IsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUMvQixDQUFDO1FBQ0QsSUFBSSxPQUFPLEtBQUssS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMvQixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQzdCLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxRQUFRLENBQUM7UUFDbkMsQ0FBQztRQUNELElBQUksT0FBTyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDOUIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQztRQUMzQixDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLE1BQU0sRUFDTixHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7Ozs7OztPQVdHO0lBQ0gsS0FBSyxDQUFDLGdCQUFnQixDQUF5QyxNQUFjLEVBQUUsS0FBYSxFQUFFLFFBQWdCLEVBQUUsSUFBYTtRQUN6SCxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQzFFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxlQUFlLENBQUM7UUFDaEMsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUMvQixDQUFDO1FBQ0QsSUFBSSxPQUFPLEtBQUssS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMvQixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQzdCLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxRQUFRLENBQUM7UUFDbkMsQ0FBQztRQUNELElBQUksT0FBTyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDOUIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQztRQUMzQixDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLE1BQU0sRUFDTixHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7Ozs7Ozs7Ozs7O09BZ0JHO0lBQ0gsS0FBSyxDQUFDLGdCQUFnQixDQUF5QyxNQUFjLEVBQUUsS0FBYSxFQUFFLFFBQWdCLEVBQUUsWUFBb0IsRUFBRSxXQUFtQixFQUFFLGNBQXNCLEVBQUUsZ0JBQXdCLEVBQUUsY0FBc0IsRUFBRSxJQUFhO1FBQzlPLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELElBQUksT0FBTyxLQUFLLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDL0IsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHFDQUFxQyxDQUFDLENBQUM7UUFDdkUsQ0FBQztRQUNELElBQUksT0FBTyxRQUFRLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDbEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHdDQUF3QyxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUNELElBQUksT0FBTyxZQUFZLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDdEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLDRDQUE0QyxDQUFDLENBQUM7UUFDOUUsQ0FBQztRQUNELElBQUksT0FBTyxXQUFXLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDckMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLDJDQUEyQyxDQUFDLENBQUM7UUFDN0UsQ0FBQztRQUNELElBQUksT0FBTyxjQUFjLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDeEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLDhDQUE4QyxDQUFDLENBQUM7UUFDaEYsQ0FBQztRQUNELElBQUksT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMxQyxNQUFNLElBQUksaUJBQWlCLENBQUMsZ0RBQWdELENBQUMsQ0FBQztRQUNsRixDQUFDO1FBQ0QsSUFBSSxPQUFPLGNBQWMsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUN4QyxNQUFNLElBQUksaUJBQWlCLENBQUMsOENBQThDLENBQUMsQ0FBQztRQUNoRixDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsZUFBZSxDQUFDO1FBQ2hDLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUM7UUFDL0IsQ0FBQztRQUNELElBQUksT0FBTyxLQUFLLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDL0IsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEtBQUssQ0FBQztRQUM3QixDQUFDO1FBQ0QsSUFBSSxPQUFPLFFBQVEsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNsQyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsUUFBUSxDQUFDO1FBQ25DLENBQUM7UUFDRCxJQUFJLE9BQU8sWUFBWSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ3RDLE9BQU8sQ0FBQyxjQUFjLENBQUMsR0FBRyxZQUFZLENBQUM7UUFDM0MsQ0FBQztRQUNELElBQUksT0FBTyxXQUFXLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDckMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxHQUFHLFdBQVcsQ0FBQztRQUN6QyxDQUFDO1FBQ0QsSUFBSSxPQUFPLGNBQWMsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUN4QyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxjQUFjLENBQUM7UUFDL0MsQ0FBQztRQUNELElBQUksT0FBTyxnQkFBZ0IsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMxQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQztRQUNuRCxDQUFDO1FBQ0QsSUFBSSxPQUFPLGNBQWMsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUN4QyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxjQUFjLENBQUM7UUFDL0MsQ0FBQztRQUNELElBQUksT0FBTyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDOUIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQztRQUMzQixDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLE1BQU0sRUFDTixHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7Ozs7Ozs7OztPQWNHO0lBQ0gsS0FBSyxDQUFDLHdCQUF3QixDQUF5QyxNQUFjLEVBQUUsS0FBYSxFQUFFLFFBQWdCLEVBQUUsWUFBb0IsRUFBRSxxQkFBNkIsRUFBRSxpQkFBeUIsRUFBRSxJQUFhO1FBQ2pOLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELElBQUksT0FBTyxLQUFLLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDL0IsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHFDQUFxQyxDQUFDLENBQUM7UUFDdkUsQ0FBQztRQUNELElBQUksT0FBTyxRQUFRLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDbEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHdDQUF3QyxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUNELElBQUksT0FBTyxZQUFZLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDdEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLDRDQUE0QyxDQUFDLENBQUM7UUFDOUUsQ0FBQztRQUNELElBQUksT0FBTyxxQkFBcUIsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMvQyxNQUFNLElBQUksaUJBQWlCLENBQUMscURBQXFELENBQUMsQ0FBQztRQUN2RixDQUFDO1FBQ0QsSUFBSSxPQUFPLGlCQUFpQixLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQzNDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxpREFBaUQsQ0FBQyxDQUFDO1FBQ25GLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyx3QkFBd0IsQ0FBQztRQUN6QyxNQUFNLE9BQU8sR0FBWSxFQUFFLENBQUM7UUFDNUIsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNoQyxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLENBQUM7UUFDRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQy9CLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUM7UUFDN0IsQ0FBQztRQUNELElBQUksT0FBTyxRQUFRLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDbEMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLFFBQVEsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsSUFBSSxPQUFPLFlBQVksS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUN0QyxPQUFPLENBQUMsY0FBYyxDQUFDLEdBQUcsWUFBWSxDQUFDO1FBQzNDLENBQUM7UUFDRCxJQUFJLE9BQU8scUJBQXFCLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDL0MsT0FBTyxDQUFDLHVCQUF1QixDQUFDLEdBQUcscUJBQXFCLENBQUM7UUFDN0QsQ0FBQztRQUNELElBQUksT0FBTyxpQkFBaUIsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMzQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsR0FBRyxpQkFBaUIsQ0FBQztRQUNyRCxDQUFDO1FBQ0QsSUFBSSxPQUFPLElBQUksS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUM5QixPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQzNCLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsTUFBTSxFQUNOLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0gsS0FBSyxDQUFDLGFBQWEsQ0FBeUMsTUFBYyxFQUFFLEtBQWEsRUFBRSxRQUFnQixFQUFFLGVBQThCLEVBQUUsSUFBYTtRQUN0SixJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQzFFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUM7UUFDN0IsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUMvQixDQUFDO1FBQ0QsSUFBSSxPQUFPLEtBQUssS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMvQixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQzdCLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRyxRQUFRLENBQUM7UUFDbkMsQ0FBQztRQUNELElBQUksT0FBTyxlQUFlLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDekMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsZUFBZSxDQUFDO1FBQ2pELENBQUM7UUFDRCxJQUFJLE9BQU8sSUFBSSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQzlCLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUM7UUFDM0IsQ0FBQztRQUNELE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixNQUFNLEVBQ04sR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7T0FRRztJQUNILEtBQUssQ0FBQyxHQUFHLENBQXlDLE1BQWM7UUFDNUQsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNoQyxNQUFNLElBQUksaUJBQWlCLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsaUJBQWlCLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUM5RCxNQUFNLE9BQU8sR0FBWSxFQUFFLENBQUM7UUFDNUIsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLEtBQUssRUFDTCxHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFjO1FBQ3ZCLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDOUQsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixRQUFRLEVBQ1IsR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7O09BU0c7SUFDSCxLQUFLLENBQUMsV0FBVyxDQUF5QyxNQUFjLEVBQUUsS0FBYTtRQUNuRixJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQy9CLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxxQ0FBcUMsQ0FBQyxDQUFDO1FBQ3ZFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyx1QkFBdUIsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixJQUFJLE9BQU8sS0FBSyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQy9CLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUM7UUFDN0IsQ0FBQztRQUNELE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixPQUFPLEVBQ1AsR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7OztPQVVHO0lBQ0gsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFjLEVBQUUsU0FBa0IsRUFBRSxRQUFpQjtRQUNqRSxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ25FLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixJQUFJLE9BQU8sU0FBUyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ25DLE9BQU8sQ0FBQyxXQUFXLENBQUMsR0FBRyxTQUFTLENBQUM7UUFDckMsQ0FBQztRQUNELElBQUksT0FBTyxRQUFRLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDbEMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLFFBQVEsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLE1BQU0sRUFDTixHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7Ozs7OztPQVdHO0lBQ0gsS0FBSyxDQUFDLFlBQVksQ0FBeUMsTUFBYyxFQUFFLE1BQWdCO1FBQ3ZGLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDckUsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUMvQixDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLEtBQUssRUFDTCxHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7Ozs7T0FTRztJQUNILEtBQUssQ0FBQyxRQUFRLENBQUMsTUFBYyxFQUFFLE9BQWtCO1FBQzdDLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLHNCQUFzQixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDbkUsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLElBQUksT0FBTyxPQUFPLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDakMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLE9BQU8sQ0FBQztRQUNqQyxDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLEtBQUssRUFDTCxHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLGVBQWUsQ0FBQyxNQUFjO1FBQ2hDLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLDZCQUE2QixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDMUUsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixLQUFLLEVBQ0wsR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7O09BU0c7SUFDSCxLQUFLLENBQUMsU0FBUyxDQUF5QyxNQUFjLEVBQUUsR0FBWTtRQUNoRixJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLE9BQU8sR0FBRyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQzdCLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO1FBQ3JFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxxQkFBcUIsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2xFLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixJQUFJLE9BQU8sR0FBRyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQzdCLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxHQUFHLENBQUM7UUFDekIsQ0FBQztRQUNELE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixPQUFPLEVBQ1AsR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7O09BU0c7SUFDSCxLQUFLLENBQUMsc0JBQXNCLENBQXlDLE1BQWMsRUFBRSxJQUF1QjtRQUN4RyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLE9BQU8sSUFBSSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQzlCLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRywyQ0FBMkMsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDaEgsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixRQUFRLEVBQ1IsR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7T0FRRztJQUNILEtBQUssQ0FBQyxjQUFjLENBQUMsTUFBYztRQUMvQixJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyw2QkFBNkIsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzFFLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsS0FBSyxFQUNMLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7O09BUUc7SUFDSCxLQUFLLENBQUMsbUJBQW1CLENBQUMsTUFBYztRQUNwQyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxvQ0FBb0MsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2pGLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsS0FBSyxFQUNMLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7O09BUUc7SUFDSCxLQUFLLENBQUMsc0JBQXNCLENBQUMsTUFBYztRQUN2QyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxvQ0FBb0MsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2pGLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsS0FBSyxFQUNMLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7O09BUUc7SUFDSCxLQUFLLENBQUMsc0JBQXNCLENBQUMsTUFBYztRQUN2QyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxvQ0FBb0MsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2pGLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsT0FBTyxFQUNQLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7OztPQVNHO0lBQ0gsS0FBSyxDQUFDLFVBQVUsQ0FBeUMsTUFBYyxFQUFFLElBQVk7UUFDakYsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNoQyxNQUFNLElBQUksaUJBQWlCLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsSUFBSSxPQUFPLElBQUksS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUM5QixNQUFNLElBQUksaUJBQWlCLENBQUMsb0NBQW9DLENBQUMsQ0FBQztRQUN0RSxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsc0JBQXNCLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNuRSxNQUFNLE9BQU8sR0FBWSxFQUFFLENBQUM7UUFDNUIsSUFBSSxPQUFPLElBQUksS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUM5QixPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQzNCLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsT0FBTyxFQUNQLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7OztPQVNHO0lBQ0gsS0FBSyxDQUFDLGNBQWMsQ0FBeUMsTUFBYyxFQUFFLFFBQWdCO1FBQ3pGLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELElBQUksT0FBTyxRQUFRLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDbEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHdDQUF3QyxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLDBCQUEwQixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDdkUsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLElBQUksT0FBTyxRQUFRLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDbEMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLFFBQVEsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLE9BQU8sRUFDUCxHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7Ozs7T0FTRztJQUNILEtBQUssQ0FBQyxXQUFXLENBQXlDLE1BQWMsRUFBRSxNQUFjO1FBQ3BGLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDcEUsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUMvQixDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLE9BQU8sRUFDUCxHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLFFBQVEsQ0FBeUMsTUFBYztRQUNqRSxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyx1QkFBdUIsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsS0FBSyxFQUNMLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7OztPQVNHO0lBQ0gsS0FBSyxDQUFDLFdBQVcsQ0FBeUMsTUFBYyxFQUFFLEtBQWE7UUFDbkYsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNoQyxNQUFNLElBQUksaUJBQWlCLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsSUFBSSxPQUFPLEtBQUssS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMvQixNQUFNLElBQUksaUJBQWlCLENBQUMscUNBQXFDLENBQUMsQ0FBQztRQUN2RSxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsdUJBQXVCLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNwRSxNQUFNLE9BQU8sR0FBWSxFQUFFLENBQUM7UUFDNUIsSUFBSSxPQUFPLEtBQUssS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMvQixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQzdCLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsT0FBTyxFQUNQLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7O09BUUc7SUFDSCxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQWM7UUFDN0IsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNoQyxNQUFNLElBQUksaUJBQWlCLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsMEJBQTBCLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN2RSxNQUFNLE9BQU8sR0FBWSxFQUFFLENBQUM7UUFDNUIsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLEtBQUssRUFDTCxHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7Ozs7O09BVUc7SUFDSCxLQUFLLENBQUMsYUFBYSxDQUFDLE1BQWM7UUFDOUIsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNoQyxNQUFNLElBQUksaUJBQWlCLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsMEJBQTBCLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN2RSxNQUFNLE9BQU8sR0FBWSxFQUFFLENBQUM7UUFDNUIsTUFBTSxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBRTNELE1BQU0sVUFBVSxHQUFpQztZQUM3QyxjQUFjLEVBQUUsa0JBQWtCO1NBQ3JDLENBQUE7UUFFRCxPQUFPLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3pCLE1BQU0sRUFDTixHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sQ0FDVixDQUFDO0lBQ04sQ0FBQztJQUNEOzs7Ozs7OztPQVFHO0lBQ0gsS0FBSyxDQUFDLGNBQWMsQ0FBQyxNQUFjO1FBQy9CLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLDBCQUEwQixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDdkUsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixRQUFRLEVBQ1IsR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7O09BU0c7SUFDSCxLQUFLLENBQUMsYUFBYSxDQUFDLE1BQWMsRUFBRSxTQUFpQjtRQUNqRCxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLE9BQU8sU0FBUyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ25DLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDO1FBQzNFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxzQ0FBc0MsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDckgsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixRQUFRLEVBQ1IsR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7O09BU0c7SUFDSCxLQUFLLENBQUMsWUFBWSxDQUF5QyxNQUFjLEVBQUUsTUFBZTtRQUN0RixJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3JFLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxNQUFNLENBQUM7UUFDL0IsQ0FBQztRQUNELE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixPQUFPLEVBQ1AsR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7O09BU0c7SUFDSCxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQWMsRUFBRSxPQUFrQjtRQUNoRCxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyx5QkFBeUIsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixJQUFJLE9BQU8sT0FBTyxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2pDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxPQUFPLENBQUM7UUFDakMsQ0FBQztRQUNELE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixLQUFLLEVBQ0wsR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFjLEVBQUUsUUFBZ0IsRUFBRSxZQUFtQyxFQUFFLFVBQWtCLEVBQUUsVUFBbUIsRUFBRSxJQUFhO1FBQzVJLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELElBQUksT0FBTyxRQUFRLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDbEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHdDQUF3QyxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUNELElBQUksT0FBTyxZQUFZLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDdEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLDRDQUE0QyxDQUFDLENBQUM7UUFDOUUsQ0FBQztRQUNELElBQUksT0FBTyxVQUFVLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDcEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLDBDQUEwQyxDQUFDLENBQUM7UUFDNUUsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLHlCQUF5QixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDdEUsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLElBQUksT0FBTyxRQUFRLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDbEMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxHQUFHLFFBQVEsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsSUFBSSxPQUFPLFlBQVksS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUN0QyxPQUFPLENBQUMsY0FBYyxDQUFDLEdBQUcsWUFBWSxDQUFDO1FBQzNDLENBQUM7UUFDRCxJQUFJLE9BQU8sVUFBVSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ3BDLE9BQU8sQ0FBQyxZQUFZLENBQUMsR0FBRyxVQUFVLENBQUM7UUFDdkMsQ0FBQztRQUNELElBQUksT0FBTyxVQUFVLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDcEMsT0FBTyxDQUFDLFlBQVksQ0FBQyxHQUFHLFVBQVUsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsSUFBSSxPQUFPLElBQUksS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUM5QixPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQzNCLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsTUFBTSxFQUNOLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7OztPQVNHO0lBQ0gsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFjLEVBQUUsUUFBZ0I7UUFDNUMsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNoQyxNQUFNLElBQUksaUJBQWlCLENBQUMsc0NBQXNDLENBQUMsQ0FBQztRQUN4RSxDQUFDO1FBQ0QsSUFBSSxPQUFPLFFBQVEsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNsQyxNQUFNLElBQUksaUJBQWlCLENBQUMsd0NBQXdDLENBQUMsQ0FBQztRQUMxRSxDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsb0NBQW9DLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ2pILE1BQU0sT0FBTyxHQUFZLEVBQUUsQ0FBQztRQUM1QixNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsS0FBSyxFQUNMLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0gsS0FBSyxDQUFDLFlBQVksQ0FBQyxNQUFjLEVBQUUsUUFBZ0IsRUFBRSxVQUFtQixFQUFFLFVBQW1CLEVBQUUsSUFBYTtRQUN4RyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQzFFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxvQ0FBb0MsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDakgsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLElBQUksT0FBTyxVQUFVLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDcEMsT0FBTyxDQUFDLFlBQVksQ0FBQyxHQUFHLFVBQVUsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsSUFBSSxPQUFPLFVBQVUsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNwQyxPQUFPLENBQUMsWUFBWSxDQUFDLEdBQUcsVUFBVSxDQUFDO1FBQ3ZDLENBQUM7UUFDRCxJQUFJLE9BQU8sSUFBSSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQzlCLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUM7UUFDM0IsQ0FBQztRQUNELE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixPQUFPLEVBQ1AsR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7O09BU0c7SUFDSCxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQWMsRUFBRSxRQUFnQjtRQUMvQyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFDRCxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQ2xDLE1BQU0sSUFBSSxpQkFBaUIsQ0FBQyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQzFFLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxvQ0FBb0MsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDakgsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUUzRCxNQUFNLFVBQVUsR0FBaUM7WUFDN0MsY0FBYyxFQUFFLGtCQUFrQjtTQUNyQyxDQUFBO1FBRUQsT0FBTyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixRQUFRLEVBQ1IsR0FBRyxFQUNILFVBQVUsRUFDVixPQUFPLENBQ1YsQ0FBQztJQUNOLENBQUM7SUFDRDs7Ozs7Ozs7Ozs7T0FXRztJQUNILEtBQUssQ0FBQyxXQUFXLENBQUMsTUFBYyxFQUFFLE1BQWUsRUFBRSxNQUFlO1FBQzlELElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDckUsTUFBTSxPQUFPLEdBQVksRUFBRSxDQUFDO1FBQzVCLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLE1BQU0sQ0FBQztRQUMvQixDQUFDO1FBQ0QsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUNoQyxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDO1FBQy9CLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsTUFBTSxFQUNOLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7OztPQVNHO0lBQ0gsS0FBSyxDQUFDLHVCQUF1QixDQUF5QyxNQUFjLEVBQUUsaUJBQTBCO1FBQzVHLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELElBQUksT0FBTyxpQkFBaUIsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMzQyxNQUFNLElBQUksaUJBQWlCLENBQUMsaURBQWlELENBQUMsQ0FBQztRQUNuRixDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsOEJBQThCLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMzRSxNQUFNLE9BQU8sR0FBWSxFQUFFLENBQUM7UUFDNUIsSUFBSSxPQUFPLGlCQUFpQixLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQzNDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLGlCQUFpQixDQUFDO1FBQ3JELENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsT0FBTyxFQUNQLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0lBQ0Q7Ozs7Ozs7OztPQVNHO0lBQ0gsS0FBSyxDQUFDLHVCQUF1QixDQUF5QyxNQUFjLEVBQUUsaUJBQTBCO1FBQzVHLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLGlCQUFpQixDQUFDLHNDQUFzQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztRQUNELElBQUksT0FBTyxpQkFBaUIsS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMzQyxNQUFNLElBQUksaUJBQWlCLENBQUMsaURBQWlELENBQUMsQ0FBQztRQUNuRixDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsb0NBQW9DLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNqRixNQUFNLE9BQU8sR0FBWSxFQUFFLENBQUM7UUFDNUIsSUFBSSxPQUFPLGlCQUFpQixLQUFLLFdBQVcsRUFBRSxDQUFDO1lBQzNDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLGlCQUFpQixDQUFDO1FBQ3JELENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFFM0QsTUFBTSxVQUFVLEdBQWlDO1lBQzdDLGNBQWMsRUFBRSxrQkFBa0I7U0FDckMsQ0FBQTtRQUVELE9BQU8sTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsT0FBTyxFQUNQLEdBQUcsRUFDSCxVQUFVLEVBQ1YsT0FBTyxDQUNWLENBQUM7SUFDTixDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBcHBjb25kYUV4Y2VwdGlvbiwgQ2xpZW50LCB0eXBlIFBheWxvYWQsIFVwbG9hZFByb2dyZXNzIH0gZnJvbSAnLi4vY2xpZW50JztcbmltcG9ydCB0eXBlIHsgTW9kZWxzIH0gZnJvbSAnLi4vbW9kZWxzJztcbmltcG9ydCB7IFBhc3N3b3JkSGFzaCB9IGZyb20gJy4uL2VudW1zL3Bhc3N3b3JkLWhhc2gnO1xuaW1wb3J0IHsgQXV0aGVudGljYXRvclR5cGUgfSBmcm9tICcuLi9tb2R1bGVzL2FjY291bnQvZW51bXMvYXV0aGVudGljYXRvci10eXBlJztcbmltcG9ydCB7IE1lc3NhZ2luZ1Byb3ZpZGVyVHlwZSB9IGZyb20gJy4uL2VudW1zL21lc3NhZ2luZy1wcm92aWRlci10eXBlJztcblxuZXhwb3J0IGNsYXNzIFVzZXJzIHtcbiAgICBjbGllbnQ6IENsaWVudDtcblxuICAgIGNvbnN0cnVjdG9yKGNsaWVudDogQ2xpZW50KSB7XG4gICAgICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExpc3QgdXNlcnNcbiAgICAgKlxuICAgICAqIEdldCBhIGxpc3Qgb2YgYWxsIHRoZSBwcm9qZWN0JiMwMzk7cyB1c2Vycy4gWW91IGNhbiB1c2UgdGhlIHF1ZXJ5IHBhcmFtcyB0byBmaWx0ZXIgeW91ciByZXN1bHRzLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gcXVlcmllc1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzZWFyY2hcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVXNlckxpc3Q8UHJlZmVyZW5jZXM+Pn1cbiAgICAgKi9cbiAgICBhc3luYyBsaXN0PFByZWZlcmVuY2VzIGV4dGVuZHMgTW9kZWxzLlByZWZlcmVuY2VzPihxdWVyaWVzPzogc3RyaW5nW10sIHNlYXJjaD86IHN0cmluZyk6IFByb21pc2U8TW9kZWxzLlVzZXJMaXN0PFByZWZlcmVuY2VzPj4ge1xuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycyc7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiBxdWVyaWVzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsncXVlcmllcyddID0gcXVlcmllcztcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHNlYXJjaCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ3NlYXJjaCddID0gc2VhcmNoO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVyaSA9IG5ldyBVUkwodGhpcy5jbGllbnQuY29uZmlnLmVuZHBvaW50ICsgYXBpUGF0aCk7XG5cbiAgICAgICAgY29uc3QgYXBpSGVhZGVyczogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuY2FsbChcbiAgICAgICAgICAgICdnZXQnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSB1c2VyXG4gICAgICpcbiAgICAgKiBDcmVhdGUgYSBuZXcgdXNlci5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZW1haWxcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGhvbmVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFzc3dvcmRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj59XG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlPFByZWZlcmVuY2VzIGV4dGVuZHMgTW9kZWxzLlByZWZlcmVuY2VzPih1c2VySWQ6IHN0cmluZywgZW1haWw/OiBzdHJpbmcsIHBob25lPzogc3RyaW5nLCBwYXNzd29yZD86IHN0cmluZywgbmFtZT86IHN0cmluZyk6IFByb21pc2U8TW9kZWxzLlVzZXI8UHJlZmVyZW5jZXM+PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzJztcbiAgICAgICAgY29uc3QgcGF5bG9hZDogUGF5bG9hZCA9IHt9O1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ3VzZXJJZCddID0gdXNlcklkO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZW1haWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydlbWFpbCddID0gZW1haWw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwaG9uZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ3Bob25lJ10gPSBwaG9uZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhc3N3b3JkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsncGFzc3dvcmQnXSA9IHBhc3N3b3JkO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ25hbWUnXSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ3Bvc3QnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSB1c2VyIHdpdGggQXJnb24yIHBhc3N3b3JkXG4gICAgICpcbiAgICAgKiBDcmVhdGUgYSBuZXcgdXNlci4gUGFzc3dvcmQgcHJvdmlkZWQgbXVzdCBiZSBoYXNoZWQgd2l0aCB0aGUgW0FyZ29uMl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQXJnb24yKSBhbGdvcml0aG0uIFVzZSB0aGUgW1BPU1QgL3VzZXJzXShodHRwczovL2FwcGNvbmRhLmlvL2RvY3Mvc2VydmVyL3VzZXJzI3VzZXJzQ3JlYXRlKSBlbmRwb2ludCB0byBjcmVhdGUgdXNlcnMgd2l0aCBhIHBsYWluIHRleHQgcGFzc3dvcmQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGVtYWlsXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+fVxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZUFyZ29uMlVzZXI8UHJlZmVyZW5jZXMgZXh0ZW5kcyBNb2RlbHMuUHJlZmVyZW5jZXM+KHVzZXJJZDogc3RyaW5nLCBlbWFpbDogc3RyaW5nLCBwYXNzd29yZDogc3RyaW5nLCBuYW1lPzogc3RyaW5nKTogUHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBlbWFpbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwiZW1haWxcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInBhc3N3b3JkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy9hcmdvbjInO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsndXNlcklkJ10gPSB1c2VySWQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBlbWFpbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ2VtYWlsJ10gPSBlbWFpbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhc3N3b3JkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsncGFzc3dvcmQnXSA9IHBhc3N3b3JkO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ25hbWUnXSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ3Bvc3QnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSB1c2VyIHdpdGggYmNyeXB0IHBhc3N3b3JkXG4gICAgICpcbiAgICAgKiBDcmVhdGUgYSBuZXcgdXNlci4gUGFzc3dvcmQgcHJvdmlkZWQgbXVzdCBiZSBoYXNoZWQgd2l0aCB0aGUgW0JjcnlwdF0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQmNyeXB0KSBhbGdvcml0aG0uIFVzZSB0aGUgW1BPU1QgL3VzZXJzXShodHRwczovL2FwcGNvbmRhLmlvL2RvY3Mvc2VydmVyL3VzZXJzI3VzZXJzQ3JlYXRlKSBlbmRwb2ludCB0byBjcmVhdGUgdXNlcnMgd2l0aCBhIHBsYWluIHRleHQgcGFzc3dvcmQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGVtYWlsXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+fVxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZUJjcnlwdFVzZXI8UHJlZmVyZW5jZXMgZXh0ZW5kcyBNb2RlbHMuUHJlZmVyZW5jZXM+KHVzZXJJZDogc3RyaW5nLCBlbWFpbDogc3RyaW5nLCBwYXNzd29yZDogc3RyaW5nLCBuYW1lPzogc3RyaW5nKTogUHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBlbWFpbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwiZW1haWxcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInBhc3N3b3JkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy9iY3J5cHQnO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsndXNlcklkJ10gPSB1c2VySWQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBlbWFpbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ2VtYWlsJ10gPSBlbWFpbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhc3N3b3JkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsncGFzc3dvcmQnXSA9IHBhc3N3b3JkO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ25hbWUnXSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ3Bvc3QnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExpc3QgSWRlbnRpdGllc1xuICAgICAqXG4gICAgICogR2V0IGlkZW50aXRpZXMgZm9yIGFsbCB1c2Vycy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IHF1ZXJpZXNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc2VhcmNoXG4gICAgICogQHRocm93cyB7QXBwY29uZGFFeGNlcHRpb259XG4gICAgICogQHJldHVybnMge1Byb21pc2U8TW9kZWxzLklkZW50aXR5TGlzdD59XG4gICAgICovXG4gICAgYXN5bmMgbGlzdElkZW50aXRpZXMocXVlcmllcz86IHN0cmluZ1tdLCBzZWFyY2g/OiBzdHJpbmcpOiBQcm9taXNlPE1vZGVscy5JZGVudGl0eUxpc3Q+IHtcbiAgICAgICAgY29uc3QgYXBpUGF0aCA9ICcvdXNlcnMvaWRlbnRpdGllcyc7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiBxdWVyaWVzICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsncXVlcmllcyddID0gcXVlcmllcztcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHNlYXJjaCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ3NlYXJjaCddID0gc2VhcmNoO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVyaSA9IG5ldyBVUkwodGhpcy5jbGllbnQuY29uZmlnLmVuZHBvaW50ICsgYXBpUGF0aCk7XG5cbiAgICAgICAgY29uc3QgYXBpSGVhZGVyczogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuY2FsbChcbiAgICAgICAgICAgICdnZXQnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERlbGV0ZSBpZGVudGl0eVxuICAgICAqXG4gICAgICogRGVsZXRlIGFuIGlkZW50aXR5IGJ5IGl0cyB1bmlxdWUgSUQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWRlbnRpdHlJZFxuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHt9Pn1cbiAgICAgKi9cbiAgICBhc3luYyBkZWxldGVJZGVudGl0eShpZGVudGl0eUlkOiBzdHJpbmcpOiBQcm9taXNlPHt9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgaWRlbnRpdHlJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwiaWRlbnRpdHlJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXBpUGF0aCA9ICcvdXNlcnMvaWRlbnRpdGllcy97aWRlbnRpdHlJZH0nLnJlcGxhY2UoJ3tpZGVudGl0eUlkfScsIGlkZW50aXR5SWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGNvbnN0IHVyaSA9IG5ldyBVUkwodGhpcy5jbGllbnQuY29uZmlnLmVuZHBvaW50ICsgYXBpUGF0aCk7XG5cbiAgICAgICAgY29uc3QgYXBpSGVhZGVyczogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuY2FsbChcbiAgICAgICAgICAgICdkZWxldGUnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSB1c2VyIHdpdGggTUQ1IHBhc3N3b3JkXG4gICAgICpcbiAgICAgKiBDcmVhdGUgYSBuZXcgdXNlci4gUGFzc3dvcmQgcHJvdmlkZWQgbXVzdCBiZSBoYXNoZWQgd2l0aCB0aGUgW01ENV0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTUQ1KSBhbGdvcml0aG0uIFVzZSB0aGUgW1BPU1QgL3VzZXJzXShodHRwczovL2FwcGNvbmRhLmlvL2RvY3Mvc2VydmVyL3VzZXJzI3VzZXJzQ3JlYXRlKSBlbmRwb2ludCB0byBjcmVhdGUgdXNlcnMgd2l0aCBhIHBsYWluIHRleHQgcGFzc3dvcmQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGVtYWlsXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+fVxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZU1ENVVzZXI8UHJlZmVyZW5jZXMgZXh0ZW5kcyBNb2RlbHMuUHJlZmVyZW5jZXM+KHVzZXJJZDogc3RyaW5nLCBlbWFpbDogc3RyaW5nLCBwYXNzd29yZDogc3RyaW5nLCBuYW1lPzogc3RyaW5nKTogUHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBlbWFpbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwiZW1haWxcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInBhc3N3b3JkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy9tZDUnO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsndXNlcklkJ10gPSB1c2VySWQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBlbWFpbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ2VtYWlsJ10gPSBlbWFpbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhc3N3b3JkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsncGFzc3dvcmQnXSA9IHBhc3N3b3JkO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ25hbWUnXSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ3Bvc3QnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSB1c2VyIHdpdGggUEhQYXNzIHBhc3N3b3JkXG4gICAgICpcbiAgICAgKiBDcmVhdGUgYSBuZXcgdXNlci4gUGFzc3dvcmQgcHJvdmlkZWQgbXVzdCBiZSBoYXNoZWQgd2l0aCB0aGUgW1BIUGFzc10oaHR0cHM6Ly93d3cub3BlbndhbGwuY29tL3BocGFzcy8pIGFsZ29yaXRobS4gVXNlIHRoZSBbUE9TVCAvdXNlcnNdKGh0dHBzOi8vYXBwY29uZGEuaW8vZG9jcy9zZXJ2ZXIvdXNlcnMjdXNlcnNDcmVhdGUpIGVuZHBvaW50IHRvIGNyZWF0ZSB1c2VycyB3aXRoIGEgcGxhaW4gdGV4dCBwYXNzd29yZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZW1haWxcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFzc3dvcmRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj59XG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlUEhQYXNzVXNlcjxQcmVmZXJlbmNlcyBleHRlbmRzIE1vZGVscy5QcmVmZXJlbmNlcz4odXNlcklkOiBzdHJpbmcsIGVtYWlsOiBzdHJpbmcsIHBhc3N3b3JkOiBzdHJpbmcsIG5hbWU/OiBzdHJpbmcpOiBQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj4ge1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidXNlcklkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGVtYWlsID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJlbWFpbFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwicGFzc3dvcmRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3BocGFzcyc7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWyd1c2VySWQnXSA9IHVzZXJJZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGVtYWlsICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsnZW1haWwnXSA9IGVtYWlsO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwYXNzd29yZCddID0gcGFzc3dvcmQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsnbmFtZSddID0gbmFtZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1cmkgPSBuZXcgVVJMKHRoaXMuY2xpZW50LmNvbmZpZy5lbmRwb2ludCArIGFwaVBhdGgpO1xuXG4gICAgICAgIGNvbnN0IGFwaUhlYWRlcnM6IHsgW2hlYWRlcjogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmNhbGwoXG4gICAgICAgICAgICAncG9zdCcsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIHVzZXIgd2l0aCBTY3J5cHQgcGFzc3dvcmRcbiAgICAgKlxuICAgICAqIENyZWF0ZSBhIG5ldyB1c2VyLiBQYXNzd29yZCBwcm92aWRlZCBtdXN0IGJlIGhhc2hlZCB3aXRoIHRoZSBbU2NyeXB0XShodHRwczovL2dpdGh1Yi5jb20vVGFyc25hcC9zY3J5cHQpIGFsZ29yaXRobS4gVXNlIHRoZSBbUE9TVCAvdXNlcnNdKGh0dHBzOi8vYXBwY29uZGEuaW8vZG9jcy9zZXJ2ZXIvdXNlcnMjdXNlcnNDcmVhdGUpIGVuZHBvaW50IHRvIGNyZWF0ZSB1c2VycyB3aXRoIGEgcGxhaW4gdGV4dCBwYXNzd29yZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZW1haWxcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFzc3dvcmRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFzc3dvcmRTYWx0XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhc3N3b3JkQ3B1XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhc3N3b3JkTWVtb3J5XG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHBhc3N3b3JkUGFyYWxsZWxcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGFzc3dvcmRMZW5ndGhcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj59XG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlU2NyeXB0VXNlcjxQcmVmZXJlbmNlcyBleHRlbmRzIE1vZGVscy5QcmVmZXJlbmNlcz4odXNlcklkOiBzdHJpbmcsIGVtYWlsOiBzdHJpbmcsIHBhc3N3b3JkOiBzdHJpbmcsIHBhc3N3b3JkU2FsdDogc3RyaW5nLCBwYXNzd29yZENwdTogbnVtYmVyLCBwYXNzd29yZE1lbW9yeTogbnVtYmVyLCBwYXNzd29yZFBhcmFsbGVsOiBudW1iZXIsIHBhc3N3b3JkTGVuZ3RoOiBudW1iZXIsIG5hbWU/OiBzdHJpbmcpOiBQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj4ge1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidXNlcklkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGVtYWlsID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJlbWFpbFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwicGFzc3dvcmRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmRTYWx0ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJwYXNzd29yZFNhbHRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmRDcHUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInBhc3N3b3JkQ3B1XCInKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhc3N3b3JkTWVtb3J5ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJwYXNzd29yZE1lbW9yeVwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZFBhcmFsbGVsID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJwYXNzd29yZFBhcmFsbGVsXCInKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhc3N3b3JkTGVuZ3RoID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJwYXNzd29yZExlbmd0aFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXBpUGF0aCA9ICcvdXNlcnMvc2NyeXB0JztcbiAgICAgICAgY29uc3QgcGF5bG9hZDogUGF5bG9hZCA9IHt9O1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ3VzZXJJZCddID0gdXNlcklkO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZW1haWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydlbWFpbCddID0gZW1haWw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ3Bhc3N3b3JkJ10gPSBwYXNzd29yZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhc3N3b3JkU2FsdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ3Bhc3N3b3JkU2FsdCddID0gcGFzc3dvcmRTYWx0O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmRDcHUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwYXNzd29yZENwdSddID0gcGFzc3dvcmRDcHU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZE1lbW9yeSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ3Bhc3N3b3JkTWVtb3J5J10gPSBwYXNzd29yZE1lbW9yeTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhc3N3b3JkUGFyYWxsZWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwYXNzd29yZFBhcmFsbGVsJ10gPSBwYXNzd29yZFBhcmFsbGVsO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmRMZW5ndGggIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwYXNzd29yZExlbmd0aCddID0gcGFzc3dvcmRMZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsnbmFtZSddID0gbmFtZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1cmkgPSBuZXcgVVJMKHRoaXMuY2xpZW50LmNvbmZpZy5lbmRwb2ludCArIGFwaVBhdGgpO1xuXG4gICAgICAgIGNvbnN0IGFwaUhlYWRlcnM6IHsgW2hlYWRlcjogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmNhbGwoXG4gICAgICAgICAgICAncG9zdCcsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIHVzZXIgd2l0aCBTY3J5cHQgbW9kaWZpZWQgcGFzc3dvcmRcbiAgICAgKlxuICAgICAqIENyZWF0ZSBhIG5ldyB1c2VyLiBQYXNzd29yZCBwcm92aWRlZCBtdXN0IGJlIGhhc2hlZCB3aXRoIHRoZSBbU2NyeXB0IE1vZGlmaWVkXShodHRwczovL2dpc3QuZ2l0aHViLmNvbS9NZWxkaXJvbi9lZWNmODRhMDIyNWVjY2I1YTM3OGQ0NWJiMjc0NjJjYykgYWxnb3JpdGhtLiBVc2UgdGhlIFtQT1NUIC91c2Vyc10oaHR0cHM6Ly9hcHBjb25kYS5pby9kb2NzL3NlcnZlci91c2VycyN1c2Vyc0NyZWF0ZSkgZW5kcG9pbnQgdG8gY3JlYXRlIHVzZXJzIHdpdGggYSBwbGFpbiB0ZXh0IHBhc3N3b3JkLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBlbWFpbFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzd29yZFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzd29yZFNhbHRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFzc3dvcmRTYWx0U2VwYXJhdG9yXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhc3N3b3JkU2lnbmVyS2V5XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+fVxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZVNjcnlwdE1vZGlmaWVkVXNlcjxQcmVmZXJlbmNlcyBleHRlbmRzIE1vZGVscy5QcmVmZXJlbmNlcz4odXNlcklkOiBzdHJpbmcsIGVtYWlsOiBzdHJpbmcsIHBhc3N3b3JkOiBzdHJpbmcsIHBhc3N3b3JkU2FsdDogc3RyaW5nLCBwYXNzd29yZFNhbHRTZXBhcmF0b3I6IHN0cmluZywgcGFzc3dvcmRTaWduZXJLZXk6IHN0cmluZywgbmFtZT86IHN0cmluZyk6IFByb21pc2U8TW9kZWxzLlVzZXI8UHJlZmVyZW5jZXM+PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZW1haWwgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcImVtYWlsXCInKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhc3N3b3JkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJwYXNzd29yZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZFNhbHQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInBhc3N3b3JkU2FsdFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZFNhbHRTZXBhcmF0b3IgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInBhc3N3b3JkU2FsdFNlcGFyYXRvclwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZFNpZ25lcktleSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwicGFzc3dvcmRTaWduZXJLZXlcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3NjcnlwdC1tb2RpZmllZCc7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWyd1c2VySWQnXSA9IHVzZXJJZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGVtYWlsICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsnZW1haWwnXSA9IGVtYWlsO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwYXNzd29yZCddID0gcGFzc3dvcmQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZFNhbHQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwYXNzd29yZFNhbHQnXSA9IHBhc3N3b3JkU2FsdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHBhc3N3b3JkU2FsdFNlcGFyYXRvciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ3Bhc3N3b3JkU2FsdFNlcGFyYXRvciddID0gcGFzc3dvcmRTYWx0U2VwYXJhdG9yO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmRTaWduZXJLZXkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwYXNzd29yZFNpZ25lcktleSddID0gcGFzc3dvcmRTaWduZXJLZXk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsnbmFtZSddID0gbmFtZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1cmkgPSBuZXcgVVJMKHRoaXMuY2xpZW50LmNvbmZpZy5lbmRwb2ludCArIGFwaVBhdGgpO1xuXG4gICAgICAgIGNvbnN0IGFwaUhlYWRlcnM6IHsgW2hlYWRlcjogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmNhbGwoXG4gICAgICAgICAgICAncG9zdCcsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIHVzZXIgd2l0aCBTSEEgcGFzc3dvcmRcbiAgICAgKlxuICAgICAqIENyZWF0ZSBhIG5ldyB1c2VyLiBQYXNzd29yZCBwcm92aWRlZCBtdXN0IGJlIGhhc2hlZCB3aXRoIHRoZSBbU0hBXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9TZWN1cmVfSGFzaF9BbGdvcml0aG0pIGFsZ29yaXRobS4gVXNlIHRoZSBbUE9TVCAvdXNlcnNdKGh0dHBzOi8vYXBwY29uZGEuaW8vZG9jcy9zZXJ2ZXIvdXNlcnMjdXNlcnNDcmVhdGUpIGVuZHBvaW50IHRvIGNyZWF0ZSB1c2VycyB3aXRoIGEgcGxhaW4gdGV4dCBwYXNzd29yZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZW1haWxcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFzc3dvcmRcbiAgICAgKiBAcGFyYW0ge1Bhc3N3b3JkSGFzaH0gcGFzc3dvcmRWZXJzaW9uXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+fVxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZVNIQVVzZXI8UHJlZmVyZW5jZXMgZXh0ZW5kcyBNb2RlbHMuUHJlZmVyZW5jZXM+KHVzZXJJZDogc3RyaW5nLCBlbWFpbDogc3RyaW5nLCBwYXNzd29yZDogc3RyaW5nLCBwYXNzd29yZFZlcnNpb24/OiBQYXNzd29yZEhhc2gsIG5hbWU/OiBzdHJpbmcpOiBQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj4ge1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidXNlcklkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGVtYWlsID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJlbWFpbFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwicGFzc3dvcmRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3NoYSc7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWyd1c2VySWQnXSA9IHVzZXJJZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGVtYWlsICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsnZW1haWwnXSA9IGVtYWlsO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwYXNzd29yZCddID0gcGFzc3dvcmQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwYXNzd29yZFZlcnNpb24gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwYXNzd29yZFZlcnNpb24nXSA9IHBhc3N3b3JkVmVyc2lvbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWyduYW1lJ10gPSBuYW1lO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVyaSA9IG5ldyBVUkwodGhpcy5jbGllbnQuY29uZmlnLmVuZHBvaW50ICsgYXBpUGF0aCk7XG5cbiAgICAgICAgY29uc3QgYXBpSGVhZGVyczogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuY2FsbChcbiAgICAgICAgICAgICdwb3N0JyxcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIGFwaUhlYWRlcnMsXG4gICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdXNlclxuICAgICAqXG4gICAgICogR2V0IGEgdXNlciBieSBpdHMgdW5pcXVlIElELlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZFxuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj59XG4gICAgICovXG4gICAgYXN5bmMgZ2V0PFByZWZlcmVuY2VzIGV4dGVuZHMgTW9kZWxzLlByZWZlcmVuY2VzPih1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8TW9kZWxzLlVzZXI8UHJlZmVyZW5jZXM+PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3t1c2VySWR9Jy5yZXBsYWNlKCd7dXNlcklkfScsIHVzZXJJZCk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ2dldCcsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVsZXRlIHVzZXJcbiAgICAgKlxuICAgICAqIERlbGV0ZSBhIHVzZXIgYnkgaXRzIHVuaXF1ZSBJRCwgdGhlcmVieSByZWxlYXNpbmcgaXQmIzAzOTtzIElELiBTaW5jZSBJRCBpcyByZWxlYXNlZCBhbmQgY2FuIGJlIHJldXNlZCwgYWxsIHVzZXItcmVsYXRlZCByZXNvdXJjZXMgbGlrZSBkb2N1bWVudHMgb3Igc3RvcmFnZSBmaWxlcyBzaG91bGQgYmUgZGVsZXRlZCBiZWZvcmUgdXNlciBkZWxldGlvbi4gSWYgeW91IHdhbnQgdG8ga2VlcCBJRCByZXNlcnZlZCwgdXNlIHRoZSBbdXBkYXRlU3RhdHVzXShodHRwczovL2FwcGNvbmRhLmlvL2RvY3Mvc2VydmVyL3VzZXJzI3VzZXJzVXBkYXRlU3RhdHVzKSBlbmRwb2ludCBpbnN0ZWFkLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZFxuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHt9Pn1cbiAgICAgKi9cbiAgICBhc3luYyBkZWxldGUodXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPHt9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3t1c2VySWR9Jy5yZXBsYWNlKCd7dXNlcklkfScsIHVzZXJJZCk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ2RlbGV0ZScsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIGVtYWlsXG4gICAgICpcbiAgICAgKiBVcGRhdGUgdGhlIHVzZXIgZW1haWwgYnkgaXRzIHVuaXF1ZSBJRC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZW1haWxcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+fVxuICAgICAqL1xuICAgIGFzeW5jIHVwZGF0ZUVtYWlsPFByZWZlcmVuY2VzIGV4dGVuZHMgTW9kZWxzLlByZWZlcmVuY2VzPih1c2VySWQ6IHN0cmluZywgZW1haWw6IHN0cmluZyk6IFByb21pc2U8TW9kZWxzLlVzZXI8UHJlZmVyZW5jZXM+PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZW1haWwgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcImVtYWlsXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS9lbWFpbCcucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgZW1haWwgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydlbWFpbCddID0gZW1haWw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ3BhdGNoJyxcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIGFwaUhlYWRlcnMsXG4gICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgdXNlciBKV1RcbiAgICAgKlxuICAgICAqIFVzZSB0aGlzIGVuZHBvaW50IHRvIGNyZWF0ZSBhIEpTT04gV2ViIFRva2VuIGZvciB1c2VyIGJ5IGl0cyB1bmlxdWUgSUQuIFlvdSBjYW4gdXNlIHRoZSByZXN1bHRpbmcgSldUIHRvIGF1dGhlbnRpY2F0ZSBvbiBiZWhhbGYgb2YgdGhlIHVzZXIuIFRoZSBKV1Qgc2VjcmV0IHdpbGwgYmVjb21lIGludmFsaWQgaWYgdGhlIHNlc3Npb24gaXQgdXNlcyBnZXRzIGRlbGV0ZWQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHNlc3Npb25JZFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBkdXJhdGlvblxuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE1vZGVscy5Kd3Q+fVxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZUpXVCh1c2VySWQ6IHN0cmluZywgc2Vzc2lvbklkPzogc3RyaW5nLCBkdXJhdGlvbj86IG51bWJlcik6IFByb21pc2U8TW9kZWxzLkp3dD4ge1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidXNlcklkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS9qd3RzJy5yZXBsYWNlKCd7dXNlcklkfScsIHVzZXJJZCk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiBzZXNzaW9uSWQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydzZXNzaW9uSWQnXSA9IHNlc3Npb25JZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGR1cmF0aW9uICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsnZHVyYXRpb24nXSA9IGR1cmF0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVyaSA9IG5ldyBVUkwodGhpcy5jbGllbnQuY29uZmlnLmVuZHBvaW50ICsgYXBpUGF0aCk7XG5cbiAgICAgICAgY29uc3QgYXBpSGVhZGVyczogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuY2FsbChcbiAgICAgICAgICAgICdwb3N0JyxcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIGFwaUhlYWRlcnMsXG4gICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdXNlciBsYWJlbHNcbiAgICAgKlxuICAgICAqIFVwZGF0ZSB0aGUgdXNlciBsYWJlbHMgYnkgaXRzIHVuaXF1ZSBJRC4gXG5cbkxhYmVscyBjYW4gYmUgdXNlZCB0byBncmFudCBhY2Nlc3MgdG8gcmVzb3VyY2VzLiBXaGlsZSB0ZWFtcyBhcmUgYSB3YXkgZm9yIHVzZXImIzAzOTtzIHRvIHNoYXJlIGFjY2VzcyB0byBhIHJlc291cmNlLCBsYWJlbHMgY2FuIGJlIGRlZmluZWQgYnkgdGhlIGRldmVsb3BlciB0byBncmFudCBhY2Nlc3Mgd2l0aG91dCBhbiBpbnZpdGF0aW9uLiBTZWUgdGhlIFtQZXJtaXNzaW9ucyBkb2NzXShodHRwczovL2FwcGNvbmRhLmlvL2RvY3MvcGVybWlzc2lvbnMpIGZvciBtb3JlIGluZm8uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHBhcmFtIHtzdHJpbmdbXX0gbGFiZWxzXG4gICAgICogQHRocm93cyB7QXBwY29uZGFFeGNlcHRpb259XG4gICAgICogQHJldHVybnMge1Byb21pc2U8TW9kZWxzLlVzZXI8UHJlZmVyZW5jZXM+Pn1cbiAgICAgKi9cbiAgICBhc3luYyB1cGRhdGVMYWJlbHM8UHJlZmVyZW5jZXMgZXh0ZW5kcyBNb2RlbHMuUHJlZmVyZW5jZXM+KHVzZXJJZDogc3RyaW5nLCBsYWJlbHM6IHN0cmluZ1tdKTogUHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBsYWJlbHMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcImxhYmVsc1wiJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXBpUGF0aCA9ICcvdXNlcnMve3VzZXJJZH0vbGFiZWxzJy5yZXBsYWNlKCd7dXNlcklkfScsIHVzZXJJZCk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiBsYWJlbHMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydsYWJlbHMnXSA9IGxhYmVscztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1cmkgPSBuZXcgVVJMKHRoaXMuY2xpZW50LmNvbmZpZy5lbmRwb2ludCArIGFwaVBhdGgpO1xuXG4gICAgICAgIGNvbnN0IGFwaUhlYWRlcnM6IHsgW2hlYWRlcjogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmNhbGwoXG4gICAgICAgICAgICAncHV0JyxcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIGFwaUhlYWRlcnMsXG4gICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBMaXN0IHVzZXIgbG9nc1xuICAgICAqXG4gICAgICogR2V0IHRoZSB1c2VyIGFjdGl2aXR5IGxvZ3MgbGlzdCBieSBpdHMgdW5pcXVlIElELlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZFxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IHF1ZXJpZXNcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuTG9nTGlzdD59XG4gICAgICovXG4gICAgYXN5bmMgbGlzdExvZ3ModXNlcklkOiBzdHJpbmcsIHF1ZXJpZXM/OiBzdHJpbmdbXSk6IFByb21pc2U8TW9kZWxzLkxvZ0xpc3Q+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXBpUGF0aCA9ICcvdXNlcnMve3VzZXJJZH0vbG9ncycucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgcXVlcmllcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ3F1ZXJpZXMnXSA9IHF1ZXJpZXM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ2dldCcsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGlzdCB1c2VyIG1lbWJlcnNoaXBzXG4gICAgICpcbiAgICAgKiBHZXQgdGhlIHVzZXIgbWVtYmVyc2hpcCBsaXN0IGJ5IGl0cyB1bmlxdWUgSUQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHRocm93cyB7QXBwY29uZGFFeGNlcHRpb259XG4gICAgICogQHJldHVybnMge1Byb21pc2U8TW9kZWxzLk1lbWJlcnNoaXBMaXN0Pn1cbiAgICAgKi9cbiAgICBhc3luYyBsaXN0TWVtYmVyc2hpcHModXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPE1vZGVscy5NZW1iZXJzaGlwTGlzdD4ge1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidXNlcklkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS9tZW1iZXJzaGlwcycucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGNvbnN0IHVyaSA9IG5ldyBVUkwodGhpcy5jbGllbnQuY29uZmlnLmVuZHBvaW50ICsgYXBpUGF0aCk7XG5cbiAgICAgICAgY29uc3QgYXBpSGVhZGVyczogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuY2FsbChcbiAgICAgICAgICAgICdnZXQnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSBNRkFcbiAgICAgKlxuICAgICAqIEVuYWJsZSBvciBkaXNhYmxlIE1GQSBvbiBhIHVzZXIgYWNjb3VudC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IG1mYVxuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj59XG4gICAgICovXG4gICAgYXN5bmMgdXBkYXRlTWZhPFByZWZlcmVuY2VzIGV4dGVuZHMgTW9kZWxzLlByZWZlcmVuY2VzPih1c2VySWQ6IHN0cmluZywgbWZhOiBib29sZWFuKTogUHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBtZmEgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcIm1mYVwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXBpUGF0aCA9ICcvdXNlcnMve3VzZXJJZH0vbWZhJy5yZXBsYWNlKCd7dXNlcklkfScsIHVzZXJJZCk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiBtZmEgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydtZmEnXSA9IG1mYTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1cmkgPSBuZXcgVVJMKHRoaXMuY2xpZW50LmNvbmZpZy5lbmRwb2ludCArIGFwaVBhdGgpO1xuXG4gICAgICAgIGNvbnN0IGFwaUhlYWRlcnM6IHsgW2hlYWRlcjogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmNhbGwoXG4gICAgICAgICAgICAncGF0Y2gnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIERlbGV0ZSBBdXRoZW50aWNhdG9yXG4gICAgICpcbiAgICAgKiBEZWxldGUgYW4gYXV0aGVudGljYXRvciBhcHAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHBhcmFtIHtBdXRoZW50aWNhdG9yVHlwZX0gdHlwZVxuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj59XG4gICAgICovXG4gICAgYXN5bmMgZGVsZXRlTWZhQXV0aGVudGljYXRvcjxQcmVmZXJlbmNlcyBleHRlbmRzIE1vZGVscy5QcmVmZXJlbmNlcz4odXNlcklkOiBzdHJpbmcsIHR5cGU6IEF1dGhlbnRpY2F0b3JUeXBlKTogUHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB0eXBlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ0eXBlXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS9tZmEvYXV0aGVudGljYXRvcnMve3R5cGV9Jy5yZXBsYWNlKCd7dXNlcklkfScsIHVzZXJJZCkucmVwbGFjZSgne3R5cGV9JywgdHlwZSk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ2RlbGV0ZScsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogTGlzdCBGYWN0b3JzXG4gICAgICpcbiAgICAgKiBMaXN0IHRoZSBmYWN0b3JzIGF2YWlsYWJsZSBvbiB0aGUgYWNjb3VudCB0byBiZSB1c2VkIGFzIGEgTUZBIGNoYWxsYW5nZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuTWZhRmFjdG9ycz59XG4gICAgICovXG4gICAgYXN5bmMgbGlzdE1mYUZhY3RvcnModXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPE1vZGVscy5NZmFGYWN0b3JzPiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3t1c2VySWR9L21mYS9mYWN0b3JzJy5yZXBsYWNlKCd7dXNlcklkfScsIHVzZXJJZCk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ2dldCcsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IE1GQSBSZWNvdmVyeSBDb2Rlc1xuICAgICAqXG4gICAgICogR2V0IHJlY292ZXJ5IGNvZGVzIHRoYXQgY2FuIGJlIHVzZWQgYXMgYmFja3VwIGZvciBNRkEgZmxvdyBieSBVc2VyIElELiBCZWZvcmUgZ2V0dGluZyBjb2RlcywgdGhleSBtdXN0IGJlIGdlbmVyYXRlZCB1c2luZyBbY3JlYXRlTWZhUmVjb3ZlcnlDb2Rlc10oL2RvY3MvcmVmZXJlbmNlcy9jbG91ZC9jbGllbnQtd2ViL2FjY291bnQjY3JlYXRlTWZhUmVjb3ZlcnlDb2RlcykgbWV0aG9kLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZFxuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE1vZGVscy5NZmFSZWNvdmVyeUNvZGVzPn1cbiAgICAgKi9cbiAgICBhc3luYyBnZXRNZmFSZWNvdmVyeUNvZGVzKHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTxNb2RlbHMuTWZhUmVjb3ZlcnlDb2Rlcz4ge1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidXNlcklkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS9tZmEvcmVjb3ZlcnktY29kZXMnLnJlcGxhY2UoJ3t1c2VySWR9JywgdXNlcklkKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZDogUGF5bG9hZCA9IHt9O1xuICAgICAgICBjb25zdCB1cmkgPSBuZXcgVVJMKHRoaXMuY2xpZW50LmNvbmZpZy5lbmRwb2ludCArIGFwaVBhdGgpO1xuXG4gICAgICAgIGNvbnN0IGFwaUhlYWRlcnM6IHsgW2hlYWRlcjogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmNhbGwoXG4gICAgICAgICAgICAnZ2V0JyxcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIGFwaUhlYWRlcnMsXG4gICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdlbmVyYXRlIE1GQSBSZWNvdmVyeSBDb2Rlc1xuICAgICAqXG4gICAgICogUmVnZW5lcmF0ZSByZWNvdmVyeSBjb2RlcyB0aGF0IGNhbiBiZSB1c2VkIGFzIGJhY2t1cCBmb3IgTUZBIGZsb3cgYnkgVXNlciBJRC4gQmVmb3JlIHJlZ2VuZXJhdGluZyBjb2RlcywgdGhleSBtdXN0IGJlIGZpcnN0IGdlbmVyYXRlZCB1c2luZyBbY3JlYXRlTWZhUmVjb3ZlcnlDb2Rlc10oL2RvY3MvcmVmZXJlbmNlcy9jbG91ZC9jbGllbnQtd2ViL2FjY291bnQjY3JlYXRlTWZhUmVjb3ZlcnlDb2RlcykgbWV0aG9kLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZFxuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE1vZGVscy5NZmFSZWNvdmVyeUNvZGVzPn1cbiAgICAgKi9cbiAgICBhc3luYyB1cGRhdGVNZmFSZWNvdmVyeUNvZGVzKHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTxNb2RlbHMuTWZhUmVjb3ZlcnlDb2Rlcz4ge1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidXNlcklkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS9tZmEvcmVjb3ZlcnktY29kZXMnLnJlcGxhY2UoJ3t1c2VySWR9JywgdXNlcklkKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZDogUGF5bG9hZCA9IHt9O1xuICAgICAgICBjb25zdCB1cmkgPSBuZXcgVVJMKHRoaXMuY2xpZW50LmNvbmZpZy5lbmRwb2ludCArIGFwaVBhdGgpO1xuXG4gICAgICAgIGNvbnN0IGFwaUhlYWRlcnM6IHsgW2hlYWRlcjogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmNhbGwoXG4gICAgICAgICAgICAncHV0JyxcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIGFwaUhlYWRlcnMsXG4gICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgTUZBIFJlY292ZXJ5IENvZGVzXG4gICAgICpcbiAgICAgKiBHZW5lcmF0ZSByZWNvdmVyeSBjb2RlcyB1c2VkIGFzIGJhY2t1cCBmb3IgTUZBIGZsb3cgZm9yIFVzZXIgSUQuIFJlY292ZXJ5IGNvZGVzIGNhbiBiZSB1c2VkIGFzIGEgTUZBIHZlcmlmaWNhdGlvbiB0eXBlIGluIFtjcmVhdGVNZmFDaGFsbGVuZ2VdKC9kb2NzL3JlZmVyZW5jZXMvY2xvdWQvY2xpZW50LXdlYi9hY2NvdW50I2NyZWF0ZU1mYUNoYWxsZW5nZSkgbWV0aG9kIGJ5IGNsaWVudCBTREsuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHRocm93cyB7QXBwY29uZGFFeGNlcHRpb259XG4gICAgICogQHJldHVybnMge1Byb21pc2U8TW9kZWxzLk1mYVJlY292ZXJ5Q29kZXM+fVxuICAgICAqL1xuICAgIGFzeW5jIGNyZWF0ZU1mYVJlY292ZXJ5Q29kZXModXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPE1vZGVscy5NZmFSZWNvdmVyeUNvZGVzPiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3t1c2VySWR9L21mYS9yZWNvdmVyeS1jb2RlcycucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGNvbnN0IHVyaSA9IG5ldyBVUkwodGhpcy5jbGllbnQuY29uZmlnLmVuZHBvaW50ICsgYXBpUGF0aCk7XG5cbiAgICAgICAgY29uc3QgYXBpSGVhZGVyczogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuY2FsbChcbiAgICAgICAgICAgICdwYXRjaCcsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIG5hbWVcbiAgICAgKlxuICAgICAqIFVwZGF0ZSB0aGUgdXNlciBuYW1lIGJ5IGl0cyB1bmlxdWUgSUQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+fVxuICAgICAqL1xuICAgIGFzeW5jIHVwZGF0ZU5hbWU8UHJlZmVyZW5jZXMgZXh0ZW5kcyBNb2RlbHMuUHJlZmVyZW5jZXM+KHVzZXJJZDogc3RyaW5nLCBuYW1lOiBzdHJpbmcpOiBQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj4ge1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidXNlcklkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIG5hbWUgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcIm5hbWVcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3t1c2VySWR9L25hbWUnLnJlcGxhY2UoJ3t1c2VySWR9JywgdXNlcklkKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZDogUGF5bG9hZCA9IHt9O1xuICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWyduYW1lJ10gPSBuYW1lO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVyaSA9IG5ldyBVUkwodGhpcy5jbGllbnQuY29uZmlnLmVuZHBvaW50ICsgYXBpUGF0aCk7XG5cbiAgICAgICAgY29uc3QgYXBpSGVhZGVyczogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuY2FsbChcbiAgICAgICAgICAgICdwYXRjaCcsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIHBhc3N3b3JkXG4gICAgICpcbiAgICAgKiBVcGRhdGUgdGhlIHVzZXIgcGFzc3dvcmQgYnkgaXRzIHVuaXF1ZSBJRC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFzc3dvcmRcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+fVxuICAgICAqL1xuICAgIGFzeW5jIHVwZGF0ZVBhc3N3b3JkPFByZWZlcmVuY2VzIGV4dGVuZHMgTW9kZWxzLlByZWZlcmVuY2VzPih1c2VySWQ6IHN0cmluZywgcGFzc3dvcmQ6IHN0cmluZyk6IFByb21pc2U8TW9kZWxzLlVzZXI8UHJlZmVyZW5jZXM+PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInBhc3N3b3JkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS9wYXNzd29yZCcucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgcGFzc3dvcmQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwYXNzd29yZCddID0gcGFzc3dvcmQ7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ3BhdGNoJyxcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIGFwaUhlYWRlcnMsXG4gICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgcGhvbmVcbiAgICAgKlxuICAgICAqIFVwZGF0ZSB0aGUgdXNlciBwaG9uZSBieSBpdHMgdW5pcXVlIElELlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBudW1iZXJcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+fVxuICAgICAqL1xuICAgIGFzeW5jIHVwZGF0ZVBob25lPFByZWZlcmVuY2VzIGV4dGVuZHMgTW9kZWxzLlByZWZlcmVuY2VzPih1c2VySWQ6IHN0cmluZywgbnVtYmVyOiBzdHJpbmcpOiBQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj4ge1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidXNlcklkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIG51bWJlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwibnVtYmVyXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS9waG9uZScucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgbnVtYmVyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsnbnVtYmVyJ10gPSBudW1iZXI7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ3BhdGNoJyxcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIGFwaUhlYWRlcnMsXG4gICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdXNlciBwcmVmZXJlbmNlc1xuICAgICAqXG4gICAgICogR2V0IHRoZSB1c2VyIHByZWZlcmVuY2VzIGJ5IGl0cyB1bmlxdWUgSUQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHRocm93cyB7QXBwY29uZGFFeGNlcHRpb259XG4gICAgICogQHJldHVybnMge1Byb21pc2U8UHJlZmVyZW5jZXM+fVxuICAgICAqL1xuICAgIGFzeW5jIGdldFByZWZzPFByZWZlcmVuY2VzIGV4dGVuZHMgTW9kZWxzLlByZWZlcmVuY2VzPih1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8UHJlZmVyZW5jZXM+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXBpUGF0aCA9ICcvdXNlcnMve3VzZXJJZH0vcHJlZnMnLnJlcGxhY2UoJ3t1c2VySWR9JywgdXNlcklkKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZDogUGF5bG9hZCA9IHt9O1xuICAgICAgICBjb25zdCB1cmkgPSBuZXcgVVJMKHRoaXMuY2xpZW50LmNvbmZpZy5lbmRwb2ludCArIGFwaVBhdGgpO1xuXG4gICAgICAgIGNvbnN0IGFwaUhlYWRlcnM6IHsgW2hlYWRlcjogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmNhbGwoXG4gICAgICAgICAgICAnZ2V0JyxcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIGFwaUhlYWRlcnMsXG4gICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdXNlciBwcmVmZXJlbmNlc1xuICAgICAqXG4gICAgICogVXBkYXRlIHRoZSB1c2VyIHByZWZlcmVuY2VzIGJ5IGl0cyB1bmlxdWUgSUQuIFRoZSBvYmplY3QgeW91IHBhc3MgaXMgc3RvcmVkIGFzIGlzLCBhbmQgcmVwbGFjZXMgYW55IHByZXZpb3VzIHZhbHVlLiBUaGUgbWF4aW11bSBhbGxvd2VkIHByZWZzIHNpemUgaXMgNjRrQiBhbmQgdGhyb3dzIGVycm9yIGlmIGV4Y2VlZGVkLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZFxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBwcmVmc1xuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPFByZWZlcmVuY2VzPn1cbiAgICAgKi9cbiAgICBhc3luYyB1cGRhdGVQcmVmczxQcmVmZXJlbmNlcyBleHRlbmRzIE1vZGVscy5QcmVmZXJlbmNlcz4odXNlcklkOiBzdHJpbmcsIHByZWZzOiBvYmplY3QpOiBQcm9taXNlPFByZWZlcmVuY2VzPiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcHJlZnMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInByZWZzXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS9wcmVmcycucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgcHJlZnMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwcmVmcyddID0gcHJlZnM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ3BhdGNoJyxcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIGFwaUhlYWRlcnMsXG4gICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBMaXN0IHVzZXIgc2Vzc2lvbnNcbiAgICAgKlxuICAgICAqIEdldCB0aGUgdXNlciBzZXNzaW9ucyBsaXN0IGJ5IGl0cyB1bmlxdWUgSUQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHRocm93cyB7QXBwY29uZGFFeGNlcHRpb259XG4gICAgICogQHJldHVybnMge1Byb21pc2U8TW9kZWxzLlNlc3Npb25MaXN0Pn1cbiAgICAgKi9cbiAgICBhc3luYyBsaXN0U2Vzc2lvbnModXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPE1vZGVscy5TZXNzaW9uTGlzdD4ge1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidXNlcklkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS9zZXNzaW9ucycucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGNvbnN0IHVyaSA9IG5ldyBVUkwodGhpcy5jbGllbnQuY29uZmlnLmVuZHBvaW50ICsgYXBpUGF0aCk7XG5cbiAgICAgICAgY29uc3QgYXBpSGVhZGVyczogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuY2FsbChcbiAgICAgICAgICAgICdnZXQnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBzZXNzaW9uXG4gICAgICpcbiAgICAgKiBDcmVhdGVzIGEgc2Vzc2lvbiBmb3IgYSB1c2VyLiBSZXR1cm5zIGFuIGltbWVkaWF0ZWx5IHVzYWJsZSBzZXNzaW9uIG9iamVjdC5cblxuSWYgeW91IHdhbnQgdG8gZ2VuZXJhdGUgYSB0b2tlbiBmb3IgYSBjdXN0b20gYXV0aGVudGljYXRpb24gZmxvdywgdXNlIHRoZSBbUE9TVCAvdXNlcnMve3VzZXJJZH0vdG9rZW5zXShodHRwczovL2FwcGNvbmRhLmlvL2RvY3Mvc2VydmVyL3VzZXJzI2NyZWF0ZVRva2VuKSBlbmRwb2ludC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuU2Vzc2lvbj59XG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlU2Vzc2lvbih1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8TW9kZWxzLlNlc3Npb24+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXBpUGF0aCA9ICcvdXNlcnMve3VzZXJJZH0vc2Vzc2lvbnMnLnJlcGxhY2UoJ3t1c2VySWR9JywgdXNlcklkKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZDogUGF5bG9hZCA9IHt9O1xuICAgICAgICBjb25zdCB1cmkgPSBuZXcgVVJMKHRoaXMuY2xpZW50LmNvbmZpZy5lbmRwb2ludCArIGFwaVBhdGgpO1xuXG4gICAgICAgIGNvbnN0IGFwaUhlYWRlcnM6IHsgW2hlYWRlcjogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmNhbGwoXG4gICAgICAgICAgICAncG9zdCcsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVsZXRlIHVzZXIgc2Vzc2lvbnNcbiAgICAgKlxuICAgICAqIERlbGV0ZSBhbGwgdXNlciYjMDM5O3Mgc2Vzc2lvbnMgYnkgdXNpbmcgdGhlIHVzZXImIzAzOTtzIHVuaXF1ZSBJRC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7fT59XG4gICAgICovXG4gICAgYXN5bmMgZGVsZXRlU2Vzc2lvbnModXNlcklkOiBzdHJpbmcpOiBQcm9taXNlPHt9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3t1c2VySWR9L3Nlc3Npb25zJy5yZXBsYWNlKCd7dXNlcklkfScsIHVzZXJJZCk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ2RlbGV0ZScsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogRGVsZXRlIHVzZXIgc2Vzc2lvblxuICAgICAqXG4gICAgICogRGVsZXRlIGEgdXNlciBzZXNzaW9ucyBieSBpdHMgdW5pcXVlIElELlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzZXNzaW9uSWRcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7fT59XG4gICAgICovXG4gICAgYXN5bmMgZGVsZXRlU2Vzc2lvbih1c2VySWQ6IHN0cmluZywgc2Vzc2lvbklkOiBzdHJpbmcpOiBQcm9taXNlPHt9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Ygc2Vzc2lvbklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJzZXNzaW9uSWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3t1c2VySWR9L3Nlc3Npb25zL3tzZXNzaW9uSWR9Jy5yZXBsYWNlKCd7dXNlcklkfScsIHVzZXJJZCkucmVwbGFjZSgne3Nlc3Npb25JZH0nLCBzZXNzaW9uSWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGNvbnN0IHVyaSA9IG5ldyBVUkwodGhpcy5jbGllbnQuY29uZmlnLmVuZHBvaW50ICsgYXBpUGF0aCk7XG5cbiAgICAgICAgY29uc3QgYXBpSGVhZGVyczogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuY2FsbChcbiAgICAgICAgICAgICdkZWxldGUnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSB1c2VyIHN0YXR1c1xuICAgICAqXG4gICAgICogVXBkYXRlIHRoZSB1c2VyIHN0YXR1cyBieSBpdHMgdW5pcXVlIElELiBVc2UgdGhpcyBlbmRwb2ludCBhcyBhbiBhbHRlcm5hdGl2ZSB0byBkZWxldGluZyBhIHVzZXIgaWYgeW91IHdhbnQgdG8ga2VlcCB1c2VyJiMwMzk7cyBJRCByZXNlcnZlZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHN0YXR1c1xuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj59XG4gICAgICovXG4gICAgYXN5bmMgdXBkYXRlU3RhdHVzPFByZWZlcmVuY2VzIGV4dGVuZHMgTW9kZWxzLlByZWZlcmVuY2VzPih1c2VySWQ6IHN0cmluZywgc3RhdHVzOiBib29sZWFuKTogUHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBzdGF0dXMgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInN0YXR1c1wiJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXBpUGF0aCA9ICcvdXNlcnMve3VzZXJJZH0vc3RhdHVzJy5yZXBsYWNlKCd7dXNlcklkfScsIHVzZXJJZCk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiBzdGF0dXMgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydzdGF0dXMnXSA9IHN0YXR1cztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1cmkgPSBuZXcgVVJMKHRoaXMuY2xpZW50LmNvbmZpZy5lbmRwb2ludCArIGFwaVBhdGgpO1xuXG4gICAgICAgIGNvbnN0IGFwaUhlYWRlcnM6IHsgW2hlYWRlcjogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmNhbGwoXG4gICAgICAgICAgICAncGF0Y2gnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExpc3QgVXNlciBUYXJnZXRzXG4gICAgICpcbiAgICAgKiBMaXN0IHRoZSBtZXNzYWdpbmcgdGFyZ2V0cyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggYSB1c2VyLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZFxuICAgICAqIEBwYXJhbSB7c3RyaW5nW119IHF1ZXJpZXNcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVGFyZ2V0TGlzdD59XG4gICAgICovXG4gICAgYXN5bmMgbGlzdFRhcmdldHModXNlcklkOiBzdHJpbmcsIHF1ZXJpZXM/OiBzdHJpbmdbXSk6IFByb21pc2U8TW9kZWxzLlRhcmdldExpc3Q+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXBpUGF0aCA9ICcvdXNlcnMve3VzZXJJZH0vdGFyZ2V0cycucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgcXVlcmllcyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ3F1ZXJpZXMnXSA9IHF1ZXJpZXM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ2dldCcsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIFVzZXIgVGFyZ2V0XG4gICAgICpcbiAgICAgKiBDcmVhdGUgYSBtZXNzYWdpbmcgdGFyZ2V0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0YXJnZXRJZFxuICAgICAqIEBwYXJhbSB7TWVzc2FnaW5nUHJvdmlkZXJUeXBlfSBwcm92aWRlclR5cGVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWRlbnRpZmllclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwcm92aWRlcklkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVGFyZ2V0Pn1cbiAgICAgKi9cbiAgICBhc3luYyBjcmVhdGVUYXJnZXQodXNlcklkOiBzdHJpbmcsIHRhcmdldElkOiBzdHJpbmcsIHByb3ZpZGVyVHlwZTogTWVzc2FnaW5nUHJvdmlkZXJUeXBlLCBpZGVudGlmaWVyOiBzdHJpbmcsIHByb3ZpZGVySWQ/OiBzdHJpbmcsIG5hbWU/OiBzdHJpbmcpOiBQcm9taXNlPE1vZGVscy5UYXJnZXQ+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidGFyZ2V0SWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcHJvdmlkZXJUeXBlID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJwcm92aWRlclR5cGVcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgaWRlbnRpZmllciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwiaWRlbnRpZmllclwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXBpUGF0aCA9ICcvdXNlcnMve3VzZXJJZH0vdGFyZ2V0cycucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgdGFyZ2V0SWQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWyd0YXJnZXRJZCddID0gdGFyZ2V0SWQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwcm92aWRlclR5cGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwcm92aWRlclR5cGUnXSA9IHByb3ZpZGVyVHlwZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIGlkZW50aWZpZXIgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydpZGVudGlmaWVyJ10gPSBpZGVudGlmaWVyO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgcHJvdmlkZXJJZCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ3Byb3ZpZGVySWQnXSA9IHByb3ZpZGVySWQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBuYW1lICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsnbmFtZSddID0gbmFtZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1cmkgPSBuZXcgVVJMKHRoaXMuY2xpZW50LmNvbmZpZy5lbmRwb2ludCArIGFwaVBhdGgpO1xuXG4gICAgICAgIGNvbnN0IGFwaUhlYWRlcnM6IHsgW2hlYWRlcjogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuY2xpZW50LmNhbGwoXG4gICAgICAgICAgICAncG9zdCcsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogR2V0IFVzZXIgVGFyZ2V0XG4gICAgICpcbiAgICAgKiBHZXQgYSB1c2VyJiMwMzk7cyBwdXNoIG5vdGlmaWNhdGlvbiB0YXJnZXQgYnkgSUQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRhcmdldElkXG4gICAgICogQHRocm93cyB7QXBwY29uZGFFeGNlcHRpb259XG4gICAgICogQHJldHVybnMge1Byb21pc2U8TW9kZWxzLlRhcmdldD59XG4gICAgICovXG4gICAgYXN5bmMgZ2V0VGFyZ2V0KHVzZXJJZDogc3RyaW5nLCB0YXJnZXRJZDogc3RyaW5nKTogUHJvbWlzZTxNb2RlbHMuVGFyZ2V0PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgdGFyZ2V0SWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInRhcmdldElkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS90YXJnZXRzL3t0YXJnZXRJZH0nLnJlcGxhY2UoJ3t1c2VySWR9JywgdXNlcklkKS5yZXBsYWNlKCd7dGFyZ2V0SWR9JywgdGFyZ2V0SWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGNvbnN0IHVyaSA9IG5ldyBVUkwodGhpcy5jbGllbnQuY29uZmlnLmVuZHBvaW50ICsgYXBpUGF0aCk7XG5cbiAgICAgICAgY29uc3QgYXBpSGVhZGVyczogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuY2FsbChcbiAgICAgICAgICAgICdnZXQnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSBVc2VyIHRhcmdldFxuICAgICAqXG4gICAgICogVXBkYXRlIGEgbWVzc2FnaW5nIHRhcmdldC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGFyZ2V0SWRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gaWRlbnRpZmllclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwcm92aWRlcklkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAgICAgKiBAdGhyb3dzIHtBcHBjb25kYUV4Y2VwdGlvbn1cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxNb2RlbHMuVGFyZ2V0Pn1cbiAgICAgKi9cbiAgICBhc3luYyB1cGRhdGVUYXJnZXQodXNlcklkOiBzdHJpbmcsIHRhcmdldElkOiBzdHJpbmcsIGlkZW50aWZpZXI/OiBzdHJpbmcsIHByb3ZpZGVySWQ/OiBzdHJpbmcsIG5hbWU/OiBzdHJpbmcpOiBQcm9taXNlPE1vZGVscy5UYXJnZXQ+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidGFyZ2V0SWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3t1c2VySWR9L3RhcmdldHMve3RhcmdldElkfScucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpLnJlcGxhY2UoJ3t0YXJnZXRJZH0nLCB0YXJnZXRJZCk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiBpZGVudGlmaWVyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsnaWRlbnRpZmllciddID0gaWRlbnRpZmllcjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHByb3ZpZGVySWQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwcm92aWRlcklkJ10gPSBwcm92aWRlcklkO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgbmFtZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ25hbWUnXSA9IG5hbWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ3BhdGNoJyxcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIGFwaUhlYWRlcnMsXG4gICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICApO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZWxldGUgdXNlciB0YXJnZXRcbiAgICAgKlxuICAgICAqIERlbGV0ZSBhIG1lc3NhZ2luZyB0YXJnZXQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRhcmdldElkXG4gICAgICogQHRocm93cyB7QXBwY29uZGFFeGNlcHRpb259XG4gICAgICogQHJldHVybnMge1Byb21pc2U8e30+fVxuICAgICAqL1xuICAgIGFzeW5jIGRlbGV0ZVRhcmdldCh1c2VySWQ6IHN0cmluZywgdGFyZ2V0SWQ6IHN0cmluZyk6IFByb21pc2U8e30+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiB0YXJnZXRJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidGFyZ2V0SWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3t1c2VySWR9L3RhcmdldHMve3RhcmdldElkfScucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpLnJlcGxhY2UoJ3t0YXJnZXRJZH0nLCB0YXJnZXRJZCk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IFBheWxvYWQgPSB7fTtcbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ2RlbGV0ZScsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIHRva2VuXG4gICAgICpcbiAgICAgKiBSZXR1cm5zIGEgdG9rZW4gd2l0aCBhIHNlY3JldCBrZXkgZm9yIGNyZWF0aW5nIGEgc2Vzc2lvbi4gVXNlIHRoZSB1c2VyIElEIGFuZCBzZWNyZXQgYW5kIHN1Ym1pdCBhIHJlcXVlc3QgdG8gdGhlIFtQVVQgL2FjY291bnQvc2Vzc2lvbnMvdG9rZW5dKGh0dHBzOi8vYXBwY29uZGEuaW8vZG9jcy9yZWZlcmVuY2VzL2Nsb3VkL2NsaWVudC13ZWIvYWNjb3VudCNjcmVhdGVTZXNzaW9uKSBlbmRwb2ludCB0byBjb21wbGV0ZSB0aGUgbG9naW4gcHJvY2Vzcy5cblxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJJZFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGhcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gZXhwaXJlXG4gICAgICogQHRocm93cyB7QXBwY29uZGFFeGNlcHRpb259XG4gICAgICogQHJldHVybnMge1Byb21pc2U8TW9kZWxzLlRva2VuPn1cbiAgICAgKi9cbiAgICBhc3luYyBjcmVhdGVUb2tlbih1c2VySWQ6IHN0cmluZywgbGVuZ3RoPzogbnVtYmVyLCBleHBpcmU/OiBudW1iZXIpOiBQcm9taXNlPE1vZGVscy5Ub2tlbj4ge1xuICAgICAgICBpZiAodHlwZW9mIHVzZXJJZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwidXNlcklkXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS90b2tlbnMnLnJlcGxhY2UoJ3t1c2VySWR9JywgdXNlcklkKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZDogUGF5bG9hZCA9IHt9O1xuICAgICAgICBpZiAodHlwZW9mIGxlbmd0aCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHBheWxvYWRbJ2xlbmd0aCddID0gbGVuZ3RoO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZXhwaXJlICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsnZXhwaXJlJ10gPSBleHBpcmU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ3Bvc3QnLFxuICAgICAgICAgICAgdXJpLFxuICAgICAgICAgICAgYXBpSGVhZGVycyxcbiAgICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFVwZGF0ZSBlbWFpbCB2ZXJpZmljYXRpb25cbiAgICAgKlxuICAgICAqIFVwZGF0ZSB0aGUgdXNlciBlbWFpbCB2ZXJpZmljYXRpb24gc3RhdHVzIGJ5IGl0cyB1bmlxdWUgSUQuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlcklkXG4gICAgICogQHBhcmFtIHtib29sZWFufSBlbWFpbFZlcmlmaWNhdGlvblxuICAgICAqIEB0aHJvd3Mge0FwcGNvbmRhRXhjZXB0aW9ufVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE1vZGVscy5Vc2VyPFByZWZlcmVuY2VzPj59XG4gICAgICovXG4gICAgYXN5bmMgdXBkYXRlRW1haWxWZXJpZmljYXRpb248UHJlZmVyZW5jZXMgZXh0ZW5kcyBNb2RlbHMuUHJlZmVyZW5jZXM+KHVzZXJJZDogc3RyaW5nLCBlbWFpbFZlcmlmaWNhdGlvbjogYm9vbGVhbik6IFByb21pc2U8TW9kZWxzLlVzZXI8UHJlZmVyZW5jZXM+PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdXNlcklkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEFwcGNvbmRhRXhjZXB0aW9uKCdNaXNzaW5nIHJlcXVpcmVkIHBhcmFtZXRlcjogXCJ1c2VySWRcIicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZW1haWxWZXJpZmljYXRpb24gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcImVtYWlsVmVyaWZpY2F0aW9uXCInKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcGlQYXRoID0gJy91c2Vycy97dXNlcklkfS92ZXJpZmljYXRpb24nLnJlcGxhY2UoJ3t1c2VySWR9JywgdXNlcklkKTtcbiAgICAgICAgY29uc3QgcGF5bG9hZDogUGF5bG9hZCA9IHt9O1xuICAgICAgICBpZiAodHlwZW9mIGVtYWlsVmVyaWZpY2F0aW9uICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgcGF5bG9hZFsnZW1haWxWZXJpZmljYXRpb24nXSA9IGVtYWlsVmVyaWZpY2F0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVyaSA9IG5ldyBVUkwodGhpcy5jbGllbnQuY29uZmlnLmVuZHBvaW50ICsgYXBpUGF0aCk7XG5cbiAgICAgICAgY29uc3QgYXBpSGVhZGVyczogeyBbaGVhZGVyOiBzdHJpbmddOiBzdHJpbmcgfSA9IHtcbiAgICAgICAgICAgICdjb250ZW50LXR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5jbGllbnQuY2FsbChcbiAgICAgICAgICAgICdwYXRjaCcsXG4gICAgICAgICAgICB1cmksXG4gICAgICAgICAgICBhcGlIZWFkZXJzLFxuICAgICAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogVXBkYXRlIHBob25lIHZlcmlmaWNhdGlvblxuICAgICAqXG4gICAgICogVXBkYXRlIHRoZSB1c2VyIHBob25lIHZlcmlmaWNhdGlvbiBzdGF0dXMgYnkgaXRzIHVuaXF1ZSBJRC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VySWRcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHBob25lVmVyaWZpY2F0aW9uXG4gICAgICogQHRocm93cyB7QXBwY29uZGFFeGNlcHRpb259XG4gICAgICogQHJldHVybnMge1Byb21pc2U8TW9kZWxzLlVzZXI8UHJlZmVyZW5jZXM+Pn1cbiAgICAgKi9cbiAgICBhc3luYyB1cGRhdGVQaG9uZVZlcmlmaWNhdGlvbjxQcmVmZXJlbmNlcyBleHRlbmRzIE1vZGVscy5QcmVmZXJlbmNlcz4odXNlcklkOiBzdHJpbmcsIHBob25lVmVyaWZpY2F0aW9uOiBib29sZWFuKTogUHJvbWlzZTxNb2RlbHMuVXNlcjxQcmVmZXJlbmNlcz4+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB1c2VySWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgQXBwY29uZGFFeGNlcHRpb24oJ01pc3NpbmcgcmVxdWlyZWQgcGFyYW1ldGVyOiBcInVzZXJJZFwiJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBwaG9uZVZlcmlmaWNhdGlvbiA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBBcHBjb25kYUV4Y2VwdGlvbignTWlzc2luZyByZXF1aXJlZCBwYXJhbWV0ZXI6IFwicGhvbmVWZXJpZmljYXRpb25cIicpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGFwaVBhdGggPSAnL3VzZXJzL3t1c2VySWR9L3ZlcmlmaWNhdGlvbi9waG9uZScucmVwbGFjZSgne3VzZXJJZH0nLCB1c2VySWQpO1xuICAgICAgICBjb25zdCBwYXlsb2FkOiBQYXlsb2FkID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgcGhvbmVWZXJpZmljYXRpb24gIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBwYXlsb2FkWydwaG9uZVZlcmlmaWNhdGlvbiddID0gcGhvbmVWZXJpZmljYXRpb247XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXJpID0gbmV3IFVSTCh0aGlzLmNsaWVudC5jb25maWcuZW5kcG9pbnQgKyBhcGlQYXRoKTtcblxuICAgICAgICBjb25zdCBhcGlIZWFkZXJzOiB7IFtoZWFkZXI6IHN0cmluZ106IHN0cmluZyB9ID0ge1xuICAgICAgICAgICAgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmNsaWVudC5jYWxsKFxuICAgICAgICAgICAgJ3BhdGNoJyxcbiAgICAgICAgICAgIHVyaSxcbiAgICAgICAgICAgIGFwaUhlYWRlcnMsXG4gICAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICApO1xuICAgIH1cbn1cbiJdfQ==