math.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /**
  2. * @fileoverview added by tsickle
  3. * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4. */
  5. import { columnsByPin, columnsTotalWidth } from './column';
  6. /**
  7. * Calculates the Total Flex Grow
  8. * @param {?} columns
  9. * @return {?}
  10. */
  11. export function getTotalFlexGrow(columns) {
  12. /** @type {?} */
  13. let totalFlexGrow = 0;
  14. for (const c of columns) {
  15. totalFlexGrow += c.flexGrow || 0;
  16. }
  17. return totalFlexGrow;
  18. }
  19. /**
  20. * Adjusts the column widths.
  21. * Inspired by: https://github.com/facebook/fixed-data-table/blob/master/src/FixedDataTableWidthHelper.js
  22. * @param {?} allColumns
  23. * @param {?} expectedWidth
  24. * @return {?}
  25. */
  26. export function adjustColumnWidths(allColumns, expectedWidth) {
  27. /** @type {?} */
  28. const columnsWidth = columnsTotalWidth(allColumns);
  29. /** @type {?} */
  30. const totalFlexGrow = getTotalFlexGrow(allColumns);
  31. /** @type {?} */
  32. const colsByGroup = columnsByPin(allColumns);
  33. if (columnsWidth !== expectedWidth) {
  34. scaleColumns(colsByGroup, expectedWidth, totalFlexGrow);
  35. }
  36. }
  37. /**
  38. * Resizes columns based on the flexGrow property, while respecting manually set widths
  39. * @param {?} colsByGroup
  40. * @param {?} maxWidth
  41. * @param {?} totalFlexGrow
  42. * @return {?}
  43. */
  44. function scaleColumns(colsByGroup, maxWidth, totalFlexGrow) {
  45. // calculate total width and flexgrow points for coulumns that can be resized
  46. for (const attr in colsByGroup) {
  47. for (const column of colsByGroup[attr]) {
  48. if (!column.canAutoResize) {
  49. maxWidth -= column.width;
  50. totalFlexGrow -= column.flexGrow ? column.flexGrow : 0;
  51. }
  52. else {
  53. column.width = 0;
  54. }
  55. }
  56. }
  57. /** @type {?} */
  58. const hasMinWidth = {};
  59. /** @type {?} */
  60. let remainingWidth = maxWidth;
  61. // resize columns until no width is left to be distributed
  62. do {
  63. /** @type {?} */
  64. const widthPerFlexPoint = remainingWidth / totalFlexGrow;
  65. remainingWidth = 0;
  66. for (const attr in colsByGroup) {
  67. for (const column of colsByGroup[attr]) {
  68. // if the column can be resize and it hasn't reached its minimum width yet
  69. if (column.canAutoResize && !hasMinWidth[column.prop]) {
  70. /** @type {?} */
  71. const newWidth = column.width + column.flexGrow * widthPerFlexPoint;
  72. if (column.minWidth !== undefined && newWidth < column.minWidth) {
  73. remainingWidth += newWidth - column.minWidth;
  74. column.width = column.minWidth;
  75. hasMinWidth[column.prop] = true;
  76. }
  77. else {
  78. column.width = newWidth;
  79. }
  80. }
  81. }
  82. }
  83. } while (remainingWidth !== 0);
  84. }
  85. /**
  86. * Forces the width of the columns to
  87. * distribute equally but overflowing when necessary
  88. *
  89. * Rules:
  90. *
  91. * - If combined withs are less than the total width of the grid,
  92. * proportion the widths given the min / max / normal widths to fill the width.
  93. *
  94. * - If the combined widths, exceed the total width of the grid,
  95. * use the standard widths.
  96. *
  97. * - If a column is resized, it should always use that width
  98. *
  99. * - The proportional widths should never fall below min size if specified.
  100. *
  101. * - If the grid starts off small but then becomes greater than the size ( + / - )
  102. * the width should use the original width; not the newly proportioned widths.
  103. * @param {?} allColumns
  104. * @param {?} expectedWidth
  105. * @param {?} startIdx
  106. * @param {?} allowBleed
  107. * @param {?=} defaultColWidth
  108. * @return {?}
  109. */
  110. export function forceFillColumnWidths(allColumns, expectedWidth, startIdx, allowBleed, defaultColWidth = 300) {
  111. /** @type {?} */
  112. const columnsToResize = allColumns.slice(startIdx + 1, allColumns.length).filter((/**
  113. * @param {?} c
  114. * @return {?}
  115. */
  116. c => {
  117. return c.canAutoResize !== false;
  118. }));
  119. for (const column of columnsToResize) {
  120. if (!column.$$oldWidth) {
  121. column.$$oldWidth = column.width;
  122. }
  123. }
  124. /** @type {?} */
  125. let additionWidthPerColumn = 0;
  126. /** @type {?} */
  127. let exceedsWindow = false;
  128. /** @type {?} */
  129. let contentWidth = getContentWidth(allColumns, defaultColWidth);
  130. /** @type {?} */
  131. let remainingWidth = expectedWidth - contentWidth;
  132. /** @type {?} */
  133. const columnsProcessed = [];
  134. /** @type {?} */
  135. const remainingWidthLimit = 1;
  136. // This loop takes care of the
  137. do {
  138. additionWidthPerColumn = remainingWidth / columnsToResize.length;
  139. exceedsWindow = contentWidth >= expectedWidth;
  140. for (const column of columnsToResize) {
  141. if (exceedsWindow && allowBleed) {
  142. column.width = column.$$oldWidth || column.width || defaultColWidth;
  143. }
  144. else {
  145. /** @type {?} */
  146. const newSize = (column.width || defaultColWidth) + additionWidthPerColumn;
  147. if (column.minWidth && newSize < column.minWidth) {
  148. column.width = column.minWidth;
  149. columnsProcessed.push(column);
  150. }
  151. else if (column.maxWidth && newSize > column.maxWidth) {
  152. column.width = column.maxWidth;
  153. columnsProcessed.push(column);
  154. }
  155. else {
  156. column.width = newSize;
  157. }
  158. }
  159. column.width = Math.max(0, column.width);
  160. }
  161. contentWidth = getContentWidth(allColumns);
  162. remainingWidth = expectedWidth - contentWidth;
  163. removeProcessedColumns(columnsToResize, columnsProcessed);
  164. } while (remainingWidth > remainingWidthLimit && columnsToResize.length !== 0);
  165. }
  166. /**
  167. * Remove the processed columns from the current active columns.
  168. * @param {?} columnsToResize
  169. * @param {?} columnsProcessed
  170. * @return {?}
  171. */
  172. function removeProcessedColumns(columnsToResize, columnsProcessed) {
  173. for (const column of columnsProcessed) {
  174. /** @type {?} */
  175. const index = columnsToResize.indexOf(column);
  176. columnsToResize.splice(index, 1);
  177. }
  178. }
  179. /**
  180. * Gets the width of the columns
  181. * @param {?} allColumns
  182. * @param {?=} defaultColWidth
  183. * @return {?}
  184. */
  185. function getContentWidth(allColumns, defaultColWidth = 300) {
  186. /** @type {?} */
  187. let contentWidth = 0;
  188. for (const column of allColumns) {
  189. contentWidth += column.width || defaultColWidth;
  190. }
  191. return contentWidth;
  192. }
  193. //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0aC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0Bzd2ltbGFuZS9uZ3gtZGF0YXRhYmxlLyIsInNvdXJjZXMiOlsibGliL3V0aWxzL21hdGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxVQUFVLENBQUM7Ozs7OztBQUszRCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsT0FBYzs7UUFDekMsYUFBYSxHQUFHLENBQUM7SUFFckIsS0FBSyxNQUFNLENBQUMsSUFBSSxPQUFPLEVBQUU7UUFDdkIsYUFBYSxJQUFJLENBQUMsQ0FBQyxRQUFRLElBQUksQ0FBQyxDQUFDO0tBQ2xDO0lBRUQsT0FBTyxhQUFhLENBQUM7QUFDdkIsQ0FBQzs7Ozs7Ozs7QUFNRCxNQUFNLFVBQVUsa0JBQWtCLENBQUMsVUFBZSxFQUFFLGFBQWtCOztVQUM5RCxZQUFZLEdBQUcsaUJBQWlCLENBQUMsVUFBVSxDQUFDOztVQUM1QyxhQUFhLEdBQUcsZ0JBQWdCLENBQUMsVUFBVSxDQUFDOztVQUM1QyxXQUFXLEdBQUcsWUFBWSxDQUFDLFVBQVUsQ0FBQztJQUU1QyxJQUFJLFlBQVksS0FBSyxhQUFhLEVBQUU7UUFDbEMsWUFBWSxDQUFDLFdBQVcsRUFBRSxhQUFhLEVBQUUsYUFBYSxDQUFDLENBQUM7S0FDekQ7QUFDSCxDQUFDOzs7Ozs7OztBQUtELFNBQVMsWUFBWSxDQUFDLFdBQWdCLEVBQUUsUUFBYSxFQUFFLGFBQWtCO0lBQ3ZFLDZFQUE2RTtJQUM3RSxLQUFLLE1BQU0sSUFBSSxJQUFJLFdBQVcsRUFBRTtRQUM5QixLQUFLLE1BQU0sTUFBTSxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUN0QyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRTtnQkFDekIsUUFBUSxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUM7Z0JBQ3pCLGFBQWEsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FB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QUksZUFBZSxDQUFDO0tBQ2pEO0lBRUQsT0FBTyxZQUFZLENBQUM7QUFDdEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvbHVtbnNCeVBpbiwgY29sdW1uc1RvdGFsV2lkdGggfSBmcm9tICcuL2NvbHVtbic7XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgVG90YWwgRmxleCBHcm93XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUb3RhbEZsZXhHcm93KGNvbHVtbnM6IGFueVtdKSB7XG4gIGxldCB0b3RhbEZsZXhHcm93ID0gMDtcblxuICBmb3IgKGNvbnN0IGMgb2YgY29sdW1ucykge1xuICAgIHRvdGFsRmxleEdyb3cgKz0gYy5mbGV4R3JvdyB8fCAwO1xuICB9XG5cbiAgcmV0dXJuIHRvdGFsRmxleEdyb3c7XG59XG5cbi8qKlxuICogQWRqdXN0cyB0aGUgY29sdW1uIHdpZHRocy5cbiAqIEluc3BpcmVkIGJ5OiBodHRwczovL2dpdGh1Yi5jb20vZmFjZWJvb2svZml4ZWQtZGF0YS10YWJsZS9ibG9iL21hc3Rlci9zcmMvRml4ZWREYXRhVGFibGVXaWR0aEhlbHBlci5qc1xuICovXG5leHBvcnQgZnVuY3Rpb24gYWRqdXN0Q29sdW1uV2lkdGhzKGFsbENvbHVtbnM6IGFueSwgZXhwZWN0ZWRXaWR0aDogYW55KSB7XG4gIGNvbnN0IGNvbHVtbnNXaWR0aCA9IGNvbHVtbnNUb3RhbFdpZHRoKGFsbENvbHVtbnMpO1xuICBjb25zdCB0b3RhbEZsZXhHcm93ID0gZ2V0VG90YWxGbGV4R3JvdyhhbGxDb2x1bW5zKTtcbiAgY29uc3QgY29sc0J5R3JvdXAgPSBjb2x1bW5zQnlQaW4oYWxsQ29sdW1ucyk7XG5cbiAgaWYgKGNvbHVtbnNXaWR0aCAhPT0gZXhwZWN0ZWRXaWR0aCkge1xuICAgIHNjYWxlQ29sdW1ucyhjb2xzQnlHcm91cCwgZXhwZWN0ZWRXaWR0aCwgdG90YWxGbGV4R3Jvdyk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNpemVzIGNvbHVtbnMgYmFzZWQgb24gdGhlIGZsZXhHcm93IHByb3BlcnR5LCB3aGlsZSByZXNwZWN0aW5nIG1hbnVhbGx5IHNldCB3aWR0aHNcbiAqL1xuZnVuY3Rpb24gc2NhbGVDb2x1bW5zKGNvbHNCeUdyb3VwOiBhbnksIG1heFdpZHRoOiBhbnksIHRvdGFsRmxleEdyb3c6IGFueSkge1xuICAvLyBjYWxjdWxhdGUgdG90YWwgd2lkdGggYW5kIGZsZXhncm93IHBvaW50cyBmb3IgY291bHVtbnMgdGhhdCBjYW4gYmUgcmVzaXplZFxuICBmb3IgKGNvbnN0IGF0dHIgaW4gY29sc0J5R3JvdXApIHtcbiAgICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBjb2xzQnlHcm91cFthdHRyXSkge1xuICAgICAgaWYgKCFjb2x1bW4uY2FuQXV0b1Jlc2l6ZSkge1xuICAgICAgICBtYXhXaWR0aCAtPSBjb2x1bW4ud2lkdGg7XG4gICAgICAgIHRvdGFsRmxleEdyb3cgLT0gY29sdW1uLmZsZXhHcm93ID8gY29sdW1uLmZsZXhHcm93IDogMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbHVtbi53aWR0aCA9IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3QgaGFzTWluV2lkdGggPSB7fTtcbiAgbGV0IHJlbWFpbmluZ1dpZHRoID0gbWF4V2lkdGg7XG5cbiAgLy8gcmVzaXplIGNvbHVtbnMgdW50aWwgbm8gd2lkdGggaXMgbGVmdCB0byBiZSBkaXN0cmlidXRlZFxuICBkbyB7XG4gICAgY29uc3Qgd2lkdGhQZXJGbGV4UG9pbnQgPSByZW1haW5pbmdXaWR0aCAvIHRvdGFsRmxleEdyb3c7XG4gICAgcmVtYWluaW5nV2lkdGggPSAwO1xuXG4gICAgZm9yIChjb25zdCBhdHRyIGluIGNvbHNCeUdyb3VwKSB7XG4gICAgICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBjb2xzQnlHcm91cFthdHRyXSkge1xuICAgICAgICAvLyBpZiB0aGUgY29sdW1uIGNhbiBiZSByZXNpemUgYW5kIGl0IGhhc24ndCByZWFjaGVkIGl0cyBtaW5pbXVtIHdpZHRoIHlldFxuICAgICAgICBpZiAoY29sdW1uLmNhbkF1dG9SZXNpemUgJiYgIWhhc01pbldpZHRoW2NvbHVtbi5wcm9wXSkge1xuICAgICAgICAgIGNvbnN0IG5ld1dpZHRoID0gY29sdW1uLndpZHRoICsgY29sdW1uLmZsZXhHcm93ICogd2lkdGhQZXJGbGV4UG9pbnQ7XG4gICAgICAgICAgaWYgKGNvbHVtbi5taW5XaWR0aCAhPT0gdW5kZWZpbmVkICYmIG5ld1dpZHRoIDwgY29sdW1uLm1pbldpZHRoKSB7XG4gICAgICAgICAgICByZW1haW5pbmdXaWR0aCArPSBuZXdXaWR0aCAtIGNvbHVtbi5taW5XaWR0aDtcbiAgICAgICAgICAgIGNvbHVtbi53aWR0aCA9IGNvbHVtbi5taW5XaWR0aDtcbiAgICAgICAgICAgIGhhc01pbldpZHRoW2NvbHVtbi5wcm9wXSA9IHRydWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbHVtbi53aWR0aCA9IG5ld1dpZHRoO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSB3aGlsZSAocmVtYWluaW5nV2lkdGggIT09IDApO1xufVxuXG4vKipcbiAqIEZvcmNlcyB0aGUgd2lkdGggb2YgdGhlIGNvbHVtbnMgdG9cbiAqIGRpc3RyaWJ1dGUgZXF1YWxseSBidXQgb3ZlcmZsb3dpbmcgd2hlbiBuZWNlc3NhcnlcbiAqXG4gKiBSdWxlczpcbiAqXG4gKiAgLSBJZiBjb21iaW5lZCB3aXRocyBhcmUgbGVzcyB0aGFuIHRoZSB0b3RhbCB3aWR0aCBvZiB0aGUgZ3JpZCxcbiAqICAgIHByb3BvcnRpb24gdGhlIHdpZHRocyBnaXZlbiB0aGUgbWluIC8gbWF4IC8gbm9ybWFsIHdpZHRocyB0byBmaWxsIHRoZSB3aWR0aC5cbiAqXG4gKiAgLSBJZiB0aGUgY29tYmluZWQgd2lkdGhzLCBleGNlZWQgdGhlIHRvdGFsIHdpZHRoIG9mIHRoZSBncmlkLFxuICogICAgdXNlIHRoZSBzdGFuZGFyZCB3aWR0aHMuXG4gKlxuICogIC0gSWYgYSBjb2x1bW4gaXMgcmVzaXplZCwgaXQgc2hvdWxkIGFsd2F5cyB1c2UgdGhhdCB3aWR0aFxuICpcbiAqICAtIFRoZSBwcm9wb3J0aW9uYWwgd2lkdGhzIHNob3VsZCBuZXZlciBmYWxsIGJlbG93IG1pbiBzaXplIGlmIHNwZWNpZmllZC5cbiAqXG4gKiAgLSBJZiB0aGUgZ3JpZCBzdGFydHMgb2ZmIHNtYWxsIGJ1dCB0aGVuIGJlY29tZXMgZ3JlYXRlciB0aGFuIHRoZSBzaXplICggKyAvIC0gKVxuICogICAgdGhlIHdpZHRoIHNob3VsZCB1c2UgdGhlIG9yaWdpbmFsIHdpZHRoOyBub3QgdGhlIG5ld2x5IHByb3BvcnRpb25lZCB3aWR0aHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmb3JjZUZpbGxDb2x1bW5XaWR0aHMoXG4gIGFsbENvbHVtbnM6IGFueVtdLFxuICBleHBlY3RlZFdpZHRoOiBudW1iZXIsXG4gIHN0YXJ0SWR4OiBudW1iZXIsXG4gIGFsbG93QmxlZWQ6IGJvb2xlYW4sXG4gIGRlZmF1bHRDb2xXaWR0aDogbnVtYmVyID0gMzAwXG4pIHtcbiAgY29uc3QgY29sdW1uc1RvUmVzaXplID0gYWxsQ29sdW1ucy5zbGljZShzdGFydElkeCArIDEsIGFsbENvbHVtbnMubGVuZ3RoKS5maWx0ZXIoYyA9PiB7XG4gICAgcmV0dXJuIGMuY2FuQXV0b1Jlc2l6ZSAhPT0gZmFsc2U7XG4gIH0pO1xuXG4gIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbnNUb1Jlc2l6ZSkge1xuICAgIGlmICghY29sdW1uLiQkb2xkV2lkdGgpIHtcbiAgICAgIGNvbHVtbi4kJG9sZFdpZHRoID0gY29sdW1uLndpZHRoO1xuICAgIH1cbiAgfVxuXG4gIGxldCBhZGRpdGlvbldpZHRoUGVyQ29sdW1uID0gMDtcbiAgbGV0IGV4Y2VlZHNXaW5kb3cgPSBmYWxzZTtcbiAgbGV0IGNvbnRlbnRXaWR0aCA9IGdldENvbnRlbnRXaWR0aChhbGxDb2x1bW5zLCBkZWZhdWx0Q29sV2lkdGgpO1xuICBsZXQgcmVtYWluaW5nV2lkdGggPSBleHBlY3RlZFdpZHRoIC0gY29udGVudFdpZHRoO1xuICBjb25zdCBjb2x1bW5zUHJvY2Vzc2VkOiBhbnlbXSA9IFtdO1xuICBjb25zdCByZW1haW5pbmdXaWR0aExpbWl0ID0gMTsgLy8gd2hlbiB0byBzdG9wXG5cbiAgLy8gVGhpcyBsb29wIHRha2VzIGNhcmUgb2YgdGhlXG4gIGRvIHtcbiAgICBhZGRpdGlvbldpZHRoUGVyQ29sdW1uID0gcmVtYWluaW5nV2lkdGggLyBjb2x1bW5zVG9SZXNpemUubGVuZ3RoO1xuICAgIGV4Y2VlZHNXaW5kb3cgPSBjb250ZW50V2lkdGggPj0gZXhwZWN0ZWRXaWR0aDtcblxuICAgIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbnNUb1Jlc2l6ZSkge1xuICAgICAgaWYgKGV4Y2VlZHNXaW5kb3cgJiYgYWxsb3dCbGVlZCkge1xuICAgICAgICBjb2x1bW4ud2lkdGggPSBjb2x1bW4uJCRvbGRXaWR0aCB8fCBjb2x1bW4ud2lkdGggfHwgZGVmYXVsdENvbFdpZHRoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgbmV3U2l6ZSA9IChjb2x1bW4ud2lkdGggfHwgZGVmYXVsdENvbFdpZHRoKSArIGFkZGl0aW9uV2lkdGhQZXJDb2x1bW47XG5cbiAgICAgICAgaWYgKGNvbHVtbi5taW5XaWR0aCAmJiBuZXdTaXplIDwgY29sdW1uLm1pbldpZHRoKSB7XG4gICAgICAgICAgY29sdW1uLndpZHRoID0gY29sdW1uLm1pbldpZHRoO1xuICAgICAgICAgIGNvbHVtbnNQcm9jZXNzZWQucHVzaChjb2x1bW4pO1xuICAgICAgICB9IGVsc2UgaWYgKGNvbHVtbi5tYXhXaWR0aCAmJiBuZXdTaXplID4gY29sdW1uLm1heFdpZHRoKSB7XG4gICAgICAgICAgY29sdW1uLndpZHRoID0gY29sdW1uLm1heFdpZHRoO1xuICAgICAgICAgIGNvbHVtbnNQcm9jZXNzZWQucHVzaChjb2x1bW4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbHVtbi53aWR0aCA9IG5ld1NpemU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29sdW1uLndpZHRoID0gTWF0aC5tYXgoMCwgY29sdW1uLndpZHRoKTtcbiAgICB9XG5cbiAgICBjb250ZW50V2lkdGggPSBnZXRDb250ZW50V2lkdGgoYWxsQ29sdW1ucyk7XG4gICAgcmVtYWluaW5nV2lkdGggPSBleHBlY3RlZFdpZHRoIC0gY29udGVudFdpZHRoO1xuICAgIHJlbW92ZVByb2Nlc3NlZENvbHVtbnMoY29sdW1uc1RvUmVzaXplLCBjb2x1bW5zUHJvY2Vzc2VkKTtcbiAgfSB3aGlsZSAocmVtYWluaW5nV2lkdGggPiByZW1haW5pbmdXaWR0aExpbWl0ICYmIGNvbHVtbnNUb1Jlc2l6ZS5sZW5ndGggIT09IDApO1xufVxuXG4vKipcbiAqIFJlbW92ZSB0aGUgcHJvY2Vzc2VkIGNvbHVtbnMgZnJvbSB0aGUgY3VycmVudCBhY3RpdmUgY29sdW1ucy5cbiAqL1xuZnVuY3Rpb24gcmVtb3ZlUHJvY2Vzc2VkQ29sdW1ucyhjb2x1bW5zVG9SZXNpemU6IGFueVtdLCBjb2x1bW5zUHJvY2Vzc2VkOiBhbnlbXSkge1xuICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBjb2x1bW5zUHJvY2Vzc2VkKSB7XG4gICAgY29uc3QgaW5kZXggPSBjb2x1bW5zVG9SZXNpemUuaW5kZXhPZihjb2x1bW4pO1xuICAgIGNvbHVtbnNUb1Jlc2l6ZS5zcGxpY2UoaW5kZXgsIDEpO1xuICB9XG59XG5cbi8qKlxuICogR2V0cyB0aGUgd2lkdGggb2YgdGhlIGNvbHVtbnNcbiAqL1xuZnVuY3Rpb24gZ2V0Q29udGVudFdpZHRoKGFsbENvbHVtbnM6IGFueSwgZGVmYXVsdENvbFdpZHRoOiBudW1iZXIgPSAzMDApOiBudW1iZXIge1xuICBsZXQgY29udGVudFdpZHRoID0gMDtcblxuICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBhbGxDb2x1bW5zKSB7XG4gICAgY29udGVudFdpZHRoICs9IGNvbHVtbi53aWR0aCB8fCBkZWZhdWx0Q29sV2lkdGg7XG4gIH1cblxuICByZXR1cm4gY29udGVudFdpZHRoO1xufVxuIl19