http.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. import { provide } from 'angular2/core';
  2. import { Http, Jsonp } from './src/http/http';
  3. import { XHRBackend } from './src/http/backends/xhr_backend';
  4. import { JSONPBackend, JSONPBackend_ } from './src/http/backends/jsonp_backend';
  5. import { BrowserXhr } from './src/http/backends/browser_xhr';
  6. import { BrowserJsonp } from './src/http/backends/browser_jsonp';
  7. import { BaseRequestOptions, RequestOptions } from './src/http/base_request_options';
  8. import { BaseResponseOptions, ResponseOptions } from './src/http/base_response_options';
  9. export { Request } from './src/http/static_request';
  10. export { Response } from './src/http/static_response';
  11. export { Connection, ConnectionBackend } from './src/http/interfaces';
  12. export { BrowserXhr } from './src/http/backends/browser_xhr';
  13. export { BaseRequestOptions, RequestOptions } from './src/http/base_request_options';
  14. export { BaseResponseOptions, ResponseOptions } from './src/http/base_response_options';
  15. export { XHRBackend, XHRConnection } from './src/http/backends/xhr_backend';
  16. export { JSONPBackend, JSONPConnection } from './src/http/backends/jsonp_backend';
  17. export { Http, Jsonp } from './src/http/http';
  18. export { Headers } from './src/http/headers';
  19. export { ResponseType, ReadyState, RequestMethod } from './src/http/enums';
  20. export { URLSearchParams } from './src/http/url_search_params';
  21. /**
  22. * Provides a basic set of injectables to use the {@link Http} service in any application.
  23. *
  24. * The `HTTP_PROVIDERS` should be included either in a component's injector,
  25. * or in the root injector when bootstrapping an application.
  26. *
  27. * ### Example ([live demo](http://plnkr.co/edit/snj7Nv?p=preview))
  28. *
  29. * ```
  30. * import {Component} from 'angular2/core';
  31. * import {bootstrap} from 'angular2/platform/browser';
  32. * import {NgFor} from 'angular2/common';
  33. * import {HTTP_PROVIDERS, Http} from 'angular2/http';
  34. *
  35. * @Component({
  36. * selector: 'app',
  37. * providers: [HTTP_PROVIDERS],
  38. * template: `
  39. * <div>
  40. * <h1>People</h1>
  41. * <ul>
  42. * <li *ngFor="#person of people">
  43. * {{person.name}}
  44. * </li>
  45. * </ul>
  46. * </div>
  47. * `,
  48. * directives: [NgFor]
  49. * })
  50. * export class App {
  51. * people: Object[];
  52. * constructor(http:Http) {
  53. * http.get('people.json').subscribe(res => {
  54. * this.people = res.json();
  55. * });
  56. * }
  57. * active:boolean = false;
  58. * toggleActiveState() {
  59. * this.active = !this.active;
  60. * }
  61. * }
  62. *
  63. * bootstrap(App)
  64. * .catch(err => console.error(err));
  65. * ```
  66. *
  67. * The primary public API included in `HTTP_PROVIDERS` is the {@link Http} class.
  68. * However, other providers required by `Http` are included,
  69. * which may be beneficial to override in certain cases.
  70. *
  71. * The providers included in `HTTP_PROVIDERS` include:
  72. * * {@link Http}
  73. * * {@link XHRBackend}
  74. * * `BrowserXHR` - Private factory to create `XMLHttpRequest` instances
  75. * * {@link RequestOptions} - Bound to {@link BaseRequestOptions} class
  76. * * {@link ResponseOptions} - Bound to {@link BaseResponseOptions} class
  77. *
  78. * There may be cases where it makes sense to extend the base request options,
  79. * such as to add a search string to be appended to all URLs.
  80. * To accomplish this, a new provider for {@link RequestOptions} should
  81. * be added in the same injector as `HTTP_PROVIDERS`.
  82. *
  83. * ### Example ([live demo](http://plnkr.co/edit/aCMEXi?p=preview))
  84. *
  85. * ```
  86. * import {provide} from 'angular2/core';
  87. * import {bootstrap} from 'angular2/platform/browser';
  88. * import {HTTP_PROVIDERS, BaseRequestOptions, RequestOptions} from 'angular2/http';
  89. *
  90. * class MyOptions extends BaseRequestOptions {
  91. * search: string = 'coreTeam=true';
  92. * }
  93. *
  94. * bootstrap(App, [HTTP_PROVIDERS, provide(RequestOptions, {useClass: MyOptions})])
  95. * .catch(err => console.error(err));
  96. * ```
  97. *
  98. * Likewise, to use a mock backend for unit tests, the {@link XHRBackend}
  99. * provider should be bound to {@link MockBackend}.
  100. *
  101. * ### Example ([live demo](http://plnkr.co/edit/7LWALD?p=preview))
  102. *
  103. * ```
  104. * import {provide} from 'angular2/core';
  105. * import {bootstrap} from 'angular2/platform/browser';
  106. * import {HTTP_PROVIDERS, Http, Response, XHRBackend} from 'angular2/http';
  107. * import {MockBackend} from 'angular2/http/testing';
  108. *
  109. * var people = [{name: 'Jeff'}, {name: 'Tobias'}];
  110. *
  111. * var injector = Injector.resolveAndCreate([
  112. * HTTP_PROVIDERS,
  113. * MockBackend,
  114. * provide(XHRBackend, {useExisting: MockBackend})
  115. * ]);
  116. * var http = injector.get(Http);
  117. * var backend = injector.get(MockBackend);
  118. *
  119. * // Listen for any new requests
  120. * backend.connections.observer({
  121. * next: connection => {
  122. * var response = new Response({body: people});
  123. * setTimeout(() => {
  124. * // Send a response to the request
  125. * connection.mockRespond(response);
  126. * });
  127. * });
  128. *
  129. * http.get('people.json').observer({
  130. * next: res => {
  131. * // Response came from mock backend
  132. * console.log('first person', res.json()[0].name);
  133. * }
  134. * });
  135. * ```
  136. */
  137. export const HTTP_PROVIDERS = [
  138. // TODO(pascal): use factory type annotations once supported in DI
  139. // issue: https://github.com/angular/angular/issues/3183
  140. provide(Http, {
  141. useFactory: (xhrBackend, requestOptions) => new Http(xhrBackend, requestOptions),
  142. deps: [XHRBackend, RequestOptions]
  143. }),
  144. BrowserXhr,
  145. provide(RequestOptions, { useClass: BaseRequestOptions }),
  146. provide(ResponseOptions, { useClass: BaseResponseOptions }),
  147. XHRBackend
  148. ];
  149. /**
  150. * See {@link HTTP_PROVIDERS} instead.
  151. *
  152. * @deprecated
  153. */
  154. export const HTTP_BINDINGS = HTTP_PROVIDERS;
  155. /**
  156. * Provides a basic set of providers to use the {@link Jsonp} service in any application.
  157. *
  158. * The `JSONP_PROVIDERS` should be included either in a component's injector,
  159. * or in the root injector when bootstrapping an application.
  160. *
  161. * ### Example ([live demo](http://plnkr.co/edit/vmeN4F?p=preview))
  162. *
  163. * ```
  164. * import {Component} from 'angular2/core';
  165. * import {NgFor} from 'angular2/common';
  166. * import {JSONP_PROVIDERS, Jsonp} from 'angular2/http';
  167. *
  168. * @Component({
  169. * selector: 'app',
  170. * providers: [JSONP_PROVIDERS],
  171. * template: `
  172. * <div>
  173. * <h1>People</h1>
  174. * <ul>
  175. * <li *ngFor="#person of people">
  176. * {{person.name}}
  177. * </li>
  178. * </ul>
  179. * </div>
  180. * `,
  181. * directives: [NgFor]
  182. * })
  183. * export class App {
  184. * people: Array<Object>;
  185. * constructor(jsonp:Jsonp) {
  186. * jsonp.request('people.json').subscribe(res => {
  187. * this.people = res.json();
  188. * })
  189. * }
  190. * }
  191. * ```
  192. *
  193. * The primary public API included in `JSONP_PROVIDERS` is the {@link Jsonp} class.
  194. * However, other providers required by `Jsonp` are included,
  195. * which may be beneficial to override in certain cases.
  196. *
  197. * The providers included in `JSONP_PROVIDERS` include:
  198. * * {@link Jsonp}
  199. * * {@link JSONPBackend}
  200. * * `BrowserJsonp` - Private factory
  201. * * {@link RequestOptions} - Bound to {@link BaseRequestOptions} class
  202. * * {@link ResponseOptions} - Bound to {@link BaseResponseOptions} class
  203. *
  204. * There may be cases where it makes sense to extend the base request options,
  205. * such as to add a search string to be appended to all URLs.
  206. * To accomplish this, a new provider for {@link RequestOptions} should
  207. * be added in the same injector as `JSONP_PROVIDERS`.
  208. *
  209. * ### Example ([live demo](http://plnkr.co/edit/TFug7x?p=preview))
  210. *
  211. * ```
  212. * import {provide} from 'angular2/core';
  213. * import {bootstrap} from 'angular2/platform/browser';
  214. * import {JSONP_PROVIDERS, BaseRequestOptions, RequestOptions} from 'angular2/http';
  215. *
  216. * class MyOptions extends BaseRequestOptions {
  217. * search: string = 'coreTeam=true';
  218. * }
  219. *
  220. * bootstrap(App, [JSONP_PROVIDERS, provide(RequestOptions, {useClass: MyOptions})])
  221. * .catch(err => console.error(err));
  222. * ```
  223. *
  224. * Likewise, to use a mock backend for unit tests, the {@link JSONPBackend}
  225. * provider should be bound to {@link MockBackend}.
  226. *
  227. * ### Example ([live demo](http://plnkr.co/edit/HDqZWL?p=preview))
  228. *
  229. * ```
  230. * import {provide, Injector} from 'angular2/core';
  231. * import {JSONP_PROVIDERS, Jsonp, Response, JSONPBackend} from 'angular2/http';
  232. * import {MockBackend} from 'angular2/http/testing';
  233. *
  234. * var people = [{name: 'Jeff'}, {name: 'Tobias'}];
  235. * var injector = Injector.resolveAndCreate([
  236. * JSONP_PROVIDERS,
  237. * MockBackend,
  238. * provide(JSONPBackend, {useExisting: MockBackend})
  239. * ]);
  240. * var jsonp = injector.get(Jsonp);
  241. * var backend = injector.get(MockBackend);
  242. *
  243. * // Listen for any new requests
  244. * backend.connections.observer({
  245. * next: connection => {
  246. * var response = new Response({body: people});
  247. * setTimeout(() => {
  248. * // Send a response to the request
  249. * connection.mockRespond(response);
  250. * });
  251. * });
  252. * jsonp.get('people.json').observer({
  253. * next: res => {
  254. * // Response came from mock backend
  255. * console.log('first person', res.json()[0].name);
  256. * }
  257. * });
  258. * ```
  259. */
  260. export const JSONP_PROVIDERS = [
  261. // TODO(pascal): use factory type annotations once supported in DI
  262. // issue: https://github.com/angular/angular/issues/3183
  263. provide(Jsonp, {
  264. useFactory: (jsonpBackend, requestOptions) => new Jsonp(jsonpBackend, requestOptions),
  265. deps: [JSONPBackend, RequestOptions]
  266. }),
  267. BrowserJsonp,
  268. provide(RequestOptions, { useClass: BaseRequestOptions }),
  269. provide(ResponseOptions, { useClass: BaseResponseOptions }),
  270. provide(JSONPBackend, { useClass: JSONPBackend_ })
  271. ];
  272. /**
  273. * See {@link JSONP_PROVIDERS} instead.
  274. *
  275. * @deprecated
  276. */
  277. export const JSON_BINDINGS = JSONP_PROVIDERS;
  278. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImFuZ3VsYXIyL2h0dHAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ik9BTU8sRUFBQyxPQUFPLEVBQVcsTUFBTSxlQUFlO09BQ3hDLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBQyxNQUFNLGlCQUFpQjtPQUNwQyxFQUFDLFVBQVUsRUFBZ0IsTUFBTSxpQ0FBaUM7T0FDbEUsRUFBQyxZQUFZLEVBQUUsYUFBYSxFQUFrQixNQUFNLG1DQUFtQztPQUN2RixFQUFDLFVBQVUsRUFBQyxNQUFNLGlDQUFpQztPQUNuRCxFQUFDLFlBQVksRUFBQyxNQUFNLG1DQUFtQztPQUN2RCxFQUFDLGtCQUFrQixFQUFFLGNBQWMsRUFBQyxNQUFNLGlDQUFpQztPQUUzRSxFQUFDLG1CQUFtQixFQUFFLGVBQWUsRUFBQyxNQUFNLGtDQUFrQztBQUNyRixTQUFRLE9BQU8sUUFBTywyQkFBMkIsQ0FBQztBQUNsRCxTQUFRLFFBQVEsUUFBTyw0QkFBNEIsQ0FBQztBQUVwRCxTQUdFLFVBQVUsRUFDVixpQkFBaUIsUUFDWix1QkFBdUIsQ0FBQztBQUUvQixTQUFRLFVBQVUsUUFBTyxpQ0FBaUMsQ0FBQztBQUMzRCxTQUFRLGtCQUFrQixFQUFFLGNBQWMsUUFBTyxpQ0FBaUMsQ0FBQztBQUNuRixTQUFRLG1CQUFtQixFQUFFLGVBQWUsUUFBTyxrQ0FBa0MsQ0FBQztBQUN0RixTQUFRLFVBQVUsRUFBRSxhQUFhLFFBQU8saUNBQWlDLENBQUM7QUFDMUUsU0FBUSxZQUFZLEVBQUUsZUFBZSxRQUFPLG1DQUFtQyxDQUFDO0FBQ2hGLFNBQVEsSUFBSSxFQUFFLEtBQUssUUFBTyxpQkFBaUIsQ0FBQztBQUU1QyxTQUFRLE9BQU8sUUFBTyxvQkFBb0IsQ0FBQztBQUUzQyxTQUFRLFlBQVksRUFBRSxVQUFVLEVBQUUsYUFBYSxRQUFPLGtCQUFrQixDQUFDO0FBQ3pFLFNBQVEsZUFBZSxRQUFPLDhCQUE4QixDQUFDO0FBRTdEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUhHO0FBQ0gsYUFBYSxjQUFjLEdBQVU7SUFDbkMsa0VBQWtFO0lBQ2xFLHdEQUF3RDtJQUN4RCxPQUFPLENBQUMsSUFBSSxFQUNKO1FBQ0UsVUFBVSxFQUFFLENBQUMsVUFBVSxFQUFFLGNBQWMsS0FBSyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsY0FBYyxDQUFDO1FBQ2hGLElBQUksRUFBRSxDQUFDLFVBQVUsRUFBRSxjQUFjLENBQUM7S0FDbkMsQ0FBQztJQUNWLFVBQVU7SUFDVixPQUFPLENBQUMsY0FBYyxFQUFFLEVBQUMsUUFBUSxFQUFFLGtCQUFrQixFQUFDLENBQUM7SUFDdkQsT0FBTyxDQUFDLGVBQWUsRUFBRSxFQUFDLFFBQVEsRUFBRSxtQkFBbUIsRUFBQyxDQUFDO0lBQ3pELFVBQVU7Q0FDWCxDQUFDO0FBRUY7Ozs7R0FJRztBQUNILGFBQWEsYUFBYSxHQUFHLGNBQWMsQ0FBQztBQUU1Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUdHO0FBQ0gsYUFBYSxlQUFlLEdBQVU7SUFDcEMsa0VBQWtFO0lBQ2xFLHdEQUF3RDtJQUN4RCxPQUFPLENBQUMsS0FBSyxFQUNMO1FBQ0UsVUFBVSxFQUFFLENBQUMsWUFBWSxFQUFFLGNBQWMsS0FBSyxJQUFJLEtBQUssQ0FBQyxZQUFZLEVBQUUsY0FBYyxDQUFDO1FBQ3JGLElBQUksRUFBRSxDQUFDLFlBQVksRUFBRSxjQUFjLENBQUM7S0FDckMsQ0FBQztJQUNWLFlBQVk7SUFDWixPQUFPLENBQUMsY0FBYyxFQUFFLEVBQUMsUUFBUSxFQUFFLGtCQUFrQixFQUFDLENBQUM7SUFDdkQsT0FBTyxDQUFDLGVBQWUsRUFBRSxFQUFDLFFBQVEsRUFBRSxtQkFBbUIsRUFBQyxDQUFDO0lBQ3pELE9BQU8sQ0FBQyxZQUFZLEVBQUUsRUFBQyxRQUFRLEVBQUUsYUFBYSxFQUFDLENBQUM7Q0FDakQsQ0FBQztBQUVGOzs7O0dBSUc7QUFDSCxhQUFhLGFBQWEsR0FBRyxlQUFlLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBtb2R1bGVcbiAqIEBkZXNjcmlwdGlvblxuICogVGhlIGh0dHAgbW9kdWxlIHByb3ZpZGVzIHNlcnZpY2VzIHRvIHBlcmZvcm0gaHR0cCByZXF1ZXN0cy4gVG8gZ2V0IHN0YXJ0ZWQsIHNlZSB0aGUge0BsaW5rIEh0dHB9XG4gKiBjbGFzcy5cbiAqL1xuaW1wb3J0IHtwcm92aWRlLCBQcm92aWRlcn0gZnJvbSAnYW5ndWxhcjIvY29yZSc7XG5pbXBvcnQge0h0dHAsIEpzb25wfSBmcm9tICcuL3NyYy9odHRwL2h0dHAnO1xuaW1wb3J0IHtYSFJCYWNrZW5kLCBYSFJDb25uZWN0aW9ufSBmcm9tICcuL3NyYy9odHRwL2JhY2tlbmRzL3hocl9iYWNrZW5kJztcbmltcG9ydCB7SlNPTlBCYWNrZW5kLCBKU09OUEJhY2tlbmRfLCBKU09OUENvbm5lY3Rpb259IGZyb20gJy4vc3JjL2h0dHAvYmFja2VuZHMvanNvbnBfYmFja2VuZCc7XG5pbXBvcnQge0Jyb3dzZXJYaHJ9IGZyb20gJy4vc3JjL2h0dHAvYmFja2VuZHMvYnJvd3Nlcl94aHInO1xuaW1wb3J0IHtCcm93c2VySnNvbnB9IGZyb20gJy4vc3JjL2h0dHAvYmFja2VuZHMvYnJvd3Nlcl9qc29ucCc7XG5pbXBvcnQge0Jhc2VSZXF1ZXN0T3B0aW9ucywgUmVxdWVzdE9wdGlvbnN9IGZyb20gJy4vc3JjL2h0dHAvYmFzZV9yZXF1ZXN0X29wdGlvbnMnO1xuaW1wb3J0IHtDb25uZWN0aW9uQmFja2VuZH0gZnJvbSAnLi9zcmMvaHR0cC9pbnRlcmZhY2VzJztcbmltcG9ydCB7QmFzZVJlc3BvbnNlT3B0aW9ucywgUmVzcG9uc2VPcHRpb25zfSBmcm9tICcuL3NyYy9odHRwL2Jhc2VfcmVzcG9uc2Vfb3B0aW9ucyc7XG5leHBvcnQge1JlcXVlc3R9IGZyb20gJy4vc3JjL2h0dHAvc3RhdGljX3JlcXVlc3QnO1xuZXhwb3J0IHtSZXNwb25zZX0gZnJvbSAnLi9zcmMvaHR0cC9zdGF0aWNfcmVzcG9uc2UnO1xuXG5leHBvcnQge1xuICBSZXF1ZXN0T3B0aW9uc0FyZ3MsXG4gIFJlc3BvbnNlT3B0aW9uc0FyZ3MsXG4gIENvbm5lY3Rpb24sXG4gIENvbm5lY3Rpb25CYWNrZW5kXG59IGZyb20gJy4vc3JjL2h0dHAvaW50ZXJmYWNlcyc7XG5cbmV4cG9ydCB7QnJvd3Nlclhocn0gZnJvbSAnLi9zcmMvaHR0cC9iYWNrZW5kcy9icm93c2VyX3hocic7XG5leHBvcnQge0Jhc2VSZXF1ZXN0T3B0aW9ucywgUmVxdWVzdE9wdGlvbnN9IGZyb20gJy4vc3JjL2h0dHAvYmFzZV9yZXF1ZXN0X29wdGlvbnMnO1xuZXhwb3J0IHtCYXNlUmVzcG9uc2VPcHRpb25zLCBSZXNwb25zZU9wdGlvbnN9IGZyb20gJy4vc3JjL2h0dHAvYmFzZV9yZXNwb25zZV9vcHRpb25zJztcbmV4cG9ydCB7WEhSQmFja2VuZCwgWEhSQ29ubmVjdGlvbn0gZnJvbSAnLi9zcmMvaHR0cC9iYWNrZW5kcy94aHJfYmFja2VuZCc7XG5leHBvcnQge0pTT05QQmFja2VuZCwgSlNPTlBDb25uZWN0aW9ufSBmcm9tICcuL3NyYy9odHRwL2JhY2tlbmRzL2pzb25wX2JhY2tlbmQnO1xuZXhwb3J0IHtIdHRwLCBKc29ucH0gZnJvbSAnLi9zcmMvaHR0cC9odHRwJztcblxuZXhwb3J0IHtIZWFkZXJzfSBmcm9tICcuL3NyYy9odHRwL2hlYWRlcnMnO1xuXG5leHBvcnQge1Jlc3BvbnNlVHlwZSwgUmVhZHlTdGF0ZSwgUmVxdWVzdE1ldGhvZH0gZnJvbSAnLi9zcmMvaHR0cC9lbnVtcyc7XG5leHBvcnQge1VSTFNlYXJjaFBhcmFtc30gZnJvbSAnLi9zcmMvaHR0cC91cmxfc2VhcmNoX3BhcmFtcyc7XG5cbi8qKlxuICogUHJvdmlkZXMgYSBiYXNpYyBzZXQgb2YgaW5qZWN0YWJsZXMgdG8gdXNlIHRoZSB7QGxpbmsgSHR0cH0gc2VydmljZSBpbiBhbnkgYXBwbGljYXRpb24uXG4gKlxuICogVGhlIGBIVFRQX1BST1ZJREVSU2Agc2hvdWxkIGJlIGluY2x1ZGVkIGVpdGhlciBpbiBhIGNvbXBvbmVudCdzIGluamVjdG9yLFxuICogb3IgaW4gdGhlIHJvb3QgaW5qZWN0b3Igd2hlbiBib290c3RyYXBwaW5nIGFuIGFwcGxpY2F0aW9uLlxuICpcbiAqICMjIyBFeGFtcGxlIChbbGl2ZSBkZW1vXShodHRwOi8vcGxua3IuY28vZWRpdC9zbmo3TnY/cD1wcmV2aWV3KSlcbiAqXG4gKiBgYGBcbiAqIGltcG9ydCB7Q29tcG9uZW50fSBmcm9tICdhbmd1bGFyMi9jb3JlJztcbiAqIGltcG9ydCB7Ym9vdHN0cmFwfSBmcm9tICdhbmd1bGFyMi9wbGF0Zm9ybS9icm93c2VyJztcbiAqIGltcG9ydCB7TmdGb3J9IGZyb20gJ2FuZ3VsYXIyL2NvbW1vbic7XG4gKiBpbXBvcnQge0hUVFBfUFJPVklERVJTLCBIdHRwfSBmcm9tICdhbmd1bGFyMi9odHRwJztcbiAqXG4gKiBAQ29tcG9uZW50KHtcbiAqICAgc2VsZWN0b3I6ICdhcHAnLFxuICogICBwcm92aWRlcnM6IFtIVFRQX1BST1ZJREVSU10sXG4gKiAgIHRlbXBsYXRlOiBgXG4gKiAgICAgPGRpdj5cbiAqICAgICAgIDxoMT5QZW9wbGU8L2gxPlxuICogICAgICAgPHVsPlxuICogICAgICAgICA8bGkgKm5nRm9yPVwiI3BlcnNvbiBvZiBwZW9wbGVcIj5cbiAqICAgICAgICAgICB7e3BlcnNvbi5uYW1lfX1cbiAqICAgICAgICAgPC9saT5cbiAqICAgICAgIDwvdWw+XG4gKiAgICAgPC9kaXY+XG4gKiAgIGAsXG4gKiAgIGRpcmVjdGl2ZXM6IFtOZ0Zvcl1cbiAqIH0pXG4gKiBleHBvcnQgY2xhc3MgQXBwIHtcbiAqICAgcGVvcGxlOiBPYmplY3RbXTtcbiAqICAgY29uc3RydWN0b3IoaHR0cDpIdHRwKSB7XG4gKiAgICAgaHR0cC5nZXQoJ3Blb3BsZS5qc29uJykuc3Vic2NyaWJlKHJlcyA9PiB7XG4gKiAgICAgICB0aGlzLnBlb3BsZSA9IHJlcy5qc29uKCk7XG4gKiAgICAgfSk7XG4gKiAgIH1cbiAqICAgYWN0aXZlOmJvb2xlYW4gPSBmYWxzZTtcbiAqICAgdG9nZ2xlQWN0aXZlU3RhdGUoKSB7XG4gKiAgICAgdGhpcy5hY3RpdmUgPSAhdGhpcy5hY3RpdmU7XG4gKiAgIH1cbiAqIH1cbiAqXG4gKiBib290c3RyYXAoQXBwKVxuICogICAuY2F0Y2goZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSk7XG4gKiBgYGBcbiAqXG4gKiBUaGUgcHJpbWFyeSBwdWJsaWMgQVBJIGluY2x1ZGVkIGluIGBIVFRQX1BST1ZJREVSU2AgaXMgdGhlIHtAbGluayBIdHRwfSBjbGFzcy5cbiAqIEhvd2V2ZXIsIG90aGVyIHByb3ZpZGVycyByZXF1aXJlZCBieSBgSHR0cGAgYXJlIGluY2x1ZGVkLFxuICogd2hpY2ggbWF5IGJlIGJlbmVmaWNpYWwgdG8gb3ZlcnJpZGUgaW4gY2VydGFpbiBjYXNlcy5cbiAqXG4gKiBUaGUgcHJvdmlkZXJzIGluY2x1ZGVkIGluIGBIVFRQX1BST1ZJREVSU2AgaW5jbHVkZTpcbiAqICAqIHtAbGluayBIdHRwfVxuICogICoge0BsaW5rIFhIUkJhY2tlbmR9XG4gKiAgKiBgQnJvd3NlclhIUmAgLSBQcml2YXRlIGZhY3RvcnkgdG8gY3JlYXRlIGBYTUxIdHRwUmVxdWVzdGAgaW5zdGFuY2VzXG4gKiAgKiB7QGxpbmsgUmVxdWVzdE9wdGlvbnN9IC0gQm91bmQgdG8ge0BsaW5rIEJhc2VSZXF1ZXN0T3B0aW9uc30gY2xhc3NcbiAqICAqIHtAbGluayBSZXNwb25zZU9wdGlvbnN9IC0gQm91bmQgdG8ge0BsaW5rIEJhc2VSZXNwb25zZU9wdGlvbnN9IGNsYXNzXG4gKlxuICogVGhlcmUgbWF5IGJlIGNhc2VzIHdoZXJlIGl0IG1ha2VzIHNlbnNlIHRvIGV4dGVuZCB0aGUgYmFzZSByZXF1ZXN0IG9wdGlvbnMsXG4gKiBzdWNoIGFzIHRvIGFkZCBhIHNlYXJjaCBzdHJpbmcgdG8gYmUgYXBwZW5kZWQgdG8gYWxsIFVSTHMuXG4gKiBUbyBhY2NvbXBsaXNoIHRoaXMsIGEgbmV3IHByb3ZpZGVyIGZvciB7QGxpbmsgUmVxdWVzdE9wdGlvbnN9IHNob3VsZFxuICogYmUgYWRkZWQgaW4gdGhlIHNhbWUgaW5qZWN0b3IgYXMgYEhUVFBfUFJPVklERVJTYC5cbiAqXG4gKiAjIyMgRXhhbXBsZSAoW2xpdmUgZGVtb10oaHR0cDovL3BsbmtyLmNvL2VkaXQvYUNNRVhpP3A9cHJldmlldykpXG4gKlxuICogYGBgXG4gKiBpbXBvcnQge3Byb3ZpZGV9IGZyb20gJ2FuZ3VsYXIyL2NvcmUnO1xuICogaW1wb3J0IHtib290c3RyYXB9IGZyb20gJ2FuZ3VsYXIyL3BsYXRmb3JtL2Jyb3dzZXInO1xuICogaW1wb3J0IHtIVFRQX1BST1ZJREVSUywgQmFzZVJlcXVlc3RPcHRpb25zLCBSZXF1ZXN0T3B0aW9uc30gZnJvbSAnYW5ndWxhcjIvaHR0cCc7XG4gKlxuICogY2xhc3MgTXlPcHRpb25zIGV4dGVuZHMgQmFzZVJlcXVlc3RPcHRpb25zIHtcbiAqICAgc2VhcmNoOiBzdHJpbmcgPSAnY29yZVRlYW09dHJ1ZSc7XG4gKiB9XG4gKlxuICogYm9vdHN0cmFwKEFwcCwgW0hUVFBfUFJPVklERVJTLCBwcm92aWRlKFJlcXVlc3RPcHRpb25zLCB7dXNlQ2xhc3M6IE15T3B0aW9uc30pXSlcbiAqICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmVycm9yKGVycikpO1xuICogYGBgXG4gKlxuICogTGlrZXdpc2UsIHRvIHVzZSBhIG1vY2sgYmFja2VuZCBmb3IgdW5pdCB0ZXN0cywgdGhlIHtAbGluayBYSFJCYWNrZW5kfVxuICogcHJvdmlkZXIgc2hvdWxkIGJlIGJvdW5kIHRvIHtAbGluayBNb2NrQmFja2VuZH0uXG4gKlxuICogIyMjIEV4YW1wbGUgKFtsaXZlIGRlbW9dKGh0dHA6Ly9wbG5rci5jby9lZGl0LzdMV0FMRD9wPXByZXZpZXcpKVxuICpcbiAqIGBgYFxuICogaW1wb3J0IHtwcm92aWRlfSBmcm9tICdhbmd1bGFyMi9jb3JlJztcbiAqIGltcG9ydCB7Ym9vdHN0cmFwfSBmcm9tICdhbmd1bGFyMi9wbGF0Zm9ybS9icm93c2VyJztcbiAqIGltcG9ydCB7SFRUUF9QUk9WSURFUlMsIEh0dHAsIFJlc3BvbnNlLCBYSFJCYWNrZW5kfSBmcm9tICdhbmd1bGFyMi9odHRwJztcbiAqIGltcG9ydCB7TW9ja0JhY2tlbmR9IGZyb20gJ2FuZ3VsYXIyL2h0dHAvdGVzdGluZyc7XG4gKlxuICogdmFyIHBlb3BsZSA9IFt7bmFtZTogJ0plZmYnfSwge25hbWU6ICdUb2JpYXMnfV07XG4gKlxuICogdmFyIGluamVjdG9yID0gSW5qZWN0b3IucmVzb2x2ZUFuZENyZWF0ZShbXG4gKiAgIEhUVFBfUFJPVklERVJTLFxuICogICBNb2NrQmFja2VuZCxcbiAqICAgcHJvdmlkZShYSFJCYWNrZW5kLCB7dXNlRXhpc3Rpbmc6IE1vY2tCYWNrZW5kfSlcbiAqIF0pO1xuICogdmFyIGh0dHAgPSBpbmplY3Rvci5nZXQoSHR0cCk7XG4gKiB2YXIgYmFja2VuZCA9IGluamVjdG9yLmdldChNb2NrQmFja2VuZCk7XG4gKlxuICogLy8gTGlzdGVuIGZvciBhbnkgbmV3IHJlcXVlc3RzXG4gKiBiYWNrZW5kLmNvbm5lY3Rpb25zLm9ic2VydmVyKHtcbiAqICAgbmV4dDogY29ubmVjdGlvbiA9PiB7XG4gKiAgICAgdmFyIHJlc3BvbnNlID0gbmV3IFJlc3BvbnNlKHtib2R5OiBwZW9wbGV9KTtcbiAqICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAqICAgICAgIC8vIFNlbmQgYSByZXNwb25zZSB0byB0aGUgcmVxdWVzdFxuICogICAgICAgY29ubmVjdGlvbi5tb2NrUmVzcG9uZChyZXNwb25zZSk7XG4gKiAgICAgfSk7XG4gKiAgIH0pO1xuICpcbiAqIGh0dHAuZ2V0KCdwZW9wbGUuanNvbicpLm9ic2VydmVyKHtcbiAqICAgbmV4dDogcmVzID0+IHtcbiAqICAgICAvLyBSZXNwb25zZSBjYW1lIGZyb20gbW9jayBiYWNrZW5kXG4gKiAgICAgY29uc29sZS5sb2coJ2ZpcnN0IHBlcnNvbicsIHJlcy5qc29uKClbMF0ubmFtZSk7XG4gKiAgIH1cbiAqIH0pO1xuICogYGBgXG4gKi9cbmV4cG9ydCBjb25zdCBIVFRQX1BST1ZJREVSUzogYW55W10gPSBbXG4gIC8vIFRPRE8ocGFzY2FsKTogdXNlIGZhY3RvcnkgdHlwZSBhbm5vdGF0aW9ucyBvbmNlIHN1cHBvcnRlZCBpbiBESVxuICAvLyBpc3N1ZTogaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci9pc3N1ZXMvMzE4M1xuICBwcm92aWRlKEh0dHAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXNlRmFjdG9yeTogKHhockJhY2tlbmQsIHJlcXVlc3RPcHRpb25zKSA9PiBuZXcgSHR0cCh4aHJCYWNrZW5kLCByZXF1ZXN0T3B0aW9ucyksXG4gICAgICAgICAgICBkZXBzOiBbWEhSQmFja2VuZCwgUmVxdWVzdE9wdGlvbnNdXG4gICAgICAgICAgfSksXG4gIEJyb3dzZXJYaHIsXG4gIHByb3ZpZGUoUmVxdWVzdE9wdGlvbnMsIHt1c2VDbGFzczogQmFzZVJlcXVlc3RPcHRpb25zfSksXG4gIHByb3ZpZGUoUmVzcG9uc2VPcHRpb25zLCB7dXNlQ2xhc3M6IEJhc2VSZXNwb25zZU9wdGlvbnN9KSxcbiAgWEhSQmFja2VuZFxuXTtcblxuLyoqXG4gKiBTZWUge0BsaW5rIEhUVFBfUFJPVklERVJTfSBpbnN0ZWFkLlxuICpcbiAqIEBkZXByZWNhdGVkXG4gKi9cbmV4cG9ydCBjb25zdCBIVFRQX0JJTkRJTkdTID0gSFRUUF9QUk9WSURFUlM7XG5cbi8qKlxuICogUHJvdmlkZXMgYSBiYXNpYyBzZXQgb2YgcHJvdmlkZXJzIHRvIHVzZSB0aGUge0BsaW5rIEpzb25wfSBzZXJ2aWNlIGluIGFueSBhcHBsaWNhdGlvbi5cbiAqXG4gKiBUaGUgYEpTT05QX1BST1ZJREVSU2Agc2hvdWxkIGJlIGluY2x1ZGVkIGVpdGhlciBpbiBhIGNvbXBvbmVudCdzIGluamVjdG9yLFxuICogb3IgaW4gdGhlIHJvb3QgaW5qZWN0b3Igd2hlbiBib290c3RyYXBwaW5nIGFuIGFwcGxpY2F0aW9uLlxuICpcbiAqICMjIyBFeGFtcGxlIChbbGl2ZSBkZW1vXShodHRwOi8vcGxua3IuY28vZWRpdC92bWVONEY/cD1wcmV2aWV3KSlcbiAqXG4gKiBgYGBcbiAqIGltcG9ydCB7Q29tcG9uZW50fSBmcm9tICdhbmd1bGFyMi9jb3JlJztcbiAqIGltcG9ydCB7TmdGb3J9IGZyb20gJ2FuZ3VsYXIyL2NvbW1vbic7XG4gKiBpbXBvcnQge0pTT05QX1BST1ZJREVSUywgSnNvbnB9IGZyb20gJ2FuZ3VsYXIyL2h0dHAnO1xuICpcbiAqIEBDb21wb25lbnQoe1xuICogICBzZWxlY3RvcjogJ2FwcCcsXG4gKiAgIHByb3ZpZGVyczogW0pTT05QX1BST1ZJREVSU10sXG4gKiAgIHRlbXBsYXRlOiBgXG4gKiAgICAgPGRpdj5cbiAqICAgICAgIDxoMT5QZW9wbGU8L2gxPlxuICogICAgICAgPHVsPlxuICogICAgICAgICA8bGkgKm5nRm9yPVwiI3BlcnNvbiBvZiBwZW9wbGVcIj5cbiAqICAgICAgICAgICB7e3BlcnNvbi5uYW1lfX1cbiAqICAgICAgICAgPC9saT5cbiAqICAgICAgIDwvdWw+XG4gKiAgICAgPC9kaXY+XG4gKiAgIGAsXG4gKiAgIGRpcmVjdGl2ZXM6IFtOZ0Zvcl1cbiAqIH0pXG4gKiBleHBvcnQgY2xhc3MgQXBwIHtcbiAqICAgcGVvcGxlOiBBcnJheTxPYmplY3Q+O1xuICogICBjb25zdHJ1Y3Rvcihqc29ucDpKc29ucCkge1xuICogICAgIGpzb25wLnJlcXVlc3QoJ3Blb3BsZS5qc29uJykuc3Vic2NyaWJlKHJlcyA9PiB7XG4gKiAgICAgICB0aGlzLnBlb3BsZSA9IHJlcy5qc29uKCk7XG4gKiAgICAgfSlcbiAqICAgfVxuICogfVxuICogYGBgXG4gKlxuICogVGhlIHByaW1hcnkgcHVibGljIEFQSSBpbmNsdWRlZCBpbiBgSlNPTlBfUFJPVklERVJTYCBpcyB0aGUge0BsaW5rIEpzb25wfSBjbGFzcy5cbiAqIEhvd2V2ZXIsIG90aGVyIHByb3ZpZGVycyByZXF1aXJlZCBieSBgSnNvbnBgIGFyZSBpbmNsdWRlZCxcbiAqIHdoaWNoIG1heSBiZSBiZW5lZmljaWFsIHRvIG92ZXJyaWRlIGluIGNlcnRhaW4gY2FzZXMuXG4gKlxuICogVGhlIHByb3ZpZGVycyBpbmNsdWRlZCBpbiBgSlNPTlBfUFJPVklERVJTYCBpbmNsdWRlOlxuICogICoge0BsaW5rIEpzb25wfVxuICogICoge0BsaW5rIEpTT05QQmFja2VuZH1cbiAqICAqIGBCcm93c2VySnNvbnBgIC0gUHJpdmF0ZSBmYWN0b3J5XG4gKiAgKiB7QGxpbmsgUmVxdWVzdE9wdGlvbnN9IC0gQm91bmQgdG8ge0BsaW5rIEJhc2VSZXF1ZXN0T3B0aW9uc30gY2xhc3NcbiAqICAqIHtAbGluayBSZXNwb25zZU9wdGlvbnN9IC0gQm91bmQgdG8ge0BsaW5rIEJhc2VSZXNwb25zZU9wdGlvbnN9IGNsYXNzXG4gKlxuICogVGhlcmUgbWF5IGJlIGNhc2VzIHdoZXJlIGl0IG1ha2VzIHNlbnNlIHRvIGV4dGVuZCB0aGUgYmFzZSByZXF1ZXN0IG9wdGlvbnMsXG4gKiBzdWNoIGFzIHRvIGFkZCBhIHNlYXJjaCBzdHJpbmcgdG8gYmUgYXBwZW5kZWQgdG8gYWxsIFVSTHMuXG4gKiBUbyBhY2NvbXBsaXNoIHRoaXMsIGEgbmV3IHByb3ZpZGVyIGZvciB7QGxpbmsgUmVxdWVzdE9wdGlvbnN9IHNob3VsZFxuICogYmUgYWRkZWQgaW4gdGhlIHNhbWUgaW5qZWN0b3IgYXMgYEpTT05QX1BST1ZJREVSU2AuXG4gKlxuICogIyMjIEV4YW1wbGUgKFtsaXZlIGRlbW9dKGh0dHA6Ly9wbG5rci5jby9lZGl0L1RGdWc3eD9wPXByZXZpZXcpKVxuICpcbiAqIGBgYFxuICogaW1wb3J0IHtwcm92aWRlfSBmcm9tICdhbmd1bGFyMi9jb3JlJztcbiAqIGltcG9ydCB7Ym9vdHN0cmFwfSBmcm9tICdhbmd1bGFyMi9wbGF0Zm9ybS9icm93c2VyJztcbiAqIGltcG9ydCB7SlNPTlBfUFJPVklERVJTLCBCYXNlUmVxdWVzdE9wdGlvbnMsIFJlcXVlc3RPcHRpb25zfSBmcm9tICdhbmd1bGFyMi9odHRwJztcbiAqXG4gKiBjbGFzcyBNeU9wdGlvbnMgZXh0ZW5kcyBCYXNlUmVxdWVzdE9wdGlvbnMge1xuICogICBzZWFyY2g6IHN0cmluZyA9ICdjb3JlVGVhbT10cnVlJztcbiAqIH1cbiAqXG4gKiBib290c3RyYXAoQXBwLCBbSlNPTlBfUFJPVklERVJTLCBwcm92aWRlKFJlcXVlc3RPcHRpb25zLCB7dXNlQ2xhc3M6IE15T3B0aW9uc30pXSlcbiAqICAgLmNhdGNoKGVyciA9PiBjb25zb2xlLmVycm9yKGVycikpO1xuICogYGBgXG4gKlxuICogTGlrZXdpc2UsIHRvIHVzZSBhIG1vY2sgYmFja2VuZCBmb3IgdW5pdCB0ZXN0cywgdGhlIHtAbGluayBKU09OUEJhY2tlbmR9XG4gKiBwcm92aWRlciBzaG91bGQgYmUgYm91bmQgdG8ge0BsaW5rIE1vY2tCYWNrZW5kfS5cbiAqXG4gKiAjIyMgRXhhbXBsZSAoW2xpdmUgZGVtb10oaHR0cDovL3BsbmtyLmNvL2VkaXQvSERxWldMP3A9cHJldmlldykpXG4gKlxuICogYGBgXG4gKiBpbXBvcnQge3Byb3ZpZGUsIEluamVjdG9yfSBmcm9tICdhbmd1bGFyMi9jb3JlJztcbiAqIGltcG9ydCB7SlNPTlBfUFJPVklERVJTLCBKc29ucCwgUmVzcG9uc2UsIEpTT05QQmFja2VuZH0gZnJvbSAnYW5ndWxhcjIvaHR0cCc7XG4gKiBpbXBvcnQge01vY2tCYWNrZW5kfSBmcm9tICdhbmd1bGFyMi9odHRwL3Rlc3RpbmcnO1xuICpcbiAqIHZhciBwZW9wbGUgPSBbe25hbWU6ICdKZWZmJ30sIHtuYW1lOiAnVG9iaWFzJ31dO1xuICogdmFyIGluamVjdG9yID0gSW5qZWN0b3IucmVzb2x2ZUFuZENyZWF0ZShbXG4gKiAgIEpTT05QX1BST1ZJREVSUyxcbiAqICAgTW9ja0JhY2tlbmQsXG4gKiAgIHByb3ZpZGUoSlNPTlBCYWNrZW5kLCB7dXNlRXhpc3Rpbmc6IE1vY2tCYWNrZW5kfSlcbiAqIF0pO1xuICogdmFyIGpzb25wID0gaW5qZWN0b3IuZ2V0KEpzb25wKTtcbiAqIHZhciBiYWNrZW5kID0gaW5qZWN0b3IuZ2V0KE1vY2tCYWNrZW5kKTtcbiAqXG4gKiAvLyBMaXN0ZW4gZm9yIGFueSBuZXcgcmVxdWVzdHNcbiAqIGJhY2tlbmQuY29ubmVjdGlvbnMub2JzZXJ2ZXIoe1xuICogICBuZXh0OiBjb25uZWN0aW9uID0+IHtcbiAqICAgICB2YXIgcmVzcG9uc2UgPSBuZXcgUmVzcG9uc2Uoe2JvZHk6IHBlb3BsZX0pO1xuICogICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICogICAgICAgLy8gU2VuZCBhIHJlc3BvbnNlIHRvIHRoZSByZXF1ZXN0XG4gKiAgICAgICBjb25uZWN0aW9uLm1vY2tSZXNwb25kKHJlc3BvbnNlKTtcbiAqICAgICB9KTtcbiAqICAgfSk7XG5cbiAqIGpzb25wLmdldCgncGVvcGxlLmpzb24nKS5vYnNlcnZlcih7XG4gKiAgIG5leHQ6IHJlcyA9PiB7XG4gKiAgICAgLy8gUmVzcG9uc2UgY2FtZSBmcm9tIG1vY2sgYmFja2VuZFxuICogICAgIGNvbnNvbGUubG9nKCdmaXJzdCBwZXJzb24nLCByZXMuanNvbigpWzBdLm5hbWUpO1xuICogICB9XG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgY29uc3QgSlNPTlBfUFJPVklERVJTOiBhbnlbXSA9IFtcbiAgLy8gVE9ETyhwYXNjYWwpOiB1c2UgZmFjdG9yeSB0eXBlIGFubm90YXRpb25zIG9uY2Ugc3VwcG9ydGVkIGluIERJXG4gIC8vIGlzc3VlOiBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyL2lzc3Vlcy8zMTgzXG4gIHByb3ZpZGUoSnNvbnAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgdXNlRmFjdG9yeTogKGpzb25wQmFja2VuZCwgcmVxdWVzdE9wdGlvbnMpID0+IG5ldyBKc29ucChqc29ucEJhY2tlbmQsIHJlcXVlc3RPcHRpb25zKSxcbiAgICAgICAgICAgIGRlcHM6IFtKU09OUEJhY2tlbmQsIFJlcXVlc3RPcHRpb25zXVxuICAgICAgICAgIH0pLFxuICBCcm93c2VySnNvbnAsXG4gIHByb3ZpZGUoUmVxdWVzdE9wdGlvbnMsIHt1c2VDbGFzczogQmFzZVJlcXVlc3RPcHRpb25zfSksXG4gIHByb3ZpZGUoUmVzcG9uc2VPcHRpb25zLCB7dXNlQ2xhc3M6IEJhc2VSZXNwb25zZU9wdGlvbnN9KSxcbiAgcHJvdmlkZShKU09OUEJhY2tlbmQsIHt1c2VDbGFzczogSlNPTlBCYWNrZW5kX30pXG5dO1xuXG4vKipcbiAqIFNlZSB7QGxpbmsgSlNPTlBfUFJPVklERVJTfSBpbnN0ZWFkLlxuICpcbiAqIEBkZXByZWNhdGVkXG4gKi9cbmV4cG9ydCBjb25zdCBKU09OX0JJTkRJTkdTID0gSlNPTlBfUFJPVklERVJTO1xuIl19