radio.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import { ChangeDetectorRef, Directive, ElementRef, forwardRef, Input, Renderer2 } from '@angular/core';
  6. import { NG_VALUE_ACCESSOR } from '@angular/forms';
  7. import { NgbButtonLabel } from './label';
  8. /** @type {?} */
  9. const NGB_RADIO_VALUE_ACCESSOR = {
  10. provide: NG_VALUE_ACCESSOR,
  11. useExisting: forwardRef((/**
  12. * @return {?}
  13. */
  14. () => NgbRadioGroup)),
  15. multi: true
  16. };
  17. /** @type {?} */
  18. let nextId = 0;
  19. /**
  20. * Allows to easily create Bootstrap-style radio buttons.
  21. *
  22. * Integrates with forms, so the value of a checked button is bound to the underlying form control
  23. * either in a reactive or template-driven way.
  24. */
  25. export class NgbRadioGroup {
  26. constructor() {
  27. this._radios = new Set();
  28. this._value = null;
  29. /**
  30. * Name of the radio group applied to radio input elements.
  31. *
  32. * Will be applied to all radio input elements inside the group,
  33. * unless [`NgbRadio`](#/components/buttons/api#NgbRadio)'s specify names themselves.
  34. *
  35. * If not provided, will be generated in the `ngb-radio-xx` format.
  36. */
  37. this.name = `ngb-radio-${nextId++}`;
  38. this.onChange = (/**
  39. * @param {?} _
  40. * @return {?}
  41. */
  42. (_) => { });
  43. this.onTouched = (/**
  44. * @return {?}
  45. */
  46. () => { });
  47. }
  48. /**
  49. * @return {?}
  50. */
  51. get disabled() { return this._disabled; }
  52. /**
  53. * @param {?} isDisabled
  54. * @return {?}
  55. */
  56. set disabled(isDisabled) { this.setDisabledState(isDisabled); }
  57. /**
  58. * @param {?} radio
  59. * @return {?}
  60. */
  61. onRadioChange(radio) {
  62. this.writeValue(radio.value);
  63. this.onChange(radio.value);
  64. }
  65. /**
  66. * @return {?}
  67. */
  68. onRadioValueUpdate() { this._updateRadiosValue(); }
  69. /**
  70. * @param {?} radio
  71. * @return {?}
  72. */
  73. register(radio) { this._radios.add(radio); }
  74. /**
  75. * @param {?} fn
  76. * @return {?}
  77. */
  78. registerOnChange(fn) { this.onChange = fn; }
  79. /**
  80. * @param {?} fn
  81. * @return {?}
  82. */
  83. registerOnTouched(fn) { this.onTouched = fn; }
  84. /**
  85. * @param {?} isDisabled
  86. * @return {?}
  87. */
  88. setDisabledState(isDisabled) {
  89. this._disabled = isDisabled;
  90. this._updateRadiosDisabled();
  91. }
  92. /**
  93. * @param {?} radio
  94. * @return {?}
  95. */
  96. unregister(radio) { this._radios.delete(radio); }
  97. /**
  98. * @param {?} value
  99. * @return {?}
  100. */
  101. writeValue(value) {
  102. this._value = value;
  103. this._updateRadiosValue();
  104. }
  105. /**
  106. * @private
  107. * @return {?}
  108. */
  109. _updateRadiosValue() { this._radios.forEach((/**
  110. * @param {?} radio
  111. * @return {?}
  112. */
  113. (radio) => radio.updateValue(this._value))); }
  114. /**
  115. * @private
  116. * @return {?}
  117. */
  118. _updateRadiosDisabled() { this._radios.forEach((/**
  119. * @param {?} radio
  120. * @return {?}
  121. */
  122. (radio) => radio.updateDisabled())); }
  123. }
  124. NgbRadioGroup.decorators = [
  125. { type: Directive, args: [{ selector: '[ngbRadioGroup]', host: { 'role': 'radiogroup' }, providers: [NGB_RADIO_VALUE_ACCESSOR] },] }
  126. ];
  127. NgbRadioGroup.propDecorators = {
  128. name: [{ type: Input }]
  129. };
  130. if (false) {
  131. /**
  132. * @type {?}
  133. * @private
  134. */
  135. NgbRadioGroup.prototype._radios;
  136. /**
  137. * @type {?}
  138. * @private
  139. */
  140. NgbRadioGroup.prototype._value;
  141. /**
  142. * @type {?}
  143. * @private
  144. */
  145. NgbRadioGroup.prototype._disabled;
  146. /**
  147. * Name of the radio group applied to radio input elements.
  148. *
  149. * Will be applied to all radio input elements inside the group,
  150. * unless [`NgbRadio`](#/components/buttons/api#NgbRadio)'s specify names themselves.
  151. *
  152. * If not provided, will be generated in the `ngb-radio-xx` format.
  153. * @type {?}
  154. */
  155. NgbRadioGroup.prototype.name;
  156. /** @type {?} */
  157. NgbRadioGroup.prototype.onChange;
  158. /** @type {?} */
  159. NgbRadioGroup.prototype.onTouched;
  160. }
  161. /**
  162. * A directive that marks an input of type "radio" as a part of the
  163. * [`NgbRadioGroup`](#/components/buttons/api#NgbRadioGroup).
  164. */
  165. export class NgbRadio {
  166. /**
  167. * @param {?} _group
  168. * @param {?} _label
  169. * @param {?} _renderer
  170. * @param {?} _element
  171. * @param {?} _cd
  172. */
  173. constructor(_group, _label, _renderer, _element, _cd) {
  174. this._group = _group;
  175. this._label = _label;
  176. this._renderer = _renderer;
  177. this._element = _element;
  178. this._cd = _cd;
  179. this._value = null;
  180. this._group.register(this);
  181. this.updateDisabled();
  182. }
  183. /**
  184. * The form control value when current radio button is checked.
  185. * @param {?} value
  186. * @return {?}
  187. */
  188. set value(value) {
  189. this._value = value;
  190. /** @type {?} */
  191. const stringValue = value ? value.toString() : '';
  192. this._renderer.setProperty(this._element.nativeElement, 'value', stringValue);
  193. this._group.onRadioValueUpdate();
  194. }
  195. /**
  196. * If `true`, current radio button will be disabled.
  197. * @param {?} isDisabled
  198. * @return {?}
  199. */
  200. set disabled(isDisabled) {
  201. this._disabled = isDisabled !== false;
  202. this.updateDisabled();
  203. }
  204. /**
  205. * @param {?} isFocused
  206. * @return {?}
  207. */
  208. set focused(isFocused) {
  209. if (this._label) {
  210. this._label.focused = isFocused;
  211. }
  212. if (!isFocused) {
  213. this._group.onTouched();
  214. }
  215. }
  216. /**
  217. * @return {?}
  218. */
  219. get checked() { return this._checked; }
  220. /**
  221. * @return {?}
  222. */
  223. get disabled() { return this._group.disabled || this._disabled; }
  224. /**
  225. * @return {?}
  226. */
  227. get value() { return this._value; }
  228. /**
  229. * @return {?}
  230. */
  231. get nameAttr() { return this.name || this._group.name; }
  232. /**
  233. * @return {?}
  234. */
  235. ngOnDestroy() { this._group.unregister(this); }
  236. /**
  237. * @return {?}
  238. */
  239. onChange() { this._group.onRadioChange(this); }
  240. /**
  241. * @param {?} value
  242. * @return {?}
  243. */
  244. updateValue(value) {
  245. // label won't be updated, if it is inside the OnPush component when [ngModel] changes
  246. if (this.value !== value) {
  247. this._cd.markForCheck();
  248. }
  249. this._checked = this.value === value;
  250. this._label.active = this._checked;
  251. }
  252. /**
  253. * @return {?}
  254. */
  255. updateDisabled() { this._label.disabled = this.disabled; }
  256. }
  257. NgbRadio.decorators = [
  258. { type: Directive, args: [{
  259. selector: '[ngbButton][type=radio]',
  260. host: {
  261. '[checked]': 'checked',
  262. '[disabled]': 'disabled',
  263. '[name]': 'nameAttr',
  264. '(change)': 'onChange()',
  265. '(focus)': 'focused = true',
  266. '(blur)': 'focused = false'
  267. }
  268. },] }
  269. ];
  270. /** @nocollapse */
  271. NgbRadio.ctorParameters = () => [
  272. { type: NgbRadioGroup },
  273. { type: NgbButtonLabel },
  274. { type: Renderer2 },
  275. { type: ElementRef },
  276. { type: ChangeDetectorRef }
  277. ];
  278. NgbRadio.propDecorators = {
  279. name: [{ type: Input }],
  280. value: [{ type: Input, args: ['value',] }],
  281. disabled: [{ type: Input, args: ['disabled',] }]
  282. };
  283. if (false) {
  284. /**
  285. * @type {?}
  286. * @private
  287. */
  288. NgbRadio.prototype._checked;
  289. /**
  290. * @type {?}
  291. * @private
  292. */
  293. NgbRadio.prototype._disabled;
  294. /**
  295. * @type {?}
  296. * @private
  297. */
  298. NgbRadio.prototype._value;
  299. /**
  300. * The value for the 'name' property of the input element.
  301. *
  302. * All inputs of the radio group should have the same name. If not specified,
  303. * the name of the enclosing group is used.
  304. * @type {?}
  305. */
  306. NgbRadio.prototype.name;
  307. /**
  308. * @type {?}
  309. * @private
  310. */
  311. NgbRadio.prototype._group;
  312. /**
  313. * @type {?}
  314. * @private
  315. */
  316. NgbRadio.prototype._label;
  317. /**
  318. * @type {?}
  319. * @private
  320. */
  321. NgbRadio.prototype._renderer;
  322. /**
  323. * @type {?}
  324. * @private
  325. */
  326. NgbRadio.prototype._element;
  327. /**
  328. * @type {?}
  329. * @private
  330. */
  331. NgbRadio.prototype._cd;
  332. }
  333. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFkaW8uanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AbmctYm9vdHN0cmFwL25nLWJvb3RzdHJhcC8iLCJzb3VyY2VzIjpbImJ1dHRvbnMvcmFkaW8udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBQyxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQWEsU0FBUyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ2hILE9BQU8sRUFBdUIsaUJBQWlCLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUV2RSxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sU0FBUyxDQUFDOztNQUVqQyx3QkFBd0IsR0FBRztJQUMvQixPQUFPLEVBQUUsaUJBQWlCO0lBQzFCLFdBQVcsRUFBRSxVQUFVOzs7SUFBQyxHQUFHLEVBQUUsQ0FBQyxhQUFhLEVBQUM7SUFDNUMsS0FBSyxFQUFFLElBQUk7Q0FDWjs7SUFFRyxNQUFNLEdBQUcsQ0FBQzs7Ozs7OztBQVNkLE1BQU0sT0FBTyxhQUFhO0lBRDFCO1FBRVUsWUFBTyxHQUFrQixJQUFJLEdBQUcsRUFBWSxDQUFDO1FBQzdDLFdBQU0sR0FBRyxJQUFJLENBQUM7Ozs7Ozs7OztRQWNiLFNBQUksR0FBRyxhQUFhLE1BQU0sRUFBRSxFQUFFLENBQUM7UUFFeEMsYUFBUTs7OztRQUFHLENBQUMsQ0FBTSxFQUFFLEVBQUUsR0FBRSxDQUFDLEVBQUM7UUFDMUIsY0FBUzs7O1FBQUcsR0FBRyxFQUFFLEdBQUUsQ0FBQyxFQUFDO0lBNkJ2QixDQUFDOzs7O0lBM0NDLElBQUksUUFBUSxLQUFLLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7Ozs7O0lBQ3pDLElBQUksUUFBUSxDQUFDLFVBQW1CLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQzs7Ozs7SUFleEUsYUFBYSxDQUFDLEtBQWU7UUFDM0IsSUFBSSxDQUFDLFVBQVUsQ0FB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USxHQUFHLElBQUksQ0FBQyxLQUFLLEtBQUssS0FBSyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDckMsQ0FBQzs7OztJQUVELGNBQWMsS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQzs7O1lBbEYzRCxTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLHlCQUF5QjtnQkFDbkMsSUFBSSxFQUFFO29CQUNKLFdBQVcsRUFBRSxTQUFTO29CQUN0QixZQUFZLEVBQUUsVUFBVTtvQkFDeEIsUUFBUSxFQUFFLFVBQVU7b0JBQ3BCLFVBQVUsRUFBRSxZQUFZO29CQUN4QixTQUFTLEVBQUUsZ0JBQWdCO29CQUMzQixRQUFRLEVBQUUsaUJBQWlCO2lCQUM1QjthQUNGOzs7O1lBb0RxQixhQUFhO1lBdEkzQixjQUFjO1lBSDBELFNBQVM7WUFBbkQsVUFBVTtZQUF4QyxpQkFBaUI7OzttQkFpR3RCLEtBQUs7b0JBS0wsS0FBSyxTQUFDLE9BQU87dUJBV2IsS0FBSyxTQUFDLFVBQVU7Ozs7Ozs7SUExQmpCLDRCQUEwQjs7Ozs7SUFDMUIsNkJBQTJCOzs7OztJQUMzQiwwQkFBMkI7Ozs7Ozs7O0lBUTNCLHdCQUFzQjs7Ozs7SUF3Q2xCLDBCQUE2Qjs7Ozs7SUFBRSwwQkFBOEI7Ozs7O0lBQUUsNkJBQTRCOzs7OztJQUMzRiw0QkFBOEM7Ozs7O0lBQUUsdUJBQThCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFuZ2VEZXRlY3RvclJlZiwgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBmb3J3YXJkUmVmLCBJbnB1dCwgT25EZXN0cm95LCBSZW5kZXJlcjJ9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1J9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHtOZ2JCdXR0b25MYWJlbH0gZnJvbSAnLi9sYWJlbCc7XG5cbmNvbnN0IE5HQl9SQURJT19WQUxVRV9BQ0NFU1NPUiA9IHtcbiAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE5nYlJhZGlvR3JvdXApLFxuICBtdWx0aTogdHJ1ZVxufTtcblxubGV0IG5leHRJZCA9IDA7XG5cbi8qKlxuICogQWxsb3dzIHRvIGVhc2lseSBjcmVhdGUgQm9vdHN0cmFwLXN0eWxlIHJhZGlvIGJ1dHRvbnMuXG4gKlxuICogSW50ZWdyYXRlcyB3aXRoIGZvcm1zLCBzbyB0aGUgdmFsdWUgb2YgYSBjaGVja2VkIGJ1dHRvbiBpcyBib3VuZCB0byB0aGUgdW5kZXJseWluZyBmb3JtIGNvbnRyb2xcbiAqIGVpdGhlciBpbiBhIHJlYWN0aXZlIG9yIHRlbXBsYXRlLWRyaXZlbiB3YXkuXG4gKi9cbkBEaXJlY3RpdmUoe3NlbGVjdG9yOiAnW25nYlJhZGlvR3JvdXBdJywgaG9zdDogeydyb2xlJzogJ3JhZGlvZ3JvdXAnfSwgcHJvdmlkZXJzOiBbTkdCX1JBRElPX1ZBTFVFX0FDQ0VTU09SXX0pXG5leHBvcnQgY2xhc3MgTmdiUmFkaW9Hcm91cCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgcHJpdmF0ZSBfcmFkaW9zOiBTZXQ8TmdiUmFkaW8+ID0gbmV3IFNldDxOZ2JSYWRpbz4oKTtcbiAgcHJpdmF0ZSBfdmFsdWUgPSBudWxsO1xuICBwcml2YXRlIF9kaXNhYmxlZDogYm9vbGVhbjtcblxuICBnZXQgZGlzYWJsZWQoKSB7IHJldHVybiB0aGlzLl9kaXNhYmxlZDsgfVxuICBzZXQgZGlzYWJsZWQoaXNEaXNhYmxlZDogYm9vbGVhbikgeyB0aGlzLnNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZCk7IH1cblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgcmFkaW8gZ3JvdXAgYXBwbGllZCB0byByYWRpbyBpbnB1dCBlbGVtZW50cy5cbiAgICpcbiAgICogV2lsbCBiZSBhcHBsaWVkIHRvIGFsbCByYWRpbyBpbnB1dCBlbGVtZW50cyBpbnNpZGUgdGhlIGdyb3VwLFxuICAgKiB1bmxlc3MgW2BOZ2JSYWRpb2BdKCMvY29tcG9uZW50cy9idXR0b25zL2FwaSNOZ2JSYWRpbykncyBzcGVjaWZ5IG5hbWVzIHRoZW1zZWx2ZXMuXG4gICAqXG4gICAqIElmIG5vdCBwcm92aWRlZCwgd2lsbCBiZSBnZW5lcmF0ZWQgaW4gdGhlIGBuZ2ItcmFkaW8teHhgIGZvcm1hdC5cbiAgICovXG4gIEBJbnB1dCgpIG5hbWUgPSBgbmdiLXJhZGlvLSR7bmV4dElkKyt9YDtcblxuICBvbkNoYW5nZSA9IChfOiBhbnkpID0+IHt9O1xuICBvblRvdWNoZWQgPSAoKSA9PiB7fTtcblxuICBvblJhZGlvQ2hhbmdlKHJhZGlvOiBOZ2JSYWRpbykge1xuICAgIHRoaXMud3JpdGVWYWx1ZShyYWRpby52YWx1ZSk7XG4gICAgdGhpcy5vbkNoYW5nZShyYWRpby52YWx1ZSk7XG4gIH1cblxuICBvblJhZGlvVmFsdWVVcGRhdGUoKSB7IHRoaXMuX3VwZGF0ZVJhZGlvc1ZhbHVlKCk7IH1cblxuICByZWdpc3RlcihyYWRpbzogTmdiUmFkaW8pIHsgdGhpcy5fcmFkaW9zLmFkZChyYWRpbyk7IH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAodmFsdWU6IGFueSkgPT4gYW55KTogdm9pZCB7IHRoaXMub25DaGFuZ2UgPSBmbjsgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiAoKSA9PiBhbnkpOiB2b2lkIHsgdGhpcy5vblRvdWNoZWQgPSBmbjsgfVxuXG4gIHNldERpc2FibGVkU3RhdGUoaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuX2Rpc2FibGVkID0gaXNEaXNhYmxlZDtcbiAgICB0aGlzLl91cGRhdGVSYWRpb3NEaXNhYmxlZCgpO1xuICB9XG5cbiAgdW5yZWdpc3RlcihyYWRpbzogTmdiUmFkaW8pIHsgdGhpcy5fcmFkaW9zLmRlbGV0ZShyYWRpbyk7IH1cblxuICB3cml0ZVZhbHVlKHZhbHVlKSB7XG4gICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcbiAgICB0aGlzLl91cGRhdGVSYWRpb3NWYWx1ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBfdXBkYXRlUmFkaW9zVmFsdWUoKSB7IHRoaXMuX3JhZGlvcy5mb3JFYWNoKChyYWRpbykgPT4gcmFkaW8udXBkYXRlVmFsdWUodGhpcy5fdmFsdWUpKTsgfVxuICBwcml2YXRlIF91cGRhdGVSYWRpb3NEaXNhYmxlZCgpIHsgdGhpcy5fcmFkaW9zLmZvckVhY2goKHJhZGlvKSA9PiByYWRpby51cGRhdGVEaXNhYmxlZCgpKTsgfVxufVxuXG5cbi8qKlxuICogQSBkaXJlY3RpdmUgdGhhdCBtYXJrcyBhbiBpbnB1dCBvZiB0eXBlIFwicmFkaW9cIiBhcyBhIHBhcnQgb2YgdGhlXG4gKiBbYE5nYlJhZGlvR3JvdXBgXSgjL2NvbXBvbmVudHMvYnV0dG9ucy9hcGkjTmdiUmFkaW9Hcm91cCkuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tuZ2JCdXR0b25dW3R5cGU9cmFkaW9dJyxcbiAgaG9zdDoge1xuICAgICdbY2hlY2tlZF0nOiAnY2hlY2tlZCcsXG4gICAgJ1tkaXNhYmxlZF0nOiAnZGlzYWJsZWQnLFxuICAgICdbbmFtZV0nOiAnbmFtZUF0dHInLFxuICAgICcoY2hhbmdlKSc6ICdvbkNoYW5nZSgpJyxcbiAgICAnKGZvY3VzKSc6ICdmb2N1c2VkID0gdHJ1ZScsXG4gICAgJyhibHVyKSc6ICdmb2N1c2VkID0gZmFsc2UnXG4gIH1cbn0pXG5leHBvcnQgY2xhc3MgTmdiUmFkaW8gaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIF9jaGVja2VkOiBib29sZWFuO1xuICBwcml2YXRlIF9kaXNhYmxlZDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBfdmFsdWU6IGFueSA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFRoZSB2YWx1ZSBmb3IgdGhlICduYW1lJyBwcm9wZXJ0eSBvZiB0aGUgaW5wdXQgZWxlbWVudC5cbiAgICpcbiAgICogQWxsIGlucHV0cyBvZiB0aGUgcmFkaW8gZ3JvdXAgc2hvdWxkIGhhdmUgdGhlIHNhbWUgbmFtZS4gSWYgbm90IHNwZWNpZmllZCxcbiAgICogdGhlIG5hbWUgb2YgdGhlIGVuY2xvc2luZyBncm91cCBpcyB1c2VkLlxuICAgKi9cbiAgQElucHV0KCkgbmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZm9ybSBjb250cm9sIHZhbHVlIHdoZW4gY3VycmVudCByYWRpbyBidXR0b24gaXMgY2hlY2tlZC5cbiAgICovXG4gIEBJbnB1dCgndmFsdWUnKVxuICBzZXQgdmFsdWUodmFsdWU6IGFueSkge1xuICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7XG4gICAgY29uc3Qgc3RyaW5nVmFsdWUgPSB2YWx1ZSA/IHZhbHVlLnRvU3RyaW5nKCkgOiAnJztcbiAgICB0aGlzLl9yZW5kZXJlci5zZXRQcm9wZXJ0eSh0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQsICd2YWx1ZScsIHN0cmluZ1ZhbHVlKTtcbiAgICB0aGlzLl9ncm91cC5vblJhZGlvVmFsdWVVcGRhdGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZiBgdHJ1ZWAsIGN1cnJlbnQgcmFkaW8gYnV0dG9uIHdpbGwgYmUgZGlzYWJsZWQuXG4gICAqL1xuICBASW5wdXQoJ2Rpc2FibGVkJylcbiAgc2V0IGRpc2FibGVkKGlzRGlzYWJsZWQ6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9kaXNhYmxlZCA9IGlzRGlzYWJsZWQgIT09IGZhbHNlO1xuICAgIHRoaXMudXBkYXRlRGlzYWJsZWQoKTtcbiAgfVxuXG4gIHNldCBmb2N1c2VkKGlzRm9jdXNlZDogYm9vbGVhbikge1xuICAgIGlmICh0aGlzLl9sYWJlbCkge1xuICAgICAgdGhpcy5fbGFiZWwuZm9jdXNlZCA9IGlzRm9jdXNlZDtcbiAgICB9XG4gICAgaWYgKCFpc0ZvY3VzZWQpIHtcbiAgICAgIHRoaXMuX2dyb3VwLm9uVG91Y2hlZCgpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBjaGVja2VkKCkgeyByZXR1cm4gdGhpcy5fY2hlY2tlZDsgfVxuXG4gIGdldCBkaXNhYmxlZCgpIHsgcmV0dXJuIHRoaXMuX2dyb3VwLmRpc2FibGVkIHx8IHRoaXMuX2Rpc2FibGVkOyB9XG5cbiAgZ2V0IHZhbHVlKCkgeyByZXR1cm4gdGhpcy5fdmFsdWU7IH1cblxuICBnZXQgbmFtZUF0dHIoKSB7IHJldHVybiB0aGlzLm5hbWUgfHwgdGhpcy5fZ3JvdXAubmFtZTsgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHJpdmF0ZSBfZ3JvdXA6IE5nYlJhZGlvR3JvdXAsIHByaXZhdGUgX2xhYmVsOiBOZ2JCdXR0b25MYWJlbCwgcHJpdmF0ZSBfcmVuZGVyZXI6IFJlbmRlcmVyMixcbiAgICAgIHByaXZhdGUgX2VsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTElucHV0RWxlbWVudD4sIHByaXZhdGUgX2NkOiBDaGFuZ2VEZXRlY3RvclJlZikge1xuICAgIHRoaXMuX2dyb3VwLnJlZ2lzdGVyKHRoaXMpO1xuICAgIHRoaXMudXBkYXRlRGlzYWJsZWQoKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkgeyB0aGlzLl9ncm91cC51bnJlZ2lzdGVyKHRoaXMpOyB9XG5cbiAgb25DaGFuZ2UoKSB7IHRoaXMuX2dyb3VwLm9uUmFkaW9DaGFuZ2UodGhpcyk7IH1cblxuICB1cGRhdGVWYWx1ZSh2YWx1ZSkge1xuICAgIC8vIGxhYmVsIHdvbid0IGJlIHVwZGF0ZWQsIGlmIGl0IGlzIGluc2lkZSB0aGUgT25QdXNoIGNvbXBvbmVudCB3aGVuIFtuZ01vZGVsXSBjaGFuZ2VzXG4gICAgaWYgKHRoaXMudmFsdWUgIT09IHZhbHVlKSB7XG4gICAgICB0aGlzLl9jZC5tYXJrRm9yQ2hlY2soKTtcbiAgICB9XG5cbiAgICB0aGlzLl9jaGVja2VkID0gdGhpcy52YWx1ZSA9PT0gdmFsdWU7XG4gICAgdGhpcy5fbGFiZWwuYWN0aXZlID0gdGhpcy5fY2hlY2tlZDtcbiAgfVxuXG4gIHVwZGF0ZURpc2FibGVkKCkgeyB0aGlzLl9sYWJlbC5kaXNhYmxlZCA9IHRoaXMuZGlzYWJsZWQ7IH1cbn1cbiJdfQ==