TimeTrex/interface/html5/dist/ttgrid-TTGrid.bundle.js

1 line
68 KiB
JavaScript

(self.webpackChunktimetrex=self.webpackChunktimetrex||[]).push([["ttgrid-TTGrid"],{2185:(__unused_webpack_module,__unused_webpack_exports,__webpack_require__)=>{eval("/* provided dependency */ var $ = __webpack_require__(9755);\n/**\n * @author: joshr@timetrex.com\n * @description wrapper class for jqgrid in timetrex.\n * Requires free-jqgrid 4.15.4+ and jquery 3.3.1+\n *\n * @param setup\n * @constructor\n */\nTTGrid = function( table_id, setup, column_info_array ) {\n\tthis.getGridId = function() {\n\t\treturn this.ui_id;\n\t};\n\n\tthis.setTableIDElement = function() {\n\t\tthis.table_id_element = $( '#' + this.ui_id );\n\t\treturn true;\n\t};\n\n\tthis.getTableIDElement = function() {\n\t\treturn this.table_id_element;\n\t};\n\n\tif ( !table_id || !setup || !column_info_array ) {\n\t\tDebug.Text( 'ERROR: constructor requires all 3 arguments', 'TTGrid.js', 'TTGrid', 'constructor', 10 );\n\t\treturn;\n\t}\n\n\tthis.ui_id = table_id;\n\n\t// Issue #2891 - Forcing GridUnload can cause grids inside a AComboBox to disappear after repeated opening. Check for container_selector is to mitigate that.\n\tif ( !setup.container_selector ) {\n\t\t// We are unloading grids with the same ID if they exist to help prevent: Uncaught TypeError: Failed to execute 'replaceChild' on 'Node': parameter 2 is not of type 'Node'.\n\t\t// Looping through array in reverse to make sure no index issues after splicing.\n\t\tfor ( var i = LocalCacheData.resizeable_grids.length - 1; i >= 0; i-- ) {\n\t\t\tif ( LocalCacheData.resizeable_grids[i] != null && LocalCacheData.resizeable_grids[i].grid != null && LocalCacheData.resizeable_grids[i].ui_id == this.ui_id ) {\n\t\t\t\tLocalCacheData.resizeable_grids[i].grid.jqGrid( 'GridUnload' );\n\t\t\t\tLocalCacheData.resizeable_grids.splice( i, 1 );\n\t\t\t} else if ( LocalCacheData.resizeable_grids[i] == null || LocalCacheData.resizeable_grids[i].grid == null ) {\n\t\t\t\t// LocalCacheData.resizeable_grids array gets full of null values from resize event and we are making sure to clear it out.\n\t\t\t\tLocalCacheData.resizeable_grids.splice( i, 1 );\n\t\t\t}\n\t\t}\n\t}\n\n\tvar max_height = null;\n\n\tthis.setTableIDElement();\n\tvar table_div = this.getTableIDElement();\n\n\tthis.grid = null;\n\n\tif ( table_div[0] == false ) {\n\t\tDebug.Text( 'ERROR: table_id not found in DOM', 'TTGrid.js', 'TTGrid', 'constructor', 10 );\n\t\treturn;\n\t}\n\n\t//Default grid settings.\n\tvar default_setup = {\n\t\tcontainer_selector: 'body',\n\t\tsub_grid_mode: false,\n\t\taltRows: true,\n\t\tdata: [],\n\t\tdatatype: 'local',\n\t\t//quickEmpty: 'true', //Default is 'quickest', might fix JS Exception: Uncaught TypeError: Failed to execute 'replaceChild' on 'Node': parameter 2 is not of type 'Node', but causes this instead: TTGrid.js?v=11.6.1-20191108:99 Uncaught TypeError: Cannot read property 'cells' of undefined\n\t\tsortable: false,\n\t\theight: table_div.parents( '.view' ).height(),\n\t\twidth: table_div.parent().width(),\n\t\trowNum: 10000,\n\t\tcolNames: [],\n\t\tcolModel: column_info_array,\n\t\tmultiselect: true,\n\t\tmultiselectWidth: 22,\n\t\tmultiboxonly: true,\n\t\tviewrecords: true,\n\t\tautoencode: true,\n\t\tscrollOffset: 0,\n\t\tverticalResize: true, //when the grid resizes do we reisize it vertically? needed for timesheet and subgrid views.\n\t\tresizeGrid: true,\n\t\twinMultiSelect: true\n\t\t// resizeStop: function(width, index){\n\t\t// \t//$this.setGridColumnsWidth(width, index);\n\t\t// }\n\t};\n\n\tif ( setup.max_height === true ) {\n\t\tsetup.max_height = max_height;\n\t}\n\n\tif ( setup ) {\n\t\tsetup = $.extend( {}, default_setup, setup );\n\t} else {\n\t\tsetup = default_setup;\n\t}\n\n\tthis.setup = setup;\n\n\ttable_div.empty(); //should unbind all events bound to the grid.\n\tthis.grid = table_div.jqGrid( setup );\n\n\tLocalCacheData.resizeable_grids.push( this );\n\n\tif ( setup.winMultiSelect === true ) {\n\t\tthis.grid.winMultiSelect();\n\t}\n\n\t//turn off grid resize event (for schedule grids that need to be rebuilt on every resize)\n\tthis.noResize = function() {\n\t\tthis.setup.onResizeGrid = false;\n\t};\n\n\t/**\n\t *\n\t * @param data\n\t */\n\tthis.setData = function( data, clear_grid ) {\n\t\tif ( this.grid ) {\n\t\t\t//Clear grid by default.\n\t\t\tclear_grid = ( clear_grid == null ) ? true : clear_grid;\n\t\t\tif ( clear_grid == true ) {\n\t\t\t\tthis.grid.clearGridData();\n\t\t\t}\n\n\t\t\t//ACombo might send data as \"true\" when the unselected grid is blank and \"Show All\" is clicked. Prevent anything but an array from being passed into setGridParam( 'data' ).\n\t\t\tif ( Array.isArray( data ) == false ) {\n\t\t\t\tdata = [];\n\t\t\t}\n\n\t\t\tthis.grid.setGridParam( { 'data': data } ).trigger( 'reloadGrid' );\n\t\t\t//this.setGridColumnsWidth();\n\t\t} else {\n\t\t\tthrow( 'ERROR: Grid is not ready yet.' );\n\t\t}\n\t};\n\tthis.getData = function() {\n\t\treturn this.getGridParam( 'data' );\n\t};\n\n\tthis.getSetup = function() {\n\t\treturn this.getGridParam( 'data' );\n\t};\n\n\tthis.getHeight = function() {\n\t\treturn $( this.grid ).height();\n\t};\n\tthis.getWidth = function() {\n\t\treturn $( this.grid ).width();\n\t};\n\n\t/**\n\t *\n\t * @param value\n\t */\n\tthis.deleteRow = function( value ) {\n\t\tthis.grid.jqGrid( 'delRowData', value );\n\t};\n\n\tthis.resetSelection = function() {\n\t\tthis.grid.resetSelection();\n\t};\n\n\tthis.setSelection = function( x1, y1, x2, y2, noScale ) {\n\t\tthis.grid.setSelection( x1, y1, x2, y2, noScale );\n\t};\n\n\tthis.getGridParam = function( parameter_name ) {\n\t\treturn this.grid.getGridParam( parameter_name );\n\t};\n\n\tthis.setGridParam = function( parameter_name, value ) {\n\t\treturn this.grid.setGridParam( parameter_name, value );\n\t};\n\n\tthis.unload = function() {\n\t\tif ( this.grid ) {\n\t\t\tthis.grid.jqGrid( 'GridUnload' );\n\t\t\tthis.grid = null;\n\t\t}\n\t\treturn true;\n\t};\n\n\tthis.clearGridData = function() {\n\t\tthis.grid.jqGrid( 'clearGridData', true );\n\t};\n\n\tthis.reloadGrid = function() {\n\t\tthis.grid.trigger( 'reloadGrid' );\n\t};\n\n\tthis.getRecordFromGridById = function( id ) {\n\t\tvar data = this.grid.getGridParam( 'data' );\n\t\tvar result = null;\n\t\t/* jshint ignore:start */\n\t\t//id could be string or number.\n\t\t$.each( data, function( index, value ) {\n\n\t\t\tif ( value['_id_'] == id ) {\n\t\t\t\tresult = Global.clone( value );\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t} );\n\t\t/* jshint ignore:end */\n\n\t\tif ( result ) {\n\t\t\tresult.id = result['_id_'];\n\t\t}\n\t\treturn result;\n\n\t};\n\n\tthis.getGridWidth = function() {\n\t\tif ( this.grid ) {\n\t\t\treturn this.grid.width();\n\t\t}\n\t\treturn 0;\n\t};\n\n\tthis.setGridWidth = function( w, inner_width ) {\n\t\tif ( this.grid ) {\n\t\t\tif ( inner_width > w ) {\n\t\t\t\tw = inner_width;\n\t\t\t}\n\t\t\tthis.grid.setGridWidth( w );\n\t\t}\n\t};\n\n\tthis.getGridHeight = function() {\n\t\tif ( this.grid ) {\n\t\t\treturn this.grid.height();\n\t\t}\n\t\treturn 0;\n\t};\n\tthis.setGridHeight = function( h ) {\n\t\tif ( this.setup.static_height ) {\n\t\t\th = this.setup.static_height;\n\t\t}\n\n\t\tif ( this.grid ) {\n\t\t\tthis.grid.setGridHeight( h );\n\t\t}\n\t};\n\n\tthis.setRowData = function( id, new_record ) {\n\t\tthis.grid.setRowData( id, new_record );\n\t};\n\n\tthis.getRowData = function( row_id ) {\n\t\tvar row = false;\n\n\t\tvar row_data = this.getData();\n\n\t\tfor ( var i in row_data ) {\n\t\t\tif ( row_data[i].id == row_id ) {\n\t\t\t\trow = row_data[i];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn row;\n\t};\n\n\tthis.getColumnModel = function() {\n\t\treturn this.getGridParam( 'colModel' );\n\t};\n\n\tthis.setColumnModel = function( val ) {\n\t\tthis.getGridParam( 'colModel', val );\n\t};\n\n\tthis.grid2csv = function( filename ) {\n\t\t// TODO: Add in more robust quote escaping to handle data strings that have quotes. Currently we are just wrapping everything in double quotes.\n\n\t\tlet csv_data = [];\n\n\t\t// Get grid data for csv.\n\t\t// Column headers are in a different table. Seems to be a jqGrid thing?\n\t\t// Parsing column headers using aria-describedby on the first none blank <tr> (2nd) which links to the id of the header and from there gets the textContent.\n\t\tlet i = 1;\n\t\tlet headers = [];\n\t\tfor ( let tr of document.querySelectorAll( '#' + this.getGridId() + ' tr' ) ) {\n\t\t\tlet row = [];\n\t\t\tfor ( let td of tr.querySelectorAll( 'td' ) ) {\n\t\t\t\trow.push( '\"' + td.textContent.trim() + '\"' );\n\t\t\t\tif ( i === 2 ) {\n\t\t\t\t\t// Column headers sometimes contain HTML such as Claim<br>Dependents.\n\t\t\t\t\t// Using a temporary element to replace <br> with a space and then grabbing the textContent to strip the HTML.\n\t\t\t\t\tlet temp_element = document.createElement( 'div' );\n\t\t\t\t\ttemp_element.innerHTML = document.getElementById( td.getAttribute( 'aria-describedby' ) ).innerHTML.replace( '<br>', ' ' );\n\t\t\t\t\theaders.push( '\"' + temp_element.textContent.trim() + '\"' );\n\t\t\t\t}\n\t\t\t}\n\t\t\tcsv_data.push( row.join( ',' ) );\n\t\t\ti++;\n\t\t}\n\n\t\t// Replace blank row with table headers\n\t\tcsv_data[0] = headers.join( ',' );\n\n\t\tlet csv_content = csv_data.join( '\\r\\n' );\n\n\t\tGlobal.JSFileDownload( filename + '.csv', csv_content, 'text/csv;encoding:utf-8' );\n\n\t}\n\n\tthis.getRecordCount = function() {\n\t\tif ( !this.grid ) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.grid.getGridParam( 'reccount' );\n\t};\n\n\t//Gets a single row\n\tthis.getSelectedRow = function() {\n\t\tif ( !this.grid ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar result = this.grid.getGridParam( 'selrow' );\n\n\t\tif ( !result ) {\n\t\t\tresult = false;\n\t\t}\n\n\t\treturn result;\n\t};\n\n\t//Gets an array of rows if multiple are selected.\n\tthis.getSelectedRows = function() {\n\t\tif ( !this.grid ) {\n\t\t\treturn []; //Return empty array so .length on the result doesn't fail with Cannot read property 'length' of undefined\n\t\t}\n\n\t\tvar result = this.grid.getGridParam( 'selarrrow' );\n\n\t\tif ( !result ) {\n\t\t\tresult = [];\n\t\t}\n\n\t\treturn result;\n\t};\n\n\tthis.getSelection = function() {\n\t\tvar tds = this.grid.find( 'td.ui-state-highlight' );\n\n\t\tvar selection = [];\n\t\tfor ( var x = 0; x < tds.length; x++ ) {\n\t\t\tselection.push( {\n\t\t\t\ttr: $( tds[x] ).parent( 'tr' ).index(),\n\t\t\t\ttd: $( tds[x] ).index()\n\t\t\t} );\n\t\t}\n\t\treturn selection;\n\t},\n\n\t\tthis.setTimesheetSelection = function( selection_obj ) {\n\t\t\t//This is currently broken, it highlights the cells, but they aren't actually considered \"selected\".\n\t\t\t// So if you go to Attendance -> TimeSheet, select two cells, Mass Edit them, click Save, the \"Mass Edit\" is no longer available to be clicked again.\n\t\t\t// As well if you hold in SHIFT to try and expand the selection (select more cells), that doesn't work either.\n\t\t\tvar trs = this.grid.find( 'tr' );\n\t\t\tfor ( var i = 0; i < selection_obj.length; i++ ) {\n\t\t\t\tfor ( var x = 0; x < trs.length; x++ ) {\n\t\t\t\t\tif ( $( trs[x] ).index() == selection_obj[i].tr ) {\n\t\t\t\t\t\tvar tds = $( trs[x] ).find( 'td' );\n\t\t\t\t\t\tfor ( var w = 0; w < tds.length; w++ ) {\n\t\t\t\t\t\t\tif ( $( tds[w] ).index() == selection_obj[i].td ) {\n\t\t\t\t\t\t\t\t$( tds[w] ).addClass( 'ui-state-highlight' );\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\tthis.setGridColumnsWidth = function( column_model, options ) {\n\t\t// this.grid.autoResizeAllColumns();\n\t\t// return;\n\t\tif ( this.setup.treeGrid || this.setup.tree_mode ) {\n\t\t\tthis.setGridWidth( $( this.setup.container_selector ).width() - 12 );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( typeof options === 'undefined' ) {\n\t\t\toptions = {};\n\t\t}\n\n\t\tif ( this.setup.container_selector && ( !options.min_grid_width || options.min_grid_width == 0 ) ) {\n\t\t\tvar parent_container = this.grid.parents( this.setup.container_selector ).find( '.edit-view-tab' );\n\t\t\tif ( parent_container.length > 0 ) {\n\t\t\t\t//Sub-View grid, check if parent div is visible, and if not don't bother resizing grid.\n\t\t\t\tif ( parent_container.is( ':visible' ) === true ) {\n\t\t\t\t\toptions.min_grid_width = parent_container.innerWidth();\n\t\t\t\t} else {\n\t\t\t\t\tDebug.Text( ' Parent container of grid is not visible, skip setting column widths...', 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t//Main grid\n\t\t\t\tlet grid_parent = $( '#gbox_' + this.ui_id );\n\t\t\t\tif ( grid_parent.length !== 0 ) {\n\t\t\t\t\toptions.min_grid_width = grid_parent.parent().width();\n\t\t\t\t} else {\n\t\t\t\t\toptions.min_grid_width = this.grid.parents( this.setup.container_selector ).innerWidth();\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t\tif ( options.min_grid_width == 0 || options.min_grid_width == 'undefined' ) { //fallback width so it's never sized to zero when render timing collides\n\t\t\toptions.min_grid_width = $( 'body' ).innerWidth();\n\t\t}\n\n\t\t//Adjust for the vertical scrollbar offset that can occur when the items per page always exceeds the screen height.\n\t\tif ( Global.isVerticalScrollBarRequired( this.grid.parents( '.ui-jqgrid-bdiv' )[0] ) ) {\n\t\t\toptions.min_grid_width -= Global.getScrollbarWidth();\n\t\t}\n\n\t\tif ( !options.max_grid_width ) {\n\t\t\toptions.max_grid_width = null; //No maximum.\n\t\t}\n\n\t\tif ( options.max_grid_width && options.max_grid_width < options.min_grid_width ) {\n\t\t\toptions.min_grid_width = options.max_grid_width;\n\t\t}\n\n\t\tDebug.Text( 'Target Grid: ' + this.setup.container_selector + ' Target Div: ' + this.grid.parents( this.setup.container_selector ).id + ' Width: Min: ' + options.min_grid_width + ' Max: ' + options.max_grid_width + ' Scrollbar Offset: ' + Global.getScrollbarWidth() + ' Parent Width: ' + $( this.grid.parents( '.edit-view-tab, body' )[0] ).width(), 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\n\t\tif ( column_model ) {\n\t\t\tvar total_column_width = 0;\n\t\t\tfor ( var i = 0; i < column_model.length; i++ ) {\n\t\t\t\tvar field = column_model[i].name;\n\t\t\t\tvar width = column_model[i].width ? column_model[i].width : column_model.widthOrg;\n\t\t\t\ttotal_column_width += width;\n\n\t\t\t\t//Don't change the width of columns if they are already the same size. This may help avoid minor changes in the table caused by simple redraws.\n\t\t\t\tif ( this.grid.getColProp( field ).width != width ) {\n\t\t\t\t\tthis.grid.setColWidth( field, width );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn total_column_width;\n\t\t}\n\n\t\tvar column_model = this.getColumnModel();\n\n\t\t//Possible exception\n\t\t//Error: Uncaught TypeError: Cannot read property 'length' of undefined in /interface/html5/#!m=TimeSheet&date=20141102&user_id=53130 line 4288\n\t\tif ( !column_model ) {\n\t\t\tDebug.Text( 'ERROR: column_model is null or undefined', 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\t\t\treturn;\n\t\t}\n\n\t\tfunction longer( champ, contender ) {\n\t\t\treturn ( contender.length > champ.length ) ? contender : champ;\n\t\t}\n\n\t\tfunction longestWord( str ) {\n\t\t\tif ( str && typeof str === 'string' ) {\n\t\t\t\tvar words = str.split( ' ' );\n\t\t\t\treturn words.reduce( longer );\n\t\t\t} else {\n\t\t\t\treturn '';\n\t\t\t}\n\t\t}\n\n\t\tvar grid_data = this.getData();\n\t\tthis.grid_total_width = 0;\n\n\t\tvar cb_column_width = 0; //checkbox column width, usually 22, but only set once we know there is a checkbox column.\n\t\tvar cb_column_count_adjustment = 0; //If the checkbox column exists or not.\n\n\t\tvar longest_field_width = 0;\n\t\tvar last_column = null;\n\t\tvar column_widths = {};\n\n\t\tfor ( var i = 0; i < column_model.length; i++ ) {\n\t\t\tvar col = column_model[i];\n\t\t\tlast_column = col;\n\t\t\tvar field = col.name;\n\t\t\tvar longest_cell_content = longestWord( col.label ); // allow extra space for sort order UI hint\n\t\t\tvar header_is_longest = true;\n\n\t\t\tif ( field == 'cb' ) { //hard coded override on CB column, so we don't try to check the data in each row for it.\n\t\t\t\tcb_column_count_adjustment = 1;\n\t\t\t\tcb_column_width = 22;\n\t\t\t\twidth = cb_column_width;\n\t\t\t} else {\n\t\t\t\tif ( options.column_width_override && options.column_width_override[field] ) {\n\t\t\t\t\twidth = options.column_width_override[field];\n\t\t\t\t} else {\n\n\t\t\t\t\tfor ( var j = 0; j < grid_data.length; j++ ) {\n\t\t\t\t\t\tvar row_data = grid_data[j];\n\t\t\t\t\t\tif ( !row_data.hasOwnProperty( field ) ) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar current_cell_content = row_data[field];\n\t\t\t\t\t\tif ( !current_cell_content ) {\n\t\t\t\t\t\t\tcurrent_cell_content = '';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( !longest_cell_content ) {\n\t\t\t\t\t\t\tlongest_cell_content = current_cell_content.toString();\n\t\t\t\t\t\t\theader_is_longest = false;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif ( current_cell_content && current_cell_content.toString().length > longest_cell_content.length ) {\n\t\t\t\t\t\t\t\tlongest_cell_content = current_cell_content.toString();\n\t\t\t\t\t\t\t\theader_is_longest = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tvar calculate_text_width_options;\n\t\t\t\t\tif ( longest_cell_content == field ) {\n\t\t\t\t\t\tcalculate_text_width_options = { fontSize: '11px', fontWeight: 'bolder' };\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcalculate_text_width_options = { fontSize: '11px', fontWeight: 'normal' };\n\t\t\t\t\t}\n\n\t\t\t\t\tvar width = Global.calculateTextWidth( longest_cell_content, calculate_text_width_options ); // + 40; // 8 is drag handle width +2 for borders +20 for sort order ui hint (17 for actual hint,13 for header padding on Firefox under windows\n\n\t\t\t\t\tif ( header_is_longest === true ) {\n\t\t\t\t\t\twidth += 40;\n\t\t\t\t\t} else {\n\t\t\t\t\t\twidth += 12;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( width > longest_field_width ) {\n\t\t\t\tlongest_field_width = width;\n\t\t\t}\n\n\t\t\t//Debug.Text( ' Column: '+ field +' Width: '+ width +' Content: \\''+ longest_cell_content +'\\' Longest Column Width: '+ longest_field_width +' Header is Longest: '+ header_is_longest, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\n\t\t\tcolumn_widths[field] = width;\n\t\t\tthis.grid_total_width += width;\n\t\t}\n\n\t\t//If the longest column width can be used for all columns, size them all equally so they don't change sizes between pages.\n\t\tif ( ( longest_field_width * column_model.length ) <= options.min_grid_width ) {\n\t\t\tvar equal_column_width = Math.floor( ( options.min_grid_width - cb_column_width ) / ( column_model.length - cb_column_count_adjustment ) );\n\t\t\tvar equal_column_width_remainder = ( ( options.min_grid_width - cb_column_width ) % ( column_model.length - cb_column_count_adjustment ) ); //Eliminate partial pixel adjustments.\n\t\t\tDebug.Text( ' Grid columns CAN fit with equal sizes... Grid Width: ' + options.min_grid_width + ' Optimal Grid Width: ' + this.grid_total_width + ' Equal Size Width: ' + equal_column_width + ' Remainder: ' + equal_column_width_remainder, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\n\t\t\tvar adjusted_grid_width = 0;\n\n\t\t\tvar x = 0;\n\t\t\tfor ( var tmp_column_name in column_widths ) {\n\t\t\t\tif ( tmp_column_name == 'cb' ) {\n\t\t\t\t\tthis.grid.setColWidth( 'cb', cb_column_width );\n\t\t\t\t\tadjusted_grid_width += cb_column_width;\n\t\t\t\t} else {\n\t\t\t\t\tvar tmp_column_width = equal_column_width;\n\n\t\t\t\t\tif ( x == 1 ) {\n\t\t\t\t\t\ttmp_column_width += equal_column_width_remainder;\n\t\t\t\t\t}\n\n\t\t\t\t\t//Debug.Text( ' Adjusted Column: '+ tmp_column_name +' Width: Old: '+ column_widths[tmp_column_name] +' New: '+ tmp_column_width, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\t\t\t\t\tif ( this.grid.getColProp( tmp_column_name ).width != tmp_column_width ) {\n\t\t\t\t\t\tthis.grid.setColWidth( tmp_column_name, tmp_column_width );\n\t\t\t\t\t}\n\t\t\t\t\tadjusted_grid_width += tmp_column_width;\n\t\t\t\t}\n\n\t\t\t\tthis.grid.setColProp( tmp_column_name, 'fixed', true );\n\n\t\t\t\tx++;\n\t\t\t}\n\t\t\tDebug.Text( ' Adjusted Grid Width: ' + adjusted_grid_width + ' Adjusted Column Remainder: ' + equal_column_width_remainder, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\n\t\t\tthis.grid_total_width = options.min_grid_width;\n\t\t} else {\n\t\t\tDebug.Text( ' Optimal Grid Width: ' + this.grid_total_width + ' Equal Size Width: ' + ( longest_field_width * column_model.length ), 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\n\t\t\tvar body_width_difference = 0;\n\t\t\tvar column_width_adjustment = 0;\n\t\t\tvar columns_to_adjust_width = 0;\n\t\t\tvar column_width_adjustment_remainder = 0;\n\n\t\t\t//If the optimal column widths are wider than the max grid width, shrink them to fit.\n\t\t\tif ( ( options.max_grid_width > 0 && this.grid_total_width > options.max_grid_width ) || ( options.min_grid_width > 0 && this.grid_total_width < options.min_grid_width ) ) {\n\t\t\t\t//When columns are too small to fit on the screen and need to be stretched, ignore the overridden column.\n\t\t\t\tif ( ( options.max_grid_width > 0 && this.grid_total_width > options.max_grid_width ) ) {\n\t\t\t\t\tbody_width_difference = this.grid_total_width - options.max_grid_width; //Should be a negative difference to shrink columns to fit max width.\n\t\t\t\t\tthis.grid_total_width = options.max_grid_width;\n\t\t\t\t} else {\n\t\t\t\t\tbody_width_difference = options.min_grid_width - this.grid_total_width; //Should be a positive difference to grow columns to fit min width.\n\t\t\t\t\tthis.grid_total_width = options.min_grid_width;\n\t\t\t\t}\n\n\t\t\t\tif ( body_width_difference != 0 ) {\n\t\t\t\t\tif ( options.column_width_override ) {\n\t\t\t\t\t\tcolumns_to_adjust_width = ( column_model.length - options.column_width_override.length() );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcolumns_to_adjust_width = ( column_model.length - cb_column_count_adjustment );\n\t\t\t\t\t}\n\t\t\t\t\tcolumn_width_adjustment = Math.floor( body_width_difference / columns_to_adjust_width );\n\t\t\t\t\tcolumn_width_adjustment_remainder = ( body_width_difference % columns_to_adjust_width ); //Eliminate partial pixel adjustments.\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar adjusted_grid_width = 0;\n\n\t\t\tvar x = 0;\n\t\t\tfor ( var tmp_column_name in column_widths ) {\n\t\t\t\tif ( tmp_column_name == 'cb' ) {\n\t\t\t\t\tthis.grid.setColWidth( 'cb', cb_column_width );\n\t\t\t\t\tadjusted_grid_width += cb_column_width;\n\t\t\t\t} else {\n\t\t\t\t\tvar tmp_column_width;\n\t\t\t\t\tif ( options.column_width_override && options.column_width_override[n] ) {\n\t\t\t\t\t\ttmp_column_width = column_widths[tmp_column_name];\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttmp_column_width = column_widths[tmp_column_name] + column_width_adjustment;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( x == 1 ) { //First column after the CB.\n\t\t\t\t\t\ttmp_column_width += column_width_adjustment_remainder;\n\t\t\t\t\t}\n\n\t\t\t\t\tDebug.Text( ' Adjusted Column: ' + tmp_column_name + ' Width: Old: ' + column_widths[tmp_column_name] + ' New: ' + tmp_column_width + ' Adjustment: ' + column_width_adjustment + ' Body Difference: ' + body_width_difference + ' Columns Adjusted: ' + columns_to_adjust_width, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\t\t\t\t\tif ( this.grid.getColProp( tmp_column_name ).width != tmp_column_width ) {\n\t\t\t\t\t\tthis.grid.setColWidth( tmp_column_name, tmp_column_width );\n\t\t\t\t\t}\n\t\t\t\t\tadjusted_grid_width += tmp_column_width;\n\t\t\t\t}\n\t\t\t\tthis.grid.setColProp( tmp_column_name, 'fixed', true );\n\n\t\t\t\tx++;\n\t\t\t}\n\t\t\t//Debug.Text( ' Adjusted Grid Width: '+ adjusted_grid_width +' Adjusted Column Remainder: '+ column_width_adjustment_remainder, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\t\t}\n\n\t\t//this.setGridWidth( this.grid_total_width, this.grid_total_width ); //Causes columns with to flucuate, specifically in schedule day mode.\n\t\tDebug.Text( ' FINAL Grid width: ' + this.grid_total_width + ' Body Width: ' + Global.bodyWidth() + ' Total Rows: ' + grid_data.length, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\t\treturn this.grid_total_width;\n\t};\n\n\t//resize event.\n\t$( window ).off( 'resize.grids' ).on( 'resize.grids', Global.debounce( ( e ) => this.TTGridResizeEvent( e ), 500 ) );\n\n\tthis.TTGridResizeEvent = function( e ) {\n\t\te.stopPropagation();\n\t\tDebug.Text( ' Window resize event hit by TTGrid. Target: ' + e.target, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\n\t\tif ( LocalCacheData.resizeable_grids.length > 0 ) {\n\n\t\t\t//remove the nulls\n\t\t\tvar grids = LocalCacheData.resizeable_grids.filter( function( t ) {\n\t\t\t\treturn t != null;\n\t\t\t} );\n\t\t\tLocalCacheData.resizeable_grids = grids;\n\n\t\t\tfor ( var i in LocalCacheData.resizeable_grids ) {\n\t\t\t\tvar ttgrid = LocalCacheData.resizeable_grids[i];\n\n\t\t\t\tif ( !ttgrid || ( typeof ttgrid.getTableIDElement === 'function' && ttgrid.getTableIDElement().length === 0 ) || !ttgrid.grid || ttgrid.setup.onResizeGrid === false ) {\n\t\t\t\t\tDebug.Arr( LocalCacheData.resizeable_grids, ' Grid ignored ' + i, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\t\t\t\t\tLocalCacheData.resizeable_grids[i] = null;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t//Try to only resize visible grids. ie: Switch from Audit tab to primary tab, wait until resize event is triggered, then switch back, triggering \"flashing\" of scroll bars appearing/disappearing\n\t\t\t\t// Only happens on edit views with double row fields (ie: Note fields), like Edit Punch or Edit Schedule.\n\t\t\t\tif ( ttgrid.getTableIDElement().is( ':visible' ) ) {\n\t\t\t\t\tDebug.Text( ' Processing: ' + ttgrid.ui_id, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\t\t\t\t\tif ( ttgrid.setup.onResizeGrid && typeof ttgrid.setup.onResizeGrid == 'function' ) {\n\t\t\t\t\t\tDebug.Text( ' TTGrid invoked setup defined onResizeGrid() for ' + ttgrid.ui_id, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\t\t\t\t\t\tttgrid.setup.onResizeGrid();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( ttgrid.grid.length == 1 ) {\n\t\t\t\t\t\t\tDebug.Text( ' TTGrid invoked TTgrid::setGridColumnsWidth() for ' + ttgrid.ui_id, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\t\t\t\t\t\t\tttgrid.setGridColumnsWidth();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tDebug.Text( ' Skipping grid that is not visible: ' + ttgrid.ui_id, 'TTGrid.js', 'TTGrid', 'setGridColumnsWidth', 10 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//Usually we will want to make double sure that visible search grids resize.\n\t\t\t//Have to check for grid though because dashboard has no \"search grid\"\n\t\t\tif ( LocalCacheData.current_open_primary_controller && LocalCacheData.current_open_primary_controller.grid ) {\n\t\t\t\tLocalCacheData.current_open_primary_controller.setGridColumnsWidth(); //Be sure to call the setGridColumnsWidth() from current_open_primary_controller in case its overridden.\n\t\t\t\tLocalCacheData.current_open_primary_controller.setGridSize();\n\t\t\t}\n\n\t\t\t//Also resize grids inside Edit Views.\n\t\t\tif ( LocalCacheData.current_open_sub_controller && LocalCacheData.current_open_sub_controller.grid ) {\n\t\t\t\tLocalCacheData.current_open_sub_controller.setGridColumnsWidth(); //Be sure to call the setGridColumnsWidth() from current_open_sub_controller in case its overridden.\n\t\t\t\tLocalCacheData.current_open_sub_controller.setGridSize();\n\t\t\t}\n\t\t}\n\t}\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,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Q0E7O0FBRUE7QUFDQTtBQUNBLHNFQUFzRTtBQUN0RTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vaW50ZXJmYWNlL2h0bWw1L2dsb2JhbC93aWRnZXRzL3R0Z3JpZC9UVEdyaWQuanM/MjVlOSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBhdXRob3I6IGpvc2hyQHRpbWV0cmV4LmNvbVxuICogQGRlc2NyaXB0aW9uIHdyYXBwZXIgY2xhc3MgZm9yIGpxZ3JpZCBpbiB0aW1ldHJleC5cbiAqIFJlcXVpcmVzIGZyZWUtanFncmlkIDQuMTUuNCsgYW5kIGpxdWVyeSAzLjMuMStcbiAqXG4gKiBAcGFyYW0gc2V0dXBcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5UVEdyaWQgPSBmdW5jdGlvbiggdGFibGVfaWQsIHNldHVwLCBjb2x1bW5faW5mb19hcnJheSApIHtcblx0dGhpcy5nZXRHcmlkSWQgPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy51aV9pZDtcblx0fTtcblxuXHR0aGlzLnNldFRhYmxlSURFbGVtZW50ID0gZnVuY3Rpb24oKSB7XG5cdFx0dGhpcy50YWJsZV9pZF9lbGVtZW50ID0gJCggJyMnICsgdGhpcy51aV9pZCApO1xuXHRcdHJldHVybiB0cnVlO1xuXHR9O1xuXG5cdHRoaXMuZ2V0VGFibGVJREVsZW1lbnQgPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy50YWJsZV9pZF9lbGVtZW50O1xuXHR9O1xuXG5cdGlmICggIXRhYmxlX2lkIHx8ICFzZXR1cCB8fCAhY29sdW1uX2luZm9fYXJyYXkgKSB7XG5cdFx0RGVidWcuVGV4dCggJ0VSUk9SOiBjb25zdHJ1Y3RvciByZXF1aXJlcyBhbGwgMyBhcmd1bWVudHMnLCAnVFRHcmlkLmpzJywgJ1RUR3JpZCcsICdjb25zdHJ1Y3RvcicsIDEwICk7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0dGhpcy51aV9pZCA9IHRhYmxlX2lkO1xuXG5cdC8vIElzc3VlICMyODkxIC0gRm9yY2luZyBHcmlkVW5sb2FkIGNhbiBjYXVzZSBncmlkcyBpbnNpZGUgYSBBQ29tYm9Cb3ggdG8gZGlzYXBwZWFyIGFmdGVyIHJlcGVhdGVkIG9wZW5pbmcuIENoZWNrIGZvciBjb250YWluZXJfc2VsZWN0b3IgaXMgdG8gbWl0aWdhdGUgdGhhdC5cblx0aWYgKCAhc2V0dXAuY29udGFpbmVyX3NlbGVjdG9yICkge1xuXHRcdC8vIFdlIGFyZSB1bmxvYWRpbmcgZ3JpZHMgd2l0aCB0aGUgc2FtZSBJRCBpZiB0aGV5IGV4aXN0IHRvIGhlbHAgcHJldmVudDogVW5jYXVnaHQgVHlwZUVycm9yOiBGYWlsZWQgdG8gZXhlY3V0ZSAncmVwbGFjZUNoaWxkJyBvbiAnTm9kZSc6IHBhcmFtZXRlciAyIGlzIG5vdCBvZiB0eXBlICdOb2RlJy5cblx0XHQvLyBMb29waW5nIHRocm91Z2ggYXJyYXkgaW4gcmV2ZXJzZSB0byBtYWtlIHN1cmUgbm8gaW5kZXggaXNzdWVzIGFmdGVyIHNwbGljaW5nLlxuXHRcdGZvciAoIHZhciBpID0gTG9jYWxDYWNoZURhdGEucmVzaXplYWJsZV9ncmlkcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSApIHtcblx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEucmVzaXplYWJsZV9ncmlkc1tpXSAhPSBudWxsICYmIExvY2FsQ2FjaGVEYXRhLnJlc2l6ZWFibGVfZ3JpZHNbaV0uZ3JpZCAhPSBudWxsICYmIExvY2FsQ2FjaGVEYXRhLnJlc2l6ZWFibGVfZ3JpZHNbaV0udWlfaWQgPT0gdGhpcy51aV9pZCApIHtcblx0XHRcdFx0TG9jYWxDYWNoZURhdGEucmVzaXplYWJsZV9ncmlkc1tpXS5ncmlkLmpxR3JpZCggJ0dyaWRVbmxvYWQnICk7XG5cdFx0XHRcdExvY2FsQ2FjaGVEYXRhLnJlc2l6ZWFibGVfZ3JpZHMuc3BsaWNlKCBpLCAxICk7XG5cdFx0XHR9IGVsc2UgaWYgKCBMb2NhbENhY2hlRGF0YS5yZXNpemVhYmxlX2dyaWRzW2ldID09IG51bGwgfHwgTG9jYWxDYWNoZURhdGEucmVzaXplYWJsZV9ncmlkc1tpXS5ncmlkID09IG51bGwgKSB7XG5cdFx0XHRcdC8vIExvY2FsQ2FjaGVEYXRhLnJlc2l6ZWFibGVfZ3JpZHMgYXJyYXkgZ2V0cyBmdWxsIG9mIG51bGwgdmFsdWVzIGZyb20gcmVzaXplIGV2ZW50IGFuZCB3ZSBhcmUgbWFraW5nIHN1cmUgdG8gY2xlYXIgaXQgb3V0LlxuXHRcdFx0XHRMb2NhbENhY2hlRGF0YS5yZXNpemVhYmxlX2dyaWRzLnNwbGljZSggaSwgMSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHZhciBtYXhfaGVpZ2h0ID0gbnVsbDtcblxuXHR0aGlzLnNldFRhYmxlSURFbGVtZW50KCk7XG5cdHZhciB0YWJsZV9kaXYgPSB0aGlzLmdldFRhYmxlSURFbGVtZW50KCk7XG5cblx0dGhpcy5ncmlkID0gbnVsbDtcblxuXHRpZiAoIHRhYmxlX2RpdlswXSA9PSBmYWxzZSApIHtcblx0XHREZWJ1Zy5UZXh0KCAnRVJST1I6IHRhYmxlX2lkIG5vdCBmb3VuZCBpbiBET00nLCAnVFRHcmlkLmpzJywgJ1RUR3JpZCcsICdjb25zdHJ1Y3RvcicsIDEwICk7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Ly9EZWZhdWx0IGdyaWQgc2V0dGluZ3MuXG5cdHZhciBkZWZhdWx0X3NldHVwID0ge1xuXHRcdGNvbnRhaW5lcl9zZWxlY3RvcjogJ2JvZHknLFxuXHRcdHN1Yl9ncmlkX21vZGU6IGZhbHNlLFxuXHRcdGFsdFJvd3M6IHRydWUsXG5cdFx0ZGF0YTogW10sXG5cdFx0ZGF0YXR5cGU6ICdsb2NhbCcsXG5cdFx0Ly9xdWlja0VtcHR5OiAndHJ1ZScsIC8vRGVmYXVsdCBpcyAncXVpY2tlc3QnLCBtaWdodCBmaXggSlMgRXhjZXB0aW9uOiBVbmNhdWdodCBUeXBlRXJyb3I6IEZhaWxlZCB0byBleGVjdXRlICdyZXBsYWNlQ2hpbGQnIG9uICdOb2RlJzogcGFyYW1ldGVyIDIgaXMgbm90IG9mIHR5cGUgJ05vZGUnLCBidXQgY2F1c2VzIHRoaXMgaW5zdGVhZDogVFRHcmlkLmpzP3Y9MTEuNi4xLTIwMTkxMTA4Ojk5IFVuY2F1Z2h0IFR5cGVFcnJvcjogQ2Fubm90IHJlYWQgcHJvcGVydHkgJ2NlbGxzJyBvZiB1bmRlZmluZWRcblx0XHRzb3J0YWJsZTogZmFsc2UsXG5cdFx0aGVpZ2h0OiB0YWJsZV9kaXYucGFyZW50cyggJy52aWV3JyApLmhlaWdodCgpLFxuXHRcdHdpZHRoOiB0YWJsZV9kaXYucGFyZW50KCkud2lkdGgoKSxcblx0XHRyb3dOdW06IDEwMDAwLFxuXHRcdGNvbE5hbWVzOiBbXSxcblx0XHRjb2xNb2RlbDogY29sdW1uX2luZm9fYXJyYXksXG5cdFx0bXVsdGlzZWxlY3Q6IHRydWUsXG5cdFx0bXVsdGlzZWxlY3RXaWR0aDogMjIsXG5cdFx0bXVsdGlib3hvbmx5OiB0cnVlLFxuXHRcdHZpZXdyZWNvcmRzOiB0cnVlLFxuXHRcdGF1dG9lbmNvZGU6IHRydWUsXG5cdFx0c2Nyb2xsT2Zmc2V0OiAwLFxuXHRcdHZlcnRpY2FsUmVzaXplOiB0cnVlLCAvL3doZW4gdGhlIGdyaWQgcmVzaXplcyBkbyB3ZSByZWlzaXplIGl0IHZlcnRpY2FsbHk/IG5lZWRlZCBmb3IgdGltZXNoZWV0IGFuZCBzdWJncmlkIHZpZXdzLlxuXHRcdHJlc2l6ZUdyaWQ6IHRydWUsXG5cdFx0d2luTXVsdGlTZWxlY3Q6IHRydWVcblx0XHQvLyByZXNpemVTdG9wOiBmdW5jdGlvbih3aWR0aCwgaW5kZXgpe1xuXHRcdC8vIFx0Ly8kdGhpcy5zZXRHcmlkQ29sdW1uc1dpZHRoKHdpZHRoLCBpbmRleCk7XG5cdFx0Ly8gfVxuXHR9O1xuXG5cdGlmICggc2V0dXAubWF4X2hlaWdodCA9PT0gdHJ1ZSApIHtcblx0XHRzZXR1cC5tYXhfaGVpZ2h0ID0gbWF4X2hlaWdodDtcblx0fVxuXG5cdGlmICggc2V0dXAgKSB7XG5cdFx0c2V0dXAgPSAkLmV4dGVuZCgge30sIGRlZmF1bHRfc2V0dXAsIHNldHVwICk7XG5cdH0gZWxzZSB7XG5cdFx0c2V0dXAgPSBkZWZhdWx0X3NldHVwO1xuXHR9XG5cblx0dGhpcy5zZXR1cCA9IHNldHVwO1xuXG5cdHRhYmxlX2Rpdi5lbXB0eSgpOyAvL3Nob3VsZCB1bmJpbmQgYWxsIGV2ZW50cyBib3VuZCB0byB0aGUgZ3JpZC5cblx0dGhpcy5ncmlkID0gdGFibGVfZGl2LmpxR3JpZCggc2V0dXAgKTtcblxuXHRMb2NhbENhY2hlRGF0YS5yZXNpemVhYmxlX2dyaWRzLnB1c2goIHRoaXMgKTtcblxuXHRpZiAoIHNldHVwLndpbk11bHRpU2VsZWN0ID09PSB0cnVlICkge1xuXHRcdHRoaXMuZ3JpZC53aW5NdWx0aVNlbGVjdCgpO1xuXHR9XG5cblx0Ly90dXJuIG9mZiBncmlkIHJlc2l6ZSBldmVudCAoZm9yIHNjaGVkdWxlIGdyaWRzIHRoYXQgbmVlZCB0byBiZSByZWJ1aWx0IG9uIGV2ZXJ5IHJlc2l6ZSlcblx0dGhpcy5ub1Jlc2l6ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdHRoaXMuc2V0dXAub25SZXNpemVHcmlkID0gZmFsc2U7XG5cdH07XG5cblx0LyoqXG5cdCAqXG5cdCAqIEBwYXJhbSBkYXRhXG5cdCAqL1xuXHR0aGlzLnNldERhdGEgPSBmdW5jdGlvbiggZGF0YSwgY2xlYXJfZ3JpZCApIHtcblx0XHRpZiAoIHRoaXMuZ3JpZCApIHtcblx0XHRcdC8vQ2xlYXIgZ3JpZCBieSBkZWZhdWx0LlxuXHRcdFx0Y2xlYXJfZ3JpZCA9ICggY2xlYXJfZ3JpZCA9PSBudWxsICkgPyB0cnVlIDogY2xlYXJfZ3JpZDtcblx0XHRcdGlmICggY2xlYXJfZ3JpZCA9PSB0cnVlICkge1xuXHRcdFx0XHR0aGlzLmdyaWQuY2xlYXJHcmlkRGF0YSgpO1xuXHRcdFx0fVxuXG5cdFx0XHQvL0FDb21ibyBtaWdodCBzZW5kIGRhdGEgYXMgXCJ0cnVlXCIgd2hlbiB0aGUgdW5zZWxlY3RlZCBncmlkIGlzIGJsYW5rIGFuZCBcIlNob3cgQWxsXCIgaXMgY2xpY2tlZC4gUHJldmVudCBhbnl0aGluZyBidXQgYW4gYXJyYXkgZnJvbSBiZWluZyBwYXNzZWQgaW50byBzZXRHcmlkUGFyYW0oICdkYXRhJyApLlxuXHRcdFx0aWYgKCBBcnJheS5pc0FycmF5KCBkYXRhICkgPT0gZmFsc2UgKSB7XG5cdFx0XHRcdGRhdGEgPSBbXTtcblx0XHRcdH1cblxuXHRcdFx0dGhpcy5ncmlkLnNldEdyaWRQYXJhbSggeyAnZGF0YSc6IGRhdGEgfSApLnRyaWdnZXIoICdyZWxvYWRHcmlkJyApO1xuXHRcdFx0Ly90aGlzLnNldEdyaWRDb2x1bW5zV2lkdGgoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhyb3coICdFUlJPUjogR3JpZCBpcyBub3QgcmVhZHkgeWV0LicgKTtcblx0XHR9XG5cdH07XG5cdHRoaXMuZ2V0RGF0YSA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmdldEdyaWRQYXJhbSggJ2RhdGEnICk7XG5cdH07XG5cblx0dGhpcy5nZXRTZXR1cCA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmdldEdyaWRQYXJhbSggJ2RhdGEnICk7XG5cdH07XG5cblx0dGhpcy5nZXRIZWlnaHQgPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gJCggdGhpcy5ncmlkICkuaGVpZ2h0KCk7XG5cdH07XG5cdHRoaXMuZ2V0V2lkdGggPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gJCggdGhpcy5ncmlkICkud2lkdGgoKTtcblx0fTtcblxuXHQvKipcblx0ICpcblx0ICogQHBhcmFtIHZhbHVlXG5cdCAqL1xuXHR0aGlzLmRlbGV0ZVJvdyA9IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR0aGlzLmdyaWQuanFHcmlkKCAnZGVsUm93RGF0YScsIHZhbHVlICk7XG5cdH07XG5cblx0dGhpcy5yZXNldFNlbGVjdGlvbiA9IGZ1bmN0aW9uKCkge1xuXHRcdHRoaXMuZ3JpZC5yZXNldFNlbGVjdGlvbigpO1xuXHR9O1xuXG5cdHRoaXMuc2V0U2VsZWN0aW9uID0gZnVuY3Rpb24oIHgxLCB5MSwgeDIsIHkyLCBub1NjYWxlICkge1xuXHRcdHRoaXMuZ3JpZC5zZXRTZWxlY3Rpb24oIHgxLCB5MSwgeDIsIHkyLCBub1NjYWxlICk7XG5cdH07XG5cblx0dGhpcy5nZXRHcmlkUGFyYW0gPSBmdW5jdGlvbiggcGFyYW1ldGVyX25hbWUgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZ3JpZC5nZXRHcmlkUGFyYW0oIHBhcmFtZXRlcl9uYW1lICk7XG5cdH07XG5cblx0dGhpcy5zZXRHcmlkUGFyYW0gPSBmdW5jdGlvbiggcGFyYW1ldGVyX25hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiB0aGlzLmdyaWQuc2V0R3JpZFBhcmFtKCBwYXJhbWV0ZXJfbmFtZSwgdmFsdWUgKTtcblx0fTtcblxuXHR0aGlzLnVubG9hZCA9IGZ1bmN0aW9uKCkge1xuXHRcdGlmICggdGhpcy5ncmlkICkge1xuXHRcdFx0dGhpcy5ncmlkLmpxR3JpZCggJ0dyaWRVbmxvYWQnICk7XG5cdFx0XHR0aGlzLmdyaWQgPSBudWxsO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fTtcblxuXHR0aGlzLmNsZWFyR3JpZERhdGEgPSBmdW5jdGlvbigpIHtcblx0XHR0aGlzLmdyaWQuanFHcmlkKCAnY2xlYXJHcmlkRGF0YScsIHRydWUgKTtcblx0fTtcblxuXHR0aGlzLnJlbG9hZEdyaWQgPSBmdW5jdGlvbigpIHtcblx0XHR0aGlzLmdyaWQudHJpZ2dlciggJ3JlbG9hZEdyaWQnICk7XG5cdH07XG5cblx0dGhpcy5nZXRSZWNvcmRGcm9tR3JpZEJ5SWQgPSBmdW5jdGlvbiggaWQgKSB7XG5cdFx0dmFyIGRhdGEgPSB0aGlzLmdyaWQuZ2V0R3JpZFBhcmFtKCAnZGF0YScgKTtcblx0XHR2YXIgcmVzdWx0ID0gbnVsbDtcblx0XHQvKiBqc2hpbnQgaWdub3JlOnN0YXJ0ICovXG5cdFx0Ly9pZCBjb3VsZCBiZSBzdHJpbmcgb3IgbnVtYmVyLlxuXHRcdCQuZWFjaCggZGF0YSwgZnVuY3Rpb24oIGluZGV4LCB2YWx1ZSApIHtcblxuXHRcdFx0aWYgKCB2YWx1ZVsnX2lkXyddID09IGlkICkge1xuXHRcdFx0XHRyZXN1bHQgPSBHbG9iYWwuY2xvbmUoIHZhbHVlICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblxuXHRcdH0gKTtcblx0XHQvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG5cdFx0aWYgKCByZXN1bHQgKSB7XG5cdFx0XHRyZXN1bHQuaWQgPSByZXN1bHRbJ19pZF8nXTtcblx0XHR9XG5cdFx0cmV0dXJuIHJlc3VsdDtcblxuXHR9O1xuXG5cdHRoaXMuZ2V0R3JpZFdpZHRoID0gZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCB0aGlzLmdyaWQgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5ncmlkLndpZHRoKCk7XG5cdFx0fVxuXHRcdHJldHVybiAwO1xuXHR9O1xuXG5cdHRoaXMuc2V0R3JpZFdpZHRoID0gZnVuY3Rpb24oIHcsIGlubmVyX3dpZHRoICkge1xuXHRcdGlmICggdGhpcy5ncmlkICkge1xuXHRcdFx0aWYgKCBpbm5lcl93aWR0aCA+IHcgKSB7XG5cdFx0XHRcdHcgPSBpbm5lcl93aWR0aDtcblx0XHRcdH1cblx0XHRcdHRoaXMuZ3JpZC5zZXRHcmlkV2lkdGgoIHcgKTtcblx0XHR9XG5cdH07XG5cblx0dGhpcy5nZXRHcmlkSGVpZ2h0ID0gZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCB0aGlzLmdyaWQgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5ncmlkLmhlaWdodCgpO1xuXHRcdH1cblx0XHRyZXR1cm4gMDtcblx0fTtcblx0dGhpcy5zZXRHcmlkSGVpZ2h0ID0gZnVuY3Rpb24oIGggKSB7XG5cdFx0aWYgKCB0aGlzLnNldHVwLnN0YXRpY19oZWlnaHQgKSB7XG5cdFx0XHRoID0gdGhpcy5zZXR1cC5zdGF0aWNfaGVpZ2h0O1xuXHRcdH1cblxuXHRcdGlmICggdGhpcy5ncmlkICkge1xuXHRcdFx0dGhpcy5ncmlkLnNldEdyaWRIZWlnaHQoIGggKTtcblx0XHR9XG5cdH07XG5cblx0dGhpcy5zZXRSb3dEYXRhID0gZnVuY3Rpb24oIGlkLCBuZXdfcmVjb3JkICkge1xuXHRcdHRoaXMuZ3JpZC5zZXRSb3dEYXRhKCBpZCwgbmV3X3JlY29yZCApO1xuXHR9O1xuXG5cdHRoaXMuZ2V0Um93RGF0YSA9IGZ1bmN0aW9uKCByb3dfaWQgKSB7XG5cdFx0dmFyIHJvdyA9IGZhbHNlO1xuXG5cdFx0dmFyIHJvd19kYXRhID0gdGhpcy5nZXREYXRhKCk7XG5cblx0XHRmb3IgKCB2YXIgaSBpbiByb3dfZGF0YSApIHtcblx0XHRcdGlmICggcm93X2RhdGFbaV0uaWQgPT0gcm93X2lkICkge1xuXHRcdFx0XHRyb3cgPSByb3dfZGF0YVtpXTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJvdztcblx0fTtcblxuXHR0aGlzLmdldENvbHVtbk1vZGVsID0gZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZ2V0R3JpZFBhcmFtKCAnY29sTW9kZWwnICk7XG5cdH07XG5cblx0dGhpcy5zZXRDb2x1bW5Nb2RlbCA9IGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0dGhpcy5nZXRHcmlkUGFyYW0oICdjb2xNb2RlbCcsIHZhbCApO1xuXHR9O1xuXG5cdHRoaXMuZ3JpZDJjc3YgPSBmdW5jdGlvbiggZmlsZW5hbWUgKSB7XG5cdFx0Ly8gVE9ETzogQWRkIGluIG1vcmUgcm9idXN0IHF1b3RlIGVzY2FwaW5nIHRvIGhhbmRsZSBkYXRhIHN0cmluZ3MgdGhhdCBoYXZlIHF1b3Rlcy4gQ3VycmVudGx5IHdlIGFyZSBqdXN0IHdyYXBwaW5nIGV2ZXJ5dGhpbmcgaW4gZG91YmxlIHF1b3Rlcy5cblxuXHRcdGxldCBjc3ZfZGF0YSA9IFtdO1xuXG5cdFx0Ly8gR2V0IGdyaWQgZGF0YSBmb3IgY3N2LlxuXHRcdC8vIENvbHVtbiBoZWFkZXJzIGFyZSBpbiBhIGRpZmZlcmVudCB0YWJsZS4gU2VlbXMgdG8gYmUgYSBqcUdyaWQgdGhpbmc/XG5cdFx0Ly8gUGFyc2luZyBjb2x1bW4gaGVhZGVycyB1c2luZyBhcmlhLWRlc2NyaWJlZGJ5IG9uIHRoZSBmaXJzdCBub25lIGJsYW5rIDx0cj4gKDJuZCkgd2hpY2ggbGlua3MgdG8gdGhlIGlkIG9mIHRoZSBoZWFkZXIgYW5kIGZyb20gdGhlcmUgZ2V0cyB0aGUgdGV4dENvbnRlbnQuXG5cdFx0bGV0IGkgPSAxO1xuXHRcdGxldCBoZWFkZXJzID0gW107XG5cdFx0Zm9yICggbGV0IHRyIG9mIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoICcjJyArIHRoaXMuZ2V0R3JpZElkKCkgKyAnIHRyJyApICkge1xuXHRcdFx0bGV0IHJvdyA9IFtdO1xuXHRcdFx0Zm9yICggbGV0IHRkIG9mIHRyLnF1ZXJ5U2VsZWN0b3JBbGwoICd0ZCcgKSApIHtcblx0XHRcdFx0cm93LnB1c2goICdcIicgKyB0ZC50ZXh0Q29udGVudC50cmltKCkgKyAnXCInICk7XG5cdFx0XHRcdGlmICggaSA9PT0gMiApIHtcblx0XHRcdFx0XHQvLyBDb2x1bW4gaGVhZGVycyBzb21ldGltZXMgY29udGFpbiBIVE1MIHN1Y2ggYXMgQ2xhaW08YnI+RGVwZW5kZW50cy5cblx0XHRcdFx0XHQvLyBVc2luZyBhIHRlbXBvcmFyeSBlbGVtZW50IHRvIHJlcGxhY2UgPGJyPiB3aXRoIGEgc3BhY2UgYW5kIHRoZW4gZ3JhYmJpbmcgdGhlIHRleHRDb250ZW50IHRvIHN0cmlwIHRoZSBIVE1MLlxuXHRcdFx0XHRcdGxldCB0ZW1wX2VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAnZGl2JyApO1xuXHRcdFx0XHRcdHRlbXBfZWxlbWVudC5pbm5lckhUTUwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCggdGQuZ2V0QXR0cmlidXRlKCAnYXJpYS1kZXNjcmliZWRieScgKSApLmlubmVySFRNTC5yZXBsYWNlKCAnPGJyPicsICcgJyApO1xuXHRcdFx0XHRcdGhlYWRlcnMucHVzaCggJ1wiJyArIHRlbXBfZWxlbWVudC50ZXh0Q29udGVudC50cmltKCkgKyAnXCInICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGNzdl9kYXRhLnB1c2goIHJvdy5qb2luKCAnLCcgKSApO1xuXHRcdFx0aSsrO1xuXHRcdH1cblxuXHRcdC8vIFJlcGxhY2UgYmxhbmsgcm93IHdpdGggdGFibGUgaGVhZGVyc1xuXHRcdGNzdl9kYXRhWzBdID0gaGVhZGVycy5qb2luKCAnLCcgKTtcblxuXHRcdGxldCBjc3ZfY29udGVudCA9IGNzdl9kYXRhLmpvaW4oICdcXHJcXG4nICk7XG5cblx0XHRHbG9iYWwuSlNGaWxlRG93bmxvYWQoIGZpbGVuYW1lICsgJy5jc3YnLCBjc3ZfY29udGVudCwgJ3RleHQvY3N2O2VuY29kaW5nOnV0Zi04JyApO1xuXG5cdH1cblxuXHR0aGlzLmdldFJlY29yZENvdW50ID0gZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCAhdGhpcy5ncmlkICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmdyaWQuZ2V0R3JpZFBhcmFtKCAncmVjY291bnQnICk7XG5cdH07XG5cblx0Ly9HZXRzIGEgc2luZ2xlIHJvd1xuXHR0aGlzLmdldFNlbGVjdGVkUm93ID0gZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCAhdGhpcy5ncmlkICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHZhciByZXN1bHQgPSB0aGlzLmdyaWQuZ2V0R3JpZFBhcmFtKCAnc2Vscm93JyApO1xuXG5cdFx0aWYgKCAhcmVzdWx0ICkge1xuXHRcdFx0cmVzdWx0ID0gZmFsc2U7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fTtcblxuXHQvL0dldHMgYW4gYXJyYXkgb2Ygcm93cyBpZiBtdWx0aXBsZSBhcmUgc2VsZWN0ZWQuXG5cdHRoaXMuZ2V0U2VsZWN0ZWRSb3dzID0gZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCAhdGhpcy5ncmlkICkge1xuXHRcdFx0cmV0dXJuIFtdOyAvL1JldHVybiBlbXB0eSBhcnJheSBzbyAubGVuZ3RoIG9uIHRoZSByZXN1bHQgZG9lc24ndCBmYWlsIHdpdGggQ2Fubm90IHJlYWQgcHJvcGVydHkgJ2xlbmd0aCcgb2YgdW5kZWZpbmVkXG5cdFx0fVxuXG5cdFx0dmFyIHJlc3VsdCA9IHRoaXMuZ3JpZC5nZXRHcmlkUGFyYW0oICdzZWxhcnJyb3cnICk7XG5cblx0XHRpZiAoICFyZXN1bHQgKSB7XG5cdFx0XHRyZXN1bHQgPSBbXTtcblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9O1xuXG5cdHRoaXMuZ2V0U2VsZWN0aW9uID0gZnVuY3Rpb24oKSB7XG5cdFx0dmFyIHRkcyA9IHRoaXMuZ3JpZC5maW5kKCAndGQudWktc3RhdGUtaGlnaGxpZ2h0JyApO1xuXG5cdFx0dmFyIHNlbGVjdGlvbiA9IFtdO1xuXHRcdGZvciAoIHZhciB4ID0gMDsgeCA8IHRkcy5sZW5ndGg7IHgrKyApIHtcblx0XHRcdHNlbGVjdGlvbi5wdXNoKCB7XG5cdFx0XHRcdHRyOiAkKCB0ZHNbeF0gKS5wYXJlbnQoICd0cicgKS5pbmRleCgpLFxuXHRcdFx0XHR0ZDogJCggdGRzW3hdICkuaW5kZXgoKVxuXHRcdFx0fSApO1xuXHRcdH1cblx0XHRyZXR1cm4gc2VsZWN0aW9uO1xuXHR9LFxuXG5cdFx0dGhpcy5zZXRUaW1lc2hlZXRTZWxlY3Rpb24gPSBmdW5jdGlvbiggc2VsZWN0aW9uX29iaiApIHtcblx0XHRcdC8vVGhpcyBpcyBjdXJyZW50bHkgYnJva2VuLCBpdCBoaWdobGlnaHRzIHRoZSBjZWxscywgYnV0IHRoZXkgYXJlbid0IGFjdHVhbGx5IGNvbnNpZGVyZWQgXCJzZWxlY3RlZFwiLlxuXHRcdFx0Ly8gU28gaWYgeW91IGdvIHRvIEF0dGVuZGFuY2UgLT4gVGltZVNoZWV0LCBzZWxlY3QgdHdvIGNlbGxzLCBNYXNzIEVkaXQgdGhlbSwgY2xpY2sgU2F2ZSwgdGhlIFwiTWFzcyBFZGl0XCIgaXMgbm8gbG9uZ2VyIGF2YWlsYWJsZSB0byBiZSBjbGlja2VkIGFnYWluLlxuXHRcdFx0Ly8gQXMgd2VsbCBpZiB5b3UgaG9sZCBpbiBTSElGVCB0byB0cnkgYW5kIGV4cGFuZCB0aGUgc2VsZWN0aW9uIChzZWxlY3QgbW9yZSBjZWxscyksIHRoYXQgZG9lc24ndCB3b3JrIGVpdGhlci5cblx0XHRcdHZhciB0cnMgPSB0aGlzLmdyaWQuZmluZCggJ3RyJyApO1xuXHRcdFx0Zm9yICggdmFyIGkgPSAwOyBpIDwgc2VsZWN0aW9uX29iai5sZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0Zm9yICggdmFyIHggPSAwOyB4IDwgdHJzLmxlbmd0aDsgeCsrICkge1xuXHRcdFx0XHRcdGlmICggJCggdHJzW3hdICkuaW5kZXgoKSA9PSBzZWxlY3Rpb25fb2JqW2ldLnRyICkge1xuXHRcdFx0XHRcdFx0dmFyIHRkcyA9ICQoIHRyc1t4XSApLmZpbmQoICd0ZCcgKTtcblx0XHRcdFx0XHRcdGZvciAoIHZhciB3ID0gMDsgdyA8IHRkcy5sZW5ndGg7IHcrKyApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCAkKCB0ZHNbd10gKS5pbmRleCgpID09IHNlbGVjdGlvbl9vYmpbaV0udGQgKSB7XG5cdFx0XHRcdFx0XHRcdFx0JCggdGRzW3ddICkuYWRkQ2xhc3MoICd1aS1zdGF0ZS1oaWdobGlnaHQnICk7XG5cdFx0XHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cblx0dGhpcy5zZXRHcmlkQ29sdW1uc1dpZHRoID0gZnVuY3Rpb24oIGNvbHVtbl9tb2RlbCwgb3B0aW9ucyApIHtcblx0XHQvLyB0aGlzLmdyaWQuYXV0b1Jlc2l6ZUFsbENvbHVtbnMoKTtcblx0XHQvLyByZXR1cm47XG5cdFx0aWYgKCB0aGlzLnNldHVwLnRyZWVHcmlkIHx8IHRoaXMuc2V0dXAudHJlZV9tb2RlICkge1xuXHRcdFx0dGhpcy5zZXRHcmlkV2lkdGgoICQoIHRoaXMuc2V0dXAuY29udGFpbmVyX3NlbGVjdG9yICkud2lkdGgoKSAtIDEyICk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCB0eXBlb2Ygb3B0aW9ucyA9PT0gJ3VuZGVmaW5lZCcgKSB7XG5cdFx0XHRvcHRpb25zID0ge307XG5cdFx0fVxuXG5cdFx0aWYgKCB0aGlzLnNldHVwLmNvbnRhaW5lcl9zZWxlY3RvciAmJiAoICFvcHRpb25zLm1pbl9ncmlkX3dpZHRoIHx8IG9wdGlvbnMubWluX2dyaWRfd2lkdGggPT0gMCApICkge1xuXHRcdFx0dmFyIHBhcmVudF9jb250YWluZXIgPSB0aGlzLmdyaWQucGFyZW50cyggdGhpcy5zZXR1cC5jb250YWluZXJfc2VsZWN0b3IgKS5maW5kKCAnLmVkaXQtdmlldy10YWInICk7XG5cdFx0XHRpZiAoIHBhcmVudF9jb250YWluZXIubGVuZ3RoID4gMCApIHtcblx0XHRcdFx0Ly9TdWItVmlldyBncmlkLCBjaGVjayBpZiBwYXJlbnQgZGl2IGlzIHZpc2libGUsIGFuZCBpZiBub3QgZG9uJ3QgYm90aGVyIHJlc2l6aW5nIGdyaWQuXG5cdFx0XHRcdGlmICggcGFyZW50X2NvbnRhaW5lci5pcyggJzp2aXNpYmxlJyApID09PSB0cnVlICkge1xuXHRcdFx0XHRcdG9wdGlvbnMubWluX2dyaWRfd2lkdGggPSBwYXJlbnRfY29udGFpbmVyLmlubmVyV2lkdGgoKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHREZWJ1Zy5UZXh0KCAnICBQYXJlbnQgY29udGFpbmVyIG9mIGdyaWQgaXMgbm90IHZpc2libGUsIHNraXAgc2V0dGluZyBjb2x1bW4gd2lkdGhzLi4uJywgJ1RUR3JpZC5qcycsICdUVEdyaWQnLCAnc2V0R3JpZENvbHVtbnNXaWR0aCcsIDEwICk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvL01haW4gZ3JpZFxuXHRcdFx0XHRsZXQgZ3JpZF9wYXJlbnQgPSAkKCAnI2dib3hfJyArIHRoaXMudWlfaWQgKTtcblx0XHRcdFx0aWYgKCBncmlkX3BhcmVudC5sZW5ndGggIT09IDAgKSB7XG5cdFx0XHRcdFx0b3B0aW9ucy5taW5fZ3JpZF93aWR0aCA9IGdyaWRfcGFyZW50LnBhcmVudCgpLndpZHRoKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0b3B0aW9ucy5taW5fZ3JpZF93aWR0aCA9IHRoaXMuZ3JpZC5wYXJlbnRzKCB0aGlzLnNldHVwLmNvbnRhaW5lcl9zZWxlY3RvciApLmlubmVyV2lkdGgoKTtcblx0XHRcdFx0fVxuXG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCBvcHRpb25zLm1pbl9ncmlkX3dpZHRoID09IDAgfHwgb3B0aW9ucy5taW5fZ3JpZF93aWR0aCA9PSAndW5kZWZpbmVkJyApIHsgLy9mYWxsYmFjayB3aWR0aCBzbyBpdCdzIG5ldmVyIHNpemVkIHRvIHplcm8gd2hlbiByZW5kZXIgdGltaW5nIGNvbGxpZGVzXG5cdFx0XHRvcHRpb25zLm1pbl9ncmlkX3dpZHRoID0gJCggJ2JvZHknICkuaW5uZXJXaWR0aCgpO1xuXHRcdH1cblxuXHRcdC8vQWRqdXN0IGZvciB0aGUgdmVydGljYWwgc2Nyb2xsYmFyIG9mZnNldCB0aGF0IGNhbiBvY2N1ciB3aGVuIHRoZSBpdGVtcyBwZXIgcGFnZSBhbHdheXMgZXhjZWVkcyB0aGUgc2NyZWVuIGhlaWdodC5cblx0XHRpZiAoIEdsb2JhbC5pc1ZlcnRpY2FsU2Nyb2xsQmFyUmVxdWlyZWQoIHRoaXMuZ3JpZC5wYXJlbnRzKCAnLnVpLWpxZ3JpZC1iZGl2JyApWzBdICkgKSB7XG5cdFx0XHRvcHRpb25zLm1pbl9ncmlkX3dpZHRoIC09IEdsb2JhbC5nZXRTY3JvbGxiYXJXaWR0aCgpO1xuXHRcdH1cblxuXHRcdGlmICggIW9wdGlvbnMubWF4X2dyaWRfd2lkdGggKSB7XG5cdFx0XHRvcHRpb25zLm1heF9ncmlkX3dpZHRoID0gbnVsbDsgLy9ObyBtYXhpbXVtLlxuXHRcdH1cblxuXHRcdGlmICggb3B0aW9ucy5tYXhfZ3JpZF93aWR0aCAmJiBvcHRpb25zLm1heF9ncmlkX3dpZHRoIDwgb3B0aW9ucy5taW5fZ3JpZF93aWR0aCApIHtcblx0XHRcdG9wdGlvbnMubWluX2dyaWRfd2lkdGggPSBvcHRpb25zLm1heF9ncmlkX3dpZHRoO1xuXHRcdH1cblxuXHRcdERlYnVnLlRleHQoICdUYXJnZXQgR3JpZDogJyArIHRoaXMuc2V0dXAuY29udGFpbmVyX3NlbGVjdG9yICsgJyBUYXJnZXQgRGl2OiAnICsgdGhpcy5ncmlkLnBhcmVudHMoIHRoaXMuc2V0dXAuY29udGFpbmVyX3NlbGVjdG9yICkuaWQgKyAnIFdpZHRoOiBNaW46ICcgKyBvcHRpb25zLm1pbl9ncmlkX3dpZHRoICsgJyBNYXg6ICcgKyBvcHRpb25zLm1heF9ncmlkX3dpZHRoICsgJyBTY3JvbGxiYXIgT2Zmc2V0OiAnICsgR2xvYmFsLmdldFNjcm9sbGJhcldpZHRoKCkgKyAnIFBhcmVudCBXaWR0aDogJyArICQoIHRoaXMuZ3JpZC5wYXJlbnRzKCAnLmVkaXQtdmlldy10YWIsIGJvZHknIClbMF0gKS53aWR0aCgpLCAnVFRHcmlkLmpzJywgJ1RUR3JpZCcsICdzZXRHcmlkQ29sdW1uc1dpZHRoJywgMTAgKTtcblxuXHRcdGlmICggY29sdW1uX21vZGVsICkge1xuXHRcdFx0dmFyIHRvdGFsX2NvbHVtbl93aWR0aCA9IDA7XG5cdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBjb2x1bW5fbW9kZWwubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdHZhciBmaWVsZCA9IGNvbHVtbl9tb2RlbFtpXS5uYW1lO1xuXHRcdFx0XHR2YXIgd2lkdGggPSBjb2x1bW5fbW9kZWxbaV0ud2lkdGggPyBjb2x1bW5fbW9kZWxbaV0ud2lkdGggOiBjb2x1bW5fbW9kZWwud2lkdGhPcmc7XG5cdFx0XHRcdHRvdGFsX2NvbHVtbl93aWR0aCArPSB3aWR0aDtcblxuXHRcdFx0XHQvL0Rvbid0IGNoYW5nZSB0aGUgd2lkdGggb2YgY29sdW1ucyBpZiB0aGV5IGFyZSBhbHJlYWR5IHRoZSBzYW1lIHNpemUuIFRoaXMgbWF5IGhlbHAgYXZvaWQgbWlub3IgY2hhbmdlcyBpbiB0aGUgdGFibGUgY2F1c2VkIGJ5IHNpbXBsZSByZWRyYXdzLlxuXHRcdFx0XHRpZiAoIHRoaXMuZ3JpZC5nZXRDb2xQcm9wKCBmaWVsZCApLndpZHRoICE9IHdpZHRoICkge1xuXHRcdFx0XHRcdHRoaXMuZ3JpZC5zZXRDb2xXaWR0aCggZmllbGQsIHdpZHRoICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRvdGFsX2NvbHVtbl93aWR0aDtcblx0XHR9XG5cblx0XHR2YXIgY29sdW1uX21vZGVsID0gdGhpcy5nZXRDb2x1bW5Nb2RlbCgpO1xuXG5cdFx0Ly9Qb3NzaWJsZSBleGNlcHRpb25cblx0XHQvL0Vycm9yOiBVbmNhdWdodCBUeXBlRXJyb3I6IENhbm5vdCByZWFkIHByb3BlcnR5ICdsZW5ndGgnIG9mIHVuZGVmaW5lZCBpbiAvaW50ZXJmYWNlL2h0bWw1LyMhbT1UaW1lU2hlZXQmZGF0ZT0yMDE0MTEwMiZ1c2VyX2lkPTUzMTMwIGxpbmUgNDI4OFxuXHRcdGlmICggIWNvbHVtbl9tb2RlbCApIHtcblx0XHRcdERlYnVnLlRleHQoICdFUlJPUjogY29sdW1uX21vZGVsIGlzIG51bGwgb3IgdW5kZWZpbmVkJywgJ1RUR3JpZC5qcycsICdUVEdyaWQnLCAnc2V0R3JpZENvbHVtbnNXaWR0aCcsIDEwICk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gbG9uZ2VyKCBjaGFtcCwgY29udGVuZGVyICkge1xuXHRcdFx0cmV0dXJuICggY29udGVuZGVyLmxlbmd0aCA+IGNoYW1wLmxlbmd0aCApID8gY29udGVuZGVyIDogY2hhbXA7XG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gbG9uZ2VzdFdvcmQoIHN0ciApIHtcblx0XHRcdGlmICggc3RyICYmIHR5cGVvZiBzdHIgPT09ICdzdHJpbmcnICkge1xuXHRcdFx0XHR2YXIgd29yZHMgPSBzdHIuc3BsaXQoICcgJyApO1xuXHRcdFx0XHRyZXR1cm4gd29yZHMucmVkdWNlKCBsb25nZXIgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiAnJztcblx0XHRcdH1cblx0XHR9XG5cblx0XHR2YXIgZ3JpZF9kYXRhID0gdGhpcy5nZXREYXRhKCk7XG5cdFx0dGhpcy5ncmlkX3RvdGFsX3dpZHRoID0gMDtcblxuXHRcdHZhciBjYl9jb2x1bW5fd2lkdGggPSAwOyAvL2NoZWNrYm94IGNvbHVtbiB3aWR0aCwgdXN1YWxseSAyMiwgYnV0IG9ubHkgc2V0IG9uY2Ugd2Uga25vdyB0aGVyZSBpcyBhIGNoZWNrYm94IGNvbHVtbi5cblx0XHR2YXIgY2JfY29sdW1uX2NvdW50X2FkanVzdG1lbnQgPSAwOyAvL0lmIHRoZSBjaGVja2JveCBjb2x1bW4gZXhpc3RzIG9yIG5vdC5cblxuXHRcdHZhciBsb25nZXN0X2ZpZWxkX3dpZHRoID0gMDtcblx0XHR2YXIgbGFzdF9jb2x1bW4gPSBudWxsO1xuXHRcdHZhciBjb2x1bW5fd2lkdGhzID0ge307XG5cblx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBjb2x1bW5fbW9kZWwubGVuZ3RoOyBpKysgKSB7XG5cdFx0XHR2YXIgY29sID0gY29sdW1uX21vZGVsW2ldO1xuXHRcdFx0bGFzdF9jb2x1bW4gPSBjb2w7XG5cdFx0XHR2YXIgZmllbGQgPSBjb2wubmFtZTtcblx0XHRcdHZhciBsb25nZXN0X2NlbGxfY29udGVudCA9IGxvbmdlc3RXb3JkKCBjb2wubGFiZWwgKTsgLy8gYWxsb3cgZXh0cmEgc3BhY2UgZm9yIHNvcnQgb3JkZXIgVUkgaGludFxuXHRcdFx0dmFyIGhlYWRlcl9pc19sb25nZXN0ID0gdHJ1ZTtcblxuXHRcdFx0aWYgKCBmaWVsZCA9PSAnY2InICkgeyAvL2hhcmQgY29kZWQgb3ZlcnJpZGUgb24gQ0IgY29sdW1uLCBzbyB3ZSBkb24ndCB0cnkgdG8gY2hlY2sgdGhlIGRhdGEgaW4gZWFjaCByb3cgZm9yIGl0LlxuXHRcdFx0XHRjYl9jb2x1bW5fY291bnRfYWRqdXN0bWVudCA9IDE7XG5cdFx0XHRcdGNiX2NvbHVtbl93aWR0aCA9IDIyO1xuXHRcdFx0XHR3aWR0aCA9IGNiX2NvbHVtbl93aWR0aDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGlmICggb3B0aW9ucy5jb2x1bW5fd2lkdGhfb3ZlcnJpZGUgJiYgb3B0aW9ucy5jb2x1bW5fd2lkdGhfb3ZlcnJpZGVbZmllbGRdICkge1xuXHRcdFx0XHRcdHdpZHRoID0gb3B0aW9ucy5jb2x1bW5fd2lkdGhfb3ZlcnJpZGVbZmllbGRdO1xuXHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0Zm9yICggdmFyIGogPSAwOyBqIDwgZ3JpZF9kYXRhLmxlbmd0aDsgaisrICkge1xuXHRcdFx0XHRcdFx0dmFyIHJvd19kYXRhID0gZ3JpZF9kYXRhW2pdO1xuXHRcdFx0XHRcdFx0aWYgKCAhcm93X2RhdGEuaGFzT3duUHJvcGVydHkoIGZpZWxkICkgKSB7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR2YXIgY3VycmVudF9jZWxsX2NvbnRlbnQgPSByb3dfZGF0YVtmaWVsZF07XG5cdFx0XHRcdFx0XHRpZiAoICFjdXJyZW50X2NlbGxfY29udGVudCApIHtcblx0XHRcdFx0XHRcdFx0Y3VycmVudF9jZWxsX2NvbnRlbnQgPSAnJztcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKCAhbG9uZ2VzdF9jZWxsX2NvbnRlbnQgKSB7XG5cdFx0XHRcdFx0XHRcdGxvbmdlc3RfY2VsbF9jb250ZW50ID0gY3VycmVudF9jZWxsX2NvbnRlbnQudG9TdHJpbmcoKTtcblx0XHRcdFx0XHRcdFx0aGVhZGVyX2lzX2xvbmdlc3QgPSBmYWxzZTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGlmICggY3VycmVudF9jZWxsX2NvbnRlbnQgJiYgY3VycmVudF9jZWxsX2NvbnRlbnQudG9TdHJpbmcoKS5sZW5ndGggPiBsb25nZXN0X2NlbGxfY29udGVudC5sZW5ndGggKSB7XG5cdFx0XHRcdFx0XHRcdFx0bG9uZ2VzdF9jZWxsX2NvbnRlbnQgPSBjdXJyZW50X2NlbGxfY29udGVudC50b1N0cmluZygpO1xuXHRcdFx0XHRcdFx0XHRcdGhlYWRlcl9pc19sb25nZXN0ID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR2YXIgY2FsY3VsYXRlX3RleHRfd2lkdGhfb3B0aW9ucztcblx0XHRcdFx0XHRpZiAoIGxvbmdlc3RfY2VsbF9jb250ZW50ID09IGZpZWxkICkge1xuXHRcdFx0XHRcdFx0Y2FsY3VsYXRlX3RleHRfd2lkdGhfb3B0aW9ucyA9IHsgZm9udFNpemU6ICcxMXB4JywgZm9udFdlaWdodDogJ2JvbGRlcicgfTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Y2FsY3VsYXRlX3RleHRfd2lkdGhfb3B0aW9ucyA9IHsgZm9udFNpemU6ICcxMXB4JywgZm9udFdlaWdodDogJ25vcm1hbCcgfTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR2YXIgd2lkdGggPSBHbG9iYWwuY2FsY3VsYXRlVGV4dFdpZHRoKCBsb25nZXN0X2NlbGxfY29udGVudCwgY2FsY3VsYXRlX3RleHRfd2lkdGhfb3B0aW9ucyApOyAvLyArIDQwOyAvLyA4IGlzIGRyYWcgaGFuZGxlIHdpZHRoICsyIGZvciBib3JkZXJzICsyMCBmb3Igc29ydCBvcmRlciB1aSBoaW50ICgxNyBmb3IgYWN0dWFsIGhpbnQsMTMgZm9yIGhlYWRlciBwYWRkaW5nIG9uIEZpcmVmb3ggdW5kZXIgd2luZG93c1xuXG5cdFx0XHRcdFx0aWYgKCBoZWFkZXJfaXNfbG9uZ2VzdCA9PT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRcdHdpZHRoICs9IDQwO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR3aWR0aCArPSAxMjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0aWYgKCB3aWR0aCA+IGxvbmdlc3RfZmllbGRfd2lkdGggKSB7XG5cdFx0XHRcdGxvbmdlc3RfZmllbGRfd2lkdGggPSB3aWR0aDtcblx0XHRcdH1cblxuXHRcdFx0Ly9EZWJ1Zy5UZXh0KCAnICAgIENvbHVtbjogJysgZmllbGQgKycgV2lkdGg6ICcrIHdpZHRoICsnIENvbnRlbnQ6IFxcJycrIGxvbmdlc3RfY2VsbF9jb250ZW50ICsnXFwnIExvbmdlc3QgQ29sdW1uIFdpZHRoOiAnKyBsb25nZXN0X2ZpZWxkX3dpZHRoICsnIEhlYWRlciBpcyBMb25nZXN0OiAnKyBoZWFkZXJfaXNfbG9uZ2VzdCwgJ1RUR3JpZC5qcycsICdUVEdyaWQnLCAnc2V0R3JpZENvbHVtbnNXaWR0aCcsIDEwICk7XG5cblx0XHRcdGNvbHVtbl93aWR0aHNbZmllbGRdID0gd2lkdGg7XG5cdFx0XHR0aGlzLmdyaWRfdG90YWxfd2lkdGggKz0gd2lkdGg7XG5cdFx0fVxuXG5cdFx0Ly9JZiB0aGUgbG9uZ2VzdCBjb2x1bW4gd2lkdGggY2FuIGJlIHVzZWQgZm9yIGFsbCBjb2x1bW5zLCBzaXplIHRoZW0gYWxsIGVxdWFsbHkgc28gdGhleSBkb24ndCBjaGFuZ2Ugc2l6ZXMgYmV0d2VlbiBwYWdlcy5cblx0XHRpZiAoICggbG9uZ2VzdF9maWVsZF93aWR0aCAqIGNvbHVtbl9tb2RlbC5sZW5ndGggKSA8PSBvcHRpb25zLm1pbl9ncmlkX3dpZHRoICkge1xuXHRcdFx0dmFyIGVxdWFsX2NvbHVtbl93aWR0aCA9IE1hdGguZmxvb3IoICggb3B0aW9ucy5taW5fZ3JpZF93aWR0aCAtIGNiX2NvbHVtbl93aWR0aCApIC8gKCBjb2x1bW5fbW9kZWwubGVuZ3RoIC0gY2JfY29sdW1uX2NvdW50X2FkanVzdG1lbnQgKSApO1xuXHRcdFx0dmFyIGVxdWFsX2NvbHVtbl93aWR0aF9yZW1haW5kZXIgPSAoICggb3B0aW9ucy5taW5fZ3JpZF93aWR0aCAtIGNiX2NvbHVtbl93aWR0aCApICUgKCBjb2x1bW5fbW9kZWwubGVuZ3RoIC0gY2JfY29sdW1uX2NvdW50X2FkanVzdG1lbnQgKSApOyAvL0VsaW1pbmF0ZSBwYXJ0aWFsIHBpeGVsIGFkanVzdG1lbnRzLlxuXHRcdFx0RGVidWcuVGV4dCggJyBHcmlkIGNvbHVtbnMgQ0FOIGZpdCB3aXRoIGVxdWFsIHNpemVzLi4uIEdyaWQgV2lkdGg6ICcgKyBvcHRpb25zLm1pbl9ncmlkX3dpZHRoICsgJyBPcHRpbWFsIEdyaWQgV2lkdGg6ICcgKyB0aGlzLmdyaWRfdG90YWxfd2lkdGggKyAnIEVxdWFsIFNpemUgV2lkdGg6ICcgKyBlcXVhbF9jb2x1bW5fd2lkdGggKyAnIFJlbWFpbmRlcjogJyArIGVxdWFsX2NvbHVtbl93aWR0aF9yZW1haW5kZXIsICdUVEdyaWQuanMnLCAnVFRHcmlkJywgJ3NldEdyaWRDb2x1bW5zV2lkdGgnLCAxMCApO1xuXG5cdFx0XHR2YXIgYWRqdXN0ZWRfZ3JpZF93aWR0aCA9IDA7XG5cblx0XHRcdHZhciB4ID0gMDtcblx0XHRcdGZvciAoIHZhciB0bXBfY29sdW1uX25hbWUgaW4gY29sdW1uX3dpZHRocyApIHtcblx0XHRcdFx0aWYgKCB0bXBfY29sdW1uX25hbWUgPT0gJ2NiJyApIHtcblx0XHRcdFx0XHR0aGlzLmdyaWQuc2V0Q29sV2lkdGgoICdjYicsIGNiX2NvbHVtbl93aWR0aCApO1xuXHRcdFx0XHRcdGFkanVzdGVkX2dyaWRfd2lkdGggKz0gY2JfY29sdW1uX3dpZHRoO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHZhciB0bXBfY29sdW1uX3dpZHRoID0gZXF1YWxfY29sdW1uX3dpZHRoO1xuXG5cdFx0XHRcdFx0aWYgKCB4ID09IDEgKSB7XG5cdFx0XHRcdFx0XHR0bXBfY29sdW1uX3dpZHRoICs9IGVxdWFsX2NvbHVtbl93aWR0aF9yZW1haW5kZXI7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly9EZWJ1Zy5UZXh0KCAnICAgIEFkanVzdGVkIENvbHVtbjogJysgdG1wX2NvbHVtbl9uYW1lICsnIFdpZHRoOiBPbGQ6ICcrIGNvbHVtbl93aWR0aHNbdG1wX2NvbHVtbl9uYW1lXSArJyBOZXc6ICcrIHRtcF9jb2x1bW5fd2lkdGgsICdUVEdyaWQuanMnLCAnVFRHcmlkJywgJ3NldEdyaWRDb2x1bW5zV2lkdGgnLCAxMCApO1xuXHRcdFx0XHRcdGlmICggdGhpcy5ncmlkLmdldENvbFByb3AoIHRtcF9jb2x1bW5fbmFtZSApLndpZHRoICE9IHRtcF9jb2x1bW5fd2lkdGggKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmdyaWQuc2V0Q29sV2lkdGgoIHRtcF9jb2x1bW5fbmFtZSwgdG1wX2NvbHVtbl93aWR0aCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRhZGp1c3RlZF9ncmlkX3dpZHRoICs9IHRtcF9jb2x1bW5fd2lkdGg7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR0aGlzLmdyaWQuc2V0Q29sUHJvcCggdG1wX2NvbHVtbl9uYW1lLCAnZml4ZWQnLCB0cnVlICk7XG5cblx0XHRcdFx0eCsrO1xuXHRcdFx0fVxuXHRcdFx0RGVidWcuVGV4dCggJyBBZGp1c3RlZCBHcmlkIFdpZHRoOiAnICsgYWRqdXN0ZWRfZ3JpZF93aWR0aCArICcgQWRqdXN0ZWQgQ29sdW1uIFJlbWFpbmRlcjogJyArIGVxdWFsX2NvbHVtbl93aWR0aF9yZW1haW5kZXIsICdUVEdyaWQuanMnLCAnVFRHcmlkJywgJ3NldEdyaWRDb2x1bW5zV2lkdGgnLCAxMCApO1xuXG5cdFx0XHR0aGlzLmdyaWRfdG90YWxfd2lkdGggPSBvcHRpb25zLm1pbl9ncmlkX3dpZHRoO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHREZWJ1Zy5UZXh0KCAnIE9wdGltYWwgR3JpZCBXaWR0aDogJyArIHRoaXMuZ3JpZF90b3RhbF93aWR0aCArICcgRXF1YWwgU2l6ZSBXaWR0aDogJyArICggbG9uZ2VzdF9maWVsZF93aWR0aCAqIGNvbHVtbl9tb2RlbC5sZW5ndGggKSwgJ1RUR3JpZC5qcycsICdUVEdyaWQnLCAnc2V0R3JpZENvbHVtbnNXaWR0aCcsIDEwICk7XG5cblx0XHRcdHZhciBib2R5X3dpZHRoX2RpZmZlcmVuY2UgPSAwO1xuXHRcdFx0dmFyIGNvbHVtbl93aWR0aF9hZGp1c3RtZW50ID0gMDtcblx0XHRcdHZhciBjb2x1bW5zX3RvX2FkanVzdF93aWR0aCA9IDA7XG5cdFx0XHR2YXIgY29sdW1uX3dpZHRoX2FkanVzdG1lbnRfcmVtYWluZGVyID0gMDtcblxuXHRcdFx0Ly9JZiB0aGUgb3B0aW1hbCBjb2x1bW4gd2lkdGhzIGFyZSB3aWRlciB0aGFuIHRoZSBtYXggZ3JpZCB3aWR0aCwgc2hyaW5rIHRoZW0gdG8gZml0LlxuXHRcdFx0aWYgKCAoIG9wdGlvbnMubWF4X2dyaWRfd2lkdGggPiAwICYmIHRoaXMuZ3JpZF90b3RhbF93aWR0aCA+IG9wdGlvbnMubWF4X2dyaWRfd2lkdGggKSB8fCAoIG9wdGlvbnMubWluX2dyaWRfd2lkdGggPiAwICYmIHRoaXMuZ3JpZF90b3RhbF93aWR0aCA8IG9wdGlvbnMubWluX2dyaWRfd2lkdGggKSApIHtcblx0XHRcdFx0Ly9XaGVuIGNvbHVtbnMgYXJlIHRvbyBzbWFsbCB0byBmaXQgb24gdGhlIHNjcmVlbiBhbmQgbmVlZCB0byBiZSBzdHJldGNoZWQsIGlnbm9yZSB0aGUgb3ZlcnJpZGRlbiBjb2x1bW4uXG5cdFx0XHRcdGlmICggKCBvcHRpb25zLm1heF9ncmlkX3dpZHRoID4gMCAmJiB0aGlzLmdyaWRfdG90YWxfd2lkdGggPiBvcHRpb25zLm1heF9ncmlkX3dpZHRoICkgKSB7XG5cdFx0XHRcdFx0Ym9keV93aWR0aF9kaWZmZXJlbmNlID0gdGhpcy5ncmlkX3RvdGFsX3dpZHRoIC0gb3B0aW9ucy5tYXhfZ3JpZF93aWR0aDsgLy9TaG91bGQgYmUgYSBuZWdhdGl2ZSBkaWZmZXJlbmNlIHRvIHNocmluayBjb2x1bW5zIHRvIGZpdCBtYXggd2lkdGguXG5cdFx0XHRcdFx0dGhpcy5ncmlkX3RvdGFsX3dpZHRoID0gb3B0aW9ucy5tYXhfZ3JpZF93aWR0aDtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRib2R5X3dpZHRoX2RpZmZlcmVuY2UgPSBvcHRpb25zLm1pbl9ncmlkX3dpZHRoIC0gdGhpcy5ncmlkX3RvdGFsX3dpZHRoOyAvL1Nob3VsZCBiZSBhIHBvc2l0aXZlIGRpZmZlcmVuY2UgdG8gZ3JvdyBjb2x1bW5zIHRvIGZpdCBtaW4gd2lkdGguXG5cdFx0XHRcdFx0dGhpcy5ncmlkX3RvdGFsX3dpZHRoID0gb3B0aW9ucy5taW5fZ3JpZF93aWR0aDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggYm9keV93aWR0aF9kaWZmZXJlbmNlICE9IDAgKSB7XG5cdFx0XHRcdFx0aWYgKCBvcHRpb25zLmNvbHVtbl93aWR0aF9vdmVycmlkZSApIHtcblx0XHRcdFx0XHRcdGNvbHVtbnNfdG9fYWRqdXN0X3dpZHRoID0gKCBjb2x1bW5fbW9kZWwubGVuZ3RoIC0gb3B0aW9ucy5jb2x1bW5fd2lkdGhfb3ZlcnJpZGUubGVuZ3RoKCkgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Y29sdW1uc190b19hZGp1c3Rfd2lkdGggPSAoIGNvbHVtbl9tb2RlbC5sZW5ndGggLSBjYl9jb2x1bW5fY291bnRfYWRqdXN0bWVudCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjb2x1bW5fd2lkdGhfYWRqdXN0bWVudCA9IE1hdGguZmxvb3IoIGJvZHlfd2lkdGhfZGlmZmVyZW5jZSAvIGNvbHVtbnNfdG9fYWRqdXN0X3dpZHRoICk7XG5cdFx0XHRcdFx0Y29sdW1uX3dpZHRoX2FkanVzdG1lbnRfcmVtYWluZGVyID0gKCBib2R5X3dpZHRoX2RpZmZlcmVuY2UgJSBjb2x1bW5zX3RvX2FkanVzdF93aWR0aCApOyAvL0VsaW1pbmF0ZSBwYXJ0aWFsIHBpeGVsIGFkanVzdG1lbnRzLlxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdHZhciBhZGp1c3RlZF9ncmlkX3dpZHRoID0gMDtcblxuXHRcdFx0dmFyIHggPSAwO1xuXHRcdFx0Zm9yICggdmFyIHRtcF9jb2x1bW5fbmFtZSBpbiBjb2x1bW5fd2lkdGhzICkge1xuXHRcdFx0XHRpZiAoIHRtcF9jb2x1bW5fbmFtZSA9PSAnY2InICkge1xuXHRcdFx0XHRcdHRoaXMuZ3JpZC5zZXRDb2xXaWR0aCggJ2NiJywgY2JfY29sdW1uX3dpZHRoICk7XG5cdFx0XHRcdFx0YWRqdXN0ZWRfZ3JpZF93aWR0aCArPSBjYl9jb2x1bW5fd2lkdGg7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dmFyIHRtcF9jb2x1bW5fd2lkdGg7XG5cdFx0XHRcdFx0aWYgKCBvcHRpb25zLmNvbHVtbl93aWR0aF9vdmVycmlkZSAmJiBvcHRpb25zLmNvbHVtbl93aWR0aF9vdmVycmlkZVtuXSApIHtcblx0XHRcdFx0XHRcdHRtcF9jb2x1bW5fd2lkdGggPSBjb2x1bW5fd2lkdGhzW3RtcF9jb2x1bW5fbmFtZV07XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRtcF9jb2x1bW5fd2lkdGggPSBjb2x1bW5fd2lkdGhzW3RtcF9jb2x1bW5fbmFtZV0gKyBjb2x1bW5fd2lkdGhfYWRqdXN0bWVudDtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRpZiAoIHggPT0gMSApIHsgLy9GaXJzdCBjb2x1bW4gYWZ0ZXIgdGhlIENCLlxuXHRcdFx0XHRcdFx0dG1wX2NvbHVtbl93aWR0aCArPSBjb2x1bW5fd2lkdGhfYWRqdXN0bWVudF9yZW1haW5kZXI7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0RGVidWcuVGV4dCggJyAgICBBZGp1c3RlZCBDb2x1bW46ICcgKyB0bXBfY29sdW1uX25hbWUgKyAnIFdpZHRoOiBPbGQ6ICcgKyBjb2x1bW5fd2lkdGhzW3RtcF9jb2x1bW5fbmFtZV0gKyAnIE5ldzogJyArIHRtcF9jb2x1bW5fd2lkdGggKyAnIEFkanVzdG1lbnQ6ICcgKyBjb2x1bW5fd2lkdGhfYWRqdXN0bWVudCArICcgQm9keSBEaWZmZXJlbmNlOiAnICsgYm9keV93aWR0aF9kaWZmZXJlbmNlICsgJyBDb2x1bW5zIEFkanVzdGVkOiAnICsgY29sdW1uc190b19hZGp1c3Rfd2lkdGgsICdUVEdyaWQuanMnLCAnVFRHcmlkJywgJ3NldEdyaWRDb2x1bW5zV2lkdGgnLCAxMCApO1xuXHRcdFx0XHRcdGlmICggdGhpcy5ncmlkLmdldENvbFByb3AoIHRtcF9jb2x1bW5fbmFtZSApLndpZHRoICE9IHRtcF9jb2x1bW5fd2lkdGggKSB7XG5cdFx0XHRcdFx0XHR0aGlzLmdyaWQuc2V0Q29sV2lkdGgoIHRtcF9jb2x1bW5fbmFtZSwgdG1wX2NvbHVtbl93aWR0aCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRhZGp1c3RlZF9ncmlkX3dpZHRoICs9IHRtcF9jb2x1bW5fd2lkdGg7XG5cdFx0XHRcdH1cblx0XHRcdFx0dGhpcy5ncmlkLnNldENvbFByb3AoIHRtcF9jb2x1bW5fbmFtZSwgJ2ZpeGVkJywgdHJ1ZSApO1xuXG5cdFx0XHRcdHgrKztcblx0XHRcdH1cblx0XHRcdC8vRGVidWcuVGV4dCggJyBBZGp1c3RlZCBHcmlkIFdpZHRoOiAnKyBhZGp1c3RlZF9ncmlkX3dpZHRoICsnIEFkanVzdGVkIENvbHVtbiBSZW1haW5kZXI6ICcrIGNvbHVtbl93aWR0aF9hZGp1c3RtZW50X3JlbWFpbmRlciwgJ1RUR3JpZC5qcycsICdUVEdyaWQnLCAnc2V0R3JpZENvbHVtbnNXaWR0aCcsIDEwICk7XG5cdFx0fVxuXG5cdFx0Ly90aGlzLnNldEdyaWRXaWR0aCggdGhpcy5ncmlkX3RvdGFsX3dpZHRoLCB0aGlzLmdyaWRfdG90YWxfd2lkdGggKTsgLy9DYXVzZXMgY29sdW1ucyB3aXRoIHRvIGZsdWN1YXRlLCBzcGVjaWZpY2FsbHkgaW4gc2NoZWR1bGUgZGF5IG1vZGUuXG5cdFx0RGVidWcuVGV4dCggJyBGSU5BTCBHcmlkIHdpZHRoOiAnICsgdGhpcy5ncmlkX3RvdGFsX3dpZHRoICsgJyBCb2R5IFdpZHRoOiAnICsgR2xvYmFsLmJvZHlXaWR0aCgpICsgJyBUb3RhbCBSb3dzOiAnICsgZ3JpZF9kYXRhLmxlbmd0aCwgJ1RUR3JpZC5qcycsICdUVEdyaWQnLCAnc2V0R3JpZENvbHVtbnNXaWR0aCcsIDEwICk7XG5cdFx0cmV0dXJuIHRoaXMuZ3JpZF90b3RhbF93aWR0aDtcblx0fTtcblxuXHQvL3Jlc2l6ZSBldmVudC5cblx0JCggd2luZG93ICkub2ZmKCAncmVzaXplLmdyaWRzJyApLm9uKCAncmVzaXplLmdyaWRzJywgR2xvYmFsLmRlYm91bmNlKCAoIGUgKSA9PiB0aGlzLlRUR3JpZFJlc2l6ZUV2ZW50KCBlICksIDUwMCApICk7XG5cblx0dGhpcy5UVEdyaWRSZXNpemVFdmVudCA9IGZ1bmN0aW9uKCBlICkge1xuXHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0RGVidWcuVGV4dCggJyBXaW5kb3cgcmVzaXplIGV2ZW50IGhpdCBieSBUVEdyaWQuIFRhcmdldDogJyArIGUudGFyZ2V0LCAnVFRHcmlkLmpzJywgJ1RUR3JpZCcsICdzZXRHcmlkQ29sdW1uc1dpZHRoJywgMTAgKTtcblxuXHRcdGlmICggTG9jYWxDYWNoZURhdGEucmVzaXplYWJsZV9ncmlkcy5sZW5ndGggPiAwICkge1xuXG5cdFx0XHQvL3JlbW92ZSB0aGUgbnVsbHNcblx0XHRcdHZhciBncmlkcyA9IExvY2FsQ2FjaGVEYXRhLnJlc2l6ZWFibGVfZ3JpZHMuZmlsdGVyKCBmdW5jdGlvbiggdCApIHtcblx0XHRcdFx0cmV0dXJuIHQgIT0gbnVsbDtcblx0XHRcdH0gKTtcblx0XHRcdExvY2FsQ2FjaGVEYXRhLnJlc2l6ZWFibGVfZ3JpZHMgPSBncmlkcztcblxuXHRcdFx0Zm9yICggdmFyIGkgaW4gTG9jYWxDYWNoZURhdGEucmVzaXplYWJsZV9ncmlkcyApIHtcblx0XHRcdFx0dmFyIHR0Z3JpZCA9IExvY2FsQ2FjaGVEYXRhLnJlc2l6ZWFibGVfZ3JpZHNbaV07XG5cblx0XHRcdFx0aWYgKCAhdHRncmlkIHx8ICggdHlwZW9mIHR0Z3JpZC5nZXRUYWJsZUlERWxlbWVudCA9PT0gJ2Z1bmN0aW9uJyAmJiB0dGdyaWQuZ2V0VGFibGVJREVsZW1lbnQoKS5sZW5ndGggPT09IDAgKSB8fCAhdHRncmlkLmdyaWQgfHwgdHRncmlkLnNldHVwLm9uUmVzaXplR3JpZCA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0RGVidWcuQXJyKCBMb2NhbENhY2hlRGF0YS5yZXNpemVhYmxlX2dyaWRzLCAnIEdyaWQgaWdub3JlZCAnICsgaSwgJ1RUR3JpZC5qcycsICdUVEdyaWQnLCAnc2V0R3JpZENvbHVtbnNXaWR0aCcsIDEwICk7XG5cdFx0XHRcdFx0TG9jYWxDYWNoZURhdGEucmVzaXplYWJsZV9ncmlkc1tpXSA9IG51bGw7XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvL1RyeSB0byBvbmx5IHJlc2l6ZSB2aXNpYmxlIGdyaWRzLiBpZTogU3dpdGNoIGZyb20gQXVkaXQgdGFiIHRvIHByaW1hcnkgdGFiLCB3YWl0IHVudGlsIHJlc2l6ZSBldmVudCBpcyB0cmlnZ2VyZWQsIHRoZW4gc3dpdGNoIGJhY2ssIHRyaWdnZXJpbmcgXCJmbGFzaGluZ1wiIG9mIHNjcm9sbCBiYXJzIGFwcGVhcmluZy9kaXNhcHBlYXJpbmdcblx0XHRcdFx0Ly8gT25seSBoYXBwZW5zIG9uIGVkaXQgdmlld3Mgd2l0aCBkb3VibGUgcm93IGZpZWxkcyAoaWU6IE5vdGUgZmllbGRzKSwgbGlrZSBFZGl0IFB1bmNoIG9yIEVkaXQgU2NoZWR1bGUuXG5cdFx0XHRcdGlmICggdHRncmlkLmdldFRhYmxlSURFbGVtZW50KCkuaXMoICc6dmlzaWJsZScgKSApIHtcblx0XHRcdFx0XHREZWJ1Zy5UZXh0KCAnIFByb2Nlc3Npbmc6ICcgKyB0dGdyaWQudWlfaWQsICdUVEdyaWQuanMnLCAnVFRHcmlkJywgJ3NldEdyaWRDb2x1bW5zV2lkdGgnLCAxMCApO1xuXHRcdFx0XHRcdGlmICggdHRncmlkLnNldHVwLm9uUmVzaXplR3JpZCAmJiB0eXBlb2YgdHRncmlkLnNldHVwLm9uUmVzaXplR3JpZCA9PSAnZnVuY3Rpb24nICkge1xuXHRcdFx0XHRcdFx0RGVidWcuVGV4dCggJyBUVEdyaWQgaW52b2tlZCBzZXR1cCBkZWZpbmVkIG9uUmVzaXplR3JpZCgpIGZvciAnICsgdHRncmlkLnVpX2lkLCAnVFRHcmlkLmpzJywgJ1RUR3JpZCcsICdzZXRHcmlkQ29sdW1uc1dpZHRoJywgMTAgKTtcblx0XHRcdFx0XHRcdHR0Z3JpZC5zZXR1cC5vblJlc2l6ZUdyaWQoKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0aWYgKCB0dGdyaWQuZ3JpZC5sZW5ndGggPT0gMSApIHtcblx0XHRcdFx0XHRcdFx0RGVidWcuVGV4dCggJyBUVEdyaWQgaW52b2tlZCBUVGdyaWQ6OnNldEdyaWRDb2x1bW5zV2lkdGgoKSBmb3IgJyArIHR0Z3JpZC51aV9pZCwgJ1RUR3JpZC5qcycsICdUVEdyaWQnLCAnc2V0R3JpZENvbHVtbnNXaWR0aCcsIDEwICk7XG5cdFx0XHRcdFx0XHRcdHR0Z3JpZC5zZXRHcmlkQ29sdW1uc1dpZHRoKCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdERlYnVnLlRleHQoICcgU2tpcHBpbmcgZ3JpZCB0aGF0IGlzIG5vdCB2aXNpYmxlOiAnICsgdHRncmlkLnVpX2lkLCAnVFRHcmlkLmpzJywgJ1RUR3JpZCcsICdzZXRHcmlkQ29sdW1uc1dpZHRoJywgMTAgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvL1VzdWFsbHkgd2Ugd2lsbCB3YW50IHRvIG1ha2UgZG91YmxlIHN1cmUgdGhhdCB2aXNpYmxlIHNlYXJjaCBncmlkcyByZXNpemUuXG5cdFx0XHQvL0hhdmUgdG8gY2hlY2sgZm9yIGdyaWQgdGhvdWdoIGJlY2F1c2UgZGFzaGJvYXJkIGhhcyBubyBcInNlYXJjaCBncmlkXCJcblx0XHRcdGlmICggTG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlciAmJiBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLmdyaWQgKSB7XG5cdFx0XHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9wcmltYXJ5X2NvbnRyb2xsZXIuc2V0R3JpZENvbHVtbnNXaWR0aCgpOyAvL0JlIHN1cmUgdG8gY2FsbCB0aGUgc2V0R3JpZENvbHVtbnNXaWR0aCgpIGZyb20gY3VycmVudF9vcGVuX3ByaW1hcnlfY29udHJvbGxlciBpbiBjYXNlIGl0cyBvdmVycmlkZGVuLlxuXHRcdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fcHJpbWFyeV9jb250cm9sbGVyLnNldEdyaWRTaXplKCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vQWxzbyByZXNpemUgZ3JpZHMgaW5zaWRlIEVkaXQgVmlld3MuXG5cdFx0XHRpZiAoIExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfb3Blbl9zdWJfY29udHJvbGxlciAmJiBMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fc3ViX2NvbnRyb2xsZXIuZ3JpZCApIHtcblx0XHRcdFx0TG9jYWxDYWNoZURhdGEuY3VycmVudF9vcGVuX3N1Yl9jb250cm9sbGVyLnNldEdyaWRDb2x1bW5zV2lkdGgoKTsgLy9CZSBzdXJlIHRvIGNhbGwgdGhlIHNldEdyaWRDb2x1bW5zV2lkdGgoKSBmcm9tIGN1cnJlbnRfb3Blbl9zdWJfY29udHJvbGxlciBpbiBjYXNlIGl0cyBvdmVycmlkZGVuLlxuXHRcdFx0XHRMb2NhbENhY2hlRGF0YS5jdXJyZW50X29wZW5fc3ViX2NvbnRyb2xsZXIuc2V0R3JpZFNpemUoKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn07Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///2185\n")}}]);