1 line
169 KiB
JavaScript
1 line
169 KiB
JavaScript
"use strict";(self.webpackChunktimetrex=self.webpackChunktimetrex||[]).push([["invoice-invoice-InvoiceViewController"],{4585:(__unused_webpack_module,__webpack_exports__,__webpack_require__)=>{eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"InvoiceViewController\": () => (/* binding */ InvoiceViewController)\n/* harmony export */ });\n/* provided dependency */ var _ = __webpack_require__(9050);\n/* provided dependency */ var $ = __webpack_require__(9755);\nclass InvoiceViewController extends BaseViewController {\n\tconstructor( options = {} ) {\n\t\t_.defaults( options, {\n\t\t\tstatus_array: null,\n\n\t\t\tclient_group_array: null,\n\t\t\tclient_group_api: null,\n\t\t\tclient_api: null,\n\t\t\tclient_contact_api: null,\n\t\t\tproduct_api: null,\n\t\t\ttransaction_api: null,\n\n\t\t\tel: '#invoice_view_container',\n\n\t\t\tsub_client_contact_view_controller: null,\n\t\t\tsub_client_payment_view_controller: null,\n\t\t\tsub_transaction_view_controller: null,\n\n\t\t\ttotal_data_render: null,\n\t\t\ttotal_data_row_render: null,\n\n\t\t\towing_amount: null,\n\n\t\t\ttransaction_paid_data: null,\n\n\t\t\thistory: null,\n\n\t\t\teditor: null\n\t\t} );\n\n\t\tsuper( options );\n\t}\n\n\tinit( options ) {\n\n\t\t//this._super('initialize', options );\n\t\tthis.edit_view_tpl = 'InvoiceEditView.html';\n\t\tthis.permission_id = 'invoice';\n\t\tthis.viewId = 'Invoice';\n\t\tthis.script_name = 'InvoiceView';\n\t\tthis.table_name_key = 'invoice';\n\t\tthis.context_menu_name = $.i18n._( 'Invoices' );\n\t\tthis.navigation_label = $.i18n._( 'Invoice' );\n\t\tthis.api = TTAPI.APIInvoice;\n\t\tthis.client_group_api = TTAPI.APIClientGroup;\n\t\tthis.client_api = TTAPI.APIClient;\n\t\tthis.product_api = TTAPI.APIProduct;\n\t\tthis.transaction_api = TTAPI.APITransaction;\n\t\tthis.client_contact_api = TTAPI.APIClientContact;\n\n\t\tthis.render();\n\n\t\tthis.buildContextMenu();\n\n\t\tif ( !this.sub_view_mode ) {\n\t\t\tthis.initData();\n\t\t}\n\t}\n\n\tgetCustomContextMenuModel() {\n\t\tvar context_menu_model = {\n\t\t\texclude: ['mass_edit'],\n\t\t\tinclude: [\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'View: Invoice' ),\n\t\t\t\t\tid: 'view',\n\t\t\t\t\taction_group: 'view',\n\t\t\t\t\tvue_icon: 'tticon tticon-visibility_black_24dp',\n\t\t\t\t\tsort_order: 1010\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'View: Packing Slip' ),\n\t\t\t\t\tid: 'packing_slip',\n\t\t\t\t\taction_group: 'view',\n\t\t\t\t\tvue_icon: 'tticon tticon-visibility_black_24dp',\n\t\t\t\t\tsort_order: 1012, //After View icon.\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tlabel: $.i18n._( 'Payment' ),\n\t\t\t\t\tid: 'payment',\n\t\t\t\t\tvue_icon: 'tticon tticon-attach_money_black_24dp',\n\t\t\t\t\tmenu_align: 'right'\n\t\t\t\t}\n\t\t\t]\n\t\t};\n\n\t\tif ( !this.sub_view_mode ) {\n\t\t\tcontext_menu_model['include'].push( {\n\t\t\t\tlabel: $.i18n._( 'Jump To' ),\n\t\t\t\tid: 'jump_to_header',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'jump_to',\n\t\t\t\taction_group_header: true,\n\t\t\t\tpermission_result: false, // to hide it in legacy context menu and avoid errors in legacy parsers.\n\t\t\t\tsort_order: 9050,\n\t\t\t} );\n\n\t\t\tcontext_menu_model['include'].push( {\n\t\t\t\tlabel: $.i18n._( 'Edit Client' ),\n\t\t\t\tid: 'edit_client',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'jump_to',\n\t\t\t\tgroup: 'navigation',\n\t\t\t\tsort_order: 9050,\n\t\t\t\t} );\n\n\t\t\tcontext_menu_model['include'].push( {\n\t\t\t\tlabel: $.i18n._( 'Clients' ),\n\t\t\t\tid: 'client',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'jump_to',\n\t\t\t\tgroup: 'navigation',\n\t\t\t\ticon: 'client_groups-35x35.png',\n\t\t\t\tsort_order: 9050,\n\t\t\t} );\n\n\t\t\tcontext_menu_model['include'].push( {\n\t\t\t\tlabel: $.i18n._( 'Client Contacts' ),\n\t\t\t\tid: 'client_contact',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'jump_to',\n\t\t\t\tgroup: 'navigation',\n\t\t\t\tsort_order: 9050,\n\t\t\t\t} );\n\n\t\t\tcontext_menu_model['include'].push( {\n\t\t\t\tlabel: $.i18n._( 'Transactions' ),\n\t\t\t\tid: 'transaction',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'jump_to',\n\t\t\t\tgroup: 'navigation',\n\t\t\t\tsort_order: 9050,\n\t\t\t\t} );\n\n\t\t\tcontext_menu_model['include'].push( {\n\t\t\t\tlabel: $.i18n._( 'Payment Methods' ),\n\t\t\t\tid: 'payment_method',\n\t\t\t\tmenu_align: 'right',\n\t\t\t\taction_group: 'jump_to',\n\t\t\t\tgroup: 'navigation',\n\t\t\t\tsort_order: 9050,\n\t\t\t\t} );\n\t\t}\n\n\t\treturn context_menu_model;\n\t}\n\n\tsetCustomDefaultMenuIcon( id, context_btn, grid_selected_length ) {\n\t\tswitch ( id ) {\n\t\t\tcase 'packing_slip':\n\t\t\t\tthis.setDefaultMenuPackingSlipIcon( context_btn, grid_selected_length );\n\t\t\t\tbreak;\n\t\t\tcase 'payment':\n\t\t\t\tthis.setDefaultMenuPaymentIcon( context_btn, grid_selected_length );\n\t\t\t\tbreak;\n\t\t\tcase 'edit_client':\n\t\t\t\tthis.setDefaultMenuEditClientIcon( context_btn, grid_selected_length );\n\t\t\t\tbreak;\n\t\t\tcase 'client':\n\t\t\t\tthis.setDefaultMenuClientIcon( context_btn, grid_selected_length );\n\t\t\t\tbreak;\n\t\t\tcase 'client_contact':\n\t\t\t\tthis.setDefaultMenuClientContactIcon( context_btn, grid_selected_length );\n\t\t\t\tbreak;\n\t\t\tcase 'transaction':\n\t\t\t\tthis.setDefaultMenuTransactionIcon( context_btn, grid_selected_length );\n\t\t\t\tbreak;\n\t\t\tcase 'payment_method':\n\t\t\t\tthis.setDefaultMenuPaymentMethodIcon( context_btn, grid_selected_length );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tsetCustomEditMenuIcon( id, context_btn ) {\n\t\tswitch ( id ) {\n\t\t\tcase 'packing_slip':\n\t\t\t\tthis.setEditMenuPackingSlipIcon( context_btn );\n\t\t\t\tbreak;\n\t\t\tcase 'payment':\n\t\t\t\tthis.setEditMenuPaymentIcon( context_btn );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tsetEditMenuPackingSlipIcon( context_btn, pId ) {\n\n\t\tif ( !this.current_edit_record || !this.current_edit_record.id ) {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t}\n\n\tsetEditMenuPaymentIcon( context_btn, pId ) {\n\t\tif ( !this.current_edit_record || !this.current_edit_record.id ) {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t}\n\n\tsetDefaultMenuViewIcon( context_btn, grid_selected_length, pId ) {\n\t\tif ( !this.viewPermissionValidate( pId ) || this.edit_only_mode ) {\n\t\t\tContextMenuManager.hideMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false )\n\t\t}\n\n\t\tif ( grid_selected_length > 0 && this.viewOwnerOrChildPermissionValidate() ) {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t\t} else {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t}\n\n\tsetDefaultMenuPackingSlipIcon( context_btn, grid_selected_length, pId ) {\n\n\t\tif ( grid_selected_length > 0 ) {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t\t} else {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t}\n\n\tsetDefaultMenuPaymentIcon( context_btn, grid_selected_length, pId ) {\n\n\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\tContextMenuManager.hideMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t}\n\n\tsetDefaultMenuEditClientIcon( context_btn, grid_selected_length, pId ) {\n\t\tif ( grid_selected_length > 0 ) {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t\t} else {\n\t\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, false );\n\t\t}\n\t}\n\n\tsetDefaultMenuClientIcon( context_btn, grid_selected_length, pId ) {\n\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t}\n\n\tsetDefaultMenuClientContactIcon( context_btn, grid_selected_length, pId ) {\n\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t}\n\n\tsetDefaultMenuTransactionIcon( context_btn, grid_selected_length, pId ) {\n\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t}\n\n\tsetDefaultMenuPaymentMethodIcon( context_btn, grid_selected_length, pId ) {\n\t\tContextMenuManager.disableMenuItem( this.determineContextMenuMountAttributes().id, context_btn.id, true );\n\t}\n\n\tgetFilterColumnsFromDisplayColumns() {\n\t\tvar column_filter = {};\n\t\tcolumn_filter.is_owner = true;\n\t\tcolumn_filter.id = true;\n\t\tcolumn_filter.is_child = true;\n\t\tcolumn_filter.in_use = true;\n\t\tcolumn_filter.first_name = true;\n\t\tcolumn_filter.last_name = true;\n\t\tcolumn_filter.client_id = true;\n\n\t\t// Error: Unable to get property 'getGridParam' of undefined or null reference\n\t\tvar display_columns = [];\n\t\tif ( this.grid ) {\n\t\t\tdisplay_columns = this.grid.getGridParam( 'colModel' );\n\t\t}\n\n\t\tif ( display_columns ) {\n\t\t\tvar len = display_columns.length;\n\n\t\t\tfor ( var i = 0; i < len; i++ ) {\n\t\t\t\tvar column_info = display_columns[i];\n\t\t\t\tcolumn_filter[column_info.name] = true;\n\t\t\t}\n\t\t}\n\n\t\treturn column_filter;\n\t}\n\n\tonCustomContextClick( id ) {\n\t\tswitch ( id ) {\n\t\t\tcase 'edit_client':\n\t\t\tcase 'client':\n\t\t\tcase 'client_contact':\n\t\t\tcase 'transaction':\n\t\t\tcase 'payment_method':\n\t\t\tcase 'payment':\n\t\t\tcase 'view':\n\t\t\tcase 'packing_slip':\n\t\t\t\tthis.onNavigationClick( id );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tonViewClick() {\n\t\treturn this.onNavigationClick( 'view' );\n\t}\n\n\tonNavigationClick( iconName ) {\n\t\tvar $this = this;\n\t\tvar grid_selected_id_array;\n\t\tvar filter = { filter_data: {} };\n\t\tvar ids = [];\n\t\tvar client_ids = [];\n\t\tvar invoice_id;\n\t\tvar currency_id;\n\t\tif ( $this.edit_view ) {\n\t\t\tif ( $this.current_edit_record.client_id ) {\n\t\t\t\tclient_ids.push( $this.current_edit_record.client_id );\n\t\t\t}\n\t\t\tcurrency_id = $this.current_edit_record.currency_id;\n\t\t\tif ( $this.current_edit_record.id ) {\n\t\t\t\tinvoice_id = $this.current_edit_record.id;\n\t\t\t\tids.push( $this.current_edit_record.id );\n\t\t\t}\n\t\t} else {\n\t\t\tgrid_selected_id_array = this.getGridSelectIdArray();\n\t\t\t$.each( grid_selected_id_array, function( index, value ) {\n\t\t\t\tvar grid_selected_row = $this.getRecordFromGridById( value );\n\t\t\t\tids.push( grid_selected_row.id );\n\t\t\t\tclient_ids.push( grid_selected_row.client_id );\n\t\t\t} );\n\t\t}\n\t\tfilter.filter_data.client_id = client_ids;\n\t\tvar args = { filter_data: { id: ids } };\n\t\tvar post_data;\n\t\tswitch ( iconName ) {\n\t\t\tcase 'edit_client':\n\t\t\t\tif ( client_ids.length > 0 ) {\n\t\t\t\t\tIndexViewController.openEditView( this, 'Client', client_ids[0] );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'payment':\n\t\t\t\tif ( invoice_id ) {\n\t\t\t\t\tIndexViewController.openEditView( this, 'InvoiceTransaction', {\n\t\t\t\t\t\ttype_id: 20,\n\t\t\t\t\t\tinvoice_id: invoice_id,\n\t\t\t\t\t\tclient_id: client_ids[0],\n\t\t\t\t\t\tcurrency_id: currency_id,\n\t\t\t\t\t\tis_add: true,\n\t\t\t\t\t\towing_amount: this.owing_amount\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'client':\n\t\t\t\tfilter.filter_data.id = filter.filter_data.client_id;\n\t\t\t\tdelete filter.filter_data.client_id;\n\t\t\t\tGlobal.addViewTab( $this.viewId, $.i18n._( 'Invoices' ), window.location.href );\n\t\t\t\tIndexViewController.goToView( 'Client', filter );\n\t\t\t\tbreak;\n\t\t\tcase 'client_contact':\n\t\t\t\tGlobal.addViewTab( $this.viewId, $.i18n._( 'Invoices' ), window.location.href );\n\t\t\t\tIndexViewController.goToView( 'ClientContact', filter );\n\t\t\t\tbreak;\n\t\t\tcase 'transaction':\n\t\t\t\tGlobal.addViewTab( $this.viewId, $.i18n._( 'Invoices' ), window.location.href );\n\t\t\t\tIndexViewController.goToView( 'InvoiceTransaction', filter );\n\t\t\t\tbreak;\n\t\t\tcase 'payment_method':\n\t\t\t\tGlobal.addViewTab( $this.viewId, $.i18n._( 'Invoices' ), window.location.href );\n\t\t\t\tIndexViewController.goToView( 'ClientPayment', filter );\n\t\t\t\tbreak;\n\t\t\tcase 'view':\n\t\t\t\tpost_data = { 0: args, 1: false, 2: 'pdf' };\n\t\t\t\tthis.doFormIFrameCall( post_data );\n\t\t\t\tbreak;\n\t\t\tcase 'packing_slip':\n\t\t\t\tpost_data = { 0: args, 1: false, 2: 'pdf_packing_slip' };\n\t\t\t\tthis.doFormIFrameCall( post_data );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tdoFormIFrameCall( postData ) {\n\t\tGlobal.APIFileDownload( this.api.className, 'get' + this.api.key_name, postData );\n\t}\n\n\tinitOptions() {\n\t\tvar $this = this;\n\n\t\tthis.initDropDownOption( 'status' );\n\t\tthis.client_group_api.getClientGroup( '', false, false, {\n\t\t\tonResult: function( res ) {\n\t\t\t\tres = res.getResult();\n\t\t\t\tres = Global.buildTreeRecord( res );\n\t\t\t\tif ( !$this.edit_only_mode && !$this.sub_view_mode ) {\n\t\t\t\t\t$this.basic_search_field_ui_dic['client_group_id'].setSourceData( res );\n\t\t\t\t\t$this.adv_search_field_ui_dic['client_group_id'].setSourceData( res );\n\t\t\t\t}\n\n\t\t\t\t$this.client_group_array = res;\n\n\t\t\t}\n\t\t} );\n\t}\n\n\tbuildEditViewUI() {\n\n\t\tsuper.buildEditViewUI();\n\n\t\tvar $this = this;\n\n\t\tthis.edit_view.children().eq( 0 ).css( 'min-width', 1050 );\n\n\t\tvar tab_model = {\n\t\t\t'tab_invoice': {\n\t\t\t\t'label': $.i18n._( 'Invoice' ),\n\t\t\t\t'html_template': this.getInvoiceTabHtml(),\n\t\t\t\t'is_multi_column': true\n\t\t\t},\n\t\t\t'tab_client_contacts': {\n\t\t\t\t'label': $.i18n._( 'Client Contacts' ),\n\t\t\t\t'init_callback': 'initSubClientContactView',\n\t\t\t\t'display_on_mass_edit': false\n\t\t\t},\n\t\t\t'tab_payment_methods': {\n\t\t\t\t'label': $.i18n._( 'Payment Methods' ),\n\t\t\t\t'init_callback': 'initSubClientPaymentView',\n\t\t\t\t'display_on_mass_edit': false\n\t\t\t},\n\t\t\t'tab_transactions': {\n\t\t\t\t'label': $.i18n._( 'Transactions' ),\n\t\t\t\t'init_callback': 'initSubTransactionView',\n\t\t\t\t'display_on_mass_edit': false\n\t\t\t},\n\t\t\t'tab_audit': true,\n\t\t};\n\t\tthis.setTabModel( tab_model );\n\n\t\tthis.navigation.AComboBox( {\n\t\t\tapi_class: TTAPI.APIInvoice,\n\t\t\tid: this.script_name + '_navigation',\n\t\t\tallow_multiple_selection: false,\n\t\t\tlayout_name: 'global_invoice',\n\t\t\tnavigation_mode: true,\n\t\t\tshow_search_inputs: true\n\t\t} );\n\n\t\tthis.setNavigation();\n\n\t\t//Tab 0 start\n\n\t\tvar tab_invoice = this.edit_view_tab.find( '#tab_invoice' );\n\n\t\tvar tab_invoice_column1 = tab_invoice.find( '.first-column' );\n\t\tvar tab_invoice_column2 = tab_invoice.find( '.second-column' );\n\t\tvar tab_invoice_column3 = tab_invoice.find( '.third-column' );\n\n\t\tthis.edit_view_tabs[0] = [];\n\n\t\tthis.edit_view_tabs[0].push( tab_invoice_column1 );\n\t\tthis.edit_view_tabs[0].push( tab_invoice_column2 );\n\t\tthis.edit_view_tabs[0].push( tab_invoice_column3 );\n\n\t\tvar form_item_input;\n\t\tvar widgetContainer;\n\t\tvar label;\n\n\t\t// Client\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );\n\n\t\tform_item_input.AComboBox( {\n\t\t\tapi_class: TTAPI.APIClient,\n\t\t\tallow_multiple_selection: false,\n\t\t\tlayout_name: 'global_client',\n\t\t\tshow_search_inputs: true,\n\t\t\tset_empty: true,\n\t\t\tfield: 'client_id'\n\t\t} );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Client' ), form_item_input, tab_invoice_column1, '', null, true );\n\n\t\t// Client\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT );\n\t\tform_item_input.TText( { field: 'client' } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Client' ), form_item_input, tab_invoice_column1, '', null, true );\n\n\t\t// Status\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.COMBO_BOX );\n\t\tform_item_input.TComboBox( { field: 'status_id' } );\n\t\tform_item_input.setSourceData( $this.status_array );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Status' ), form_item_input, tab_invoice_column1 );\n\n\t\t// Billing Contact\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );\n\n\t\tform_item_input.AComboBox( {\n\t\t\tapi_class: TTAPI.APIClientContact,\n\t\t\tallow_multiple_selection: false,\n\t\t\tlayout_name: 'global_client_contact',\n\t\t\tshow_search_inputs: true,\n\t\t\tset_empty: true,\n\t\t\tfield: 'billing_contact_id'\n\t\t} );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Billing Contact' ), form_item_input, tab_invoice_column1 );\n\n\t\t// Shipping Contact\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );\n\n\t\tform_item_input.AComboBox( {\n\t\t\tapi_class: TTAPI.APIClientContact,\n\t\t\tallow_multiple_selection: false,\n\t\t\tlayout_name: 'global_client_contact',\n\t\t\tshow_search_inputs: true,\n\t\t\tset_empty: true,\n\t\t\tfield: 'shipping_contact_id'\n\t\t} );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Shipping Contact' ), form_item_input, tab_invoice_column1 );\n\n\t\t// Other Contact\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );\n\n\t\tform_item_input.AComboBox( {\n\t\t\tapi_class: TTAPI.APIClientContact,\n\t\t\tallow_multiple_selection: false,\n\t\t\tlayout_name: 'global_client_contact',\n\t\t\tshow_search_inputs: true,\n\t\t\tset_empty: true,\n\t\t\tfield: 'other_contact_id'\n\t\t} );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Other Contact' ), form_item_input, tab_invoice_column1 );\n\n\t\t// Currency\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );\n\n\t\tform_item_input.AComboBox( {\n\t\t\tapi_class: TTAPI.APICurrency,\n\t\t\tallow_multiple_selection: false,\n\t\t\tlayout_name: 'global_currency',\n\t\t\tshow_search_inputs: true,\n\t\t\tfield: 'currency_id'\n\t\t} );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Currency' ), form_item_input, tab_invoice_column1 );\n\n\t\t// PO Number\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\n\t\tform_item_input.TTextInput( { field: 'po_number', width: 100 } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'PO Number' ), form_item_input, tab_invoice_column1 );\n\n\t\t// Tags\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TAG_INPUT );\n\n\t\tform_item_input.TTagInput( { field: 'tag', object_type_id: 910 } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Tags' ), form_item_input, tab_invoice_column1, '', null, null, true );\n\n\t\t// Invoice #\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT );\n\t\tform_item_input.TText( { field: 'invoice_number' } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Invoice #' ), form_item_input, tab_invoice_column2, '' );\n\n\t\t// Invoice Date\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.DATE_PICKER );\n\n\t\tform_item_input.TDatePicker( { field: 'invoice_date' } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Invoice Date' ), form_item_input, tab_invoice_column2 );\n\n\t\t// Order Date\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.DATE_PICKER );\n\n\t\tform_item_input.TDatePicker( { field: 'order_date' } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Order Date' ), form_item_input, tab_invoice_column2 );\n\n\t\t// Payment Required\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.DATE_PICKER );\n\n\t\tform_item_input.TDatePicker( { field: 'required_date' } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Payment Required' ), form_item_input, tab_invoice_column2 );\n\n\t\t// Shipped Date\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.DATE_PICKER );\n\n\t\tform_item_input.TDatePicker( { field: 'shipped_date' } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Shipped Date' ), form_item_input, tab_invoice_column2 );\n\n\t\t// Sales Rep\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );\n\n\t\tform_item_input.AComboBox( {\n\t\t\tapi_class: TTAPI.APIUser,\n\t\t\tallow_multiple_selection: false,\n\t\t\tlayout_name: 'global_user',\n\t\t\tshow_search_inputs: true,\n\t\t\tset_empty: true,\n\t\t\tfield: 'sales_contact_id'\n\t\t} );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Sales Rep' ), form_item_input, tab_invoice_column2 );\n\n\t\t// Tracking Number\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\n\t\tform_item_input.TTextInput( { field: 'tracking_number' } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Tracking Number' ), form_item_input, tab_invoice_column2 );\n\n\t\t// Shipping Policy\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.COMBO_BOX );\n\t\tform_item_input.TComboBox( { field: 'combined_shipping_policy_id' } );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Shipping Policy' ), form_item_input, tab_invoice_column2, '' );\n\n\t\t//Inside editor\n\n\t\tvar inside_editor_div = tab_invoice.find( '.inside-editor-div' );\n\n\t\tvar args = {\n\t\t\tproduct: $.i18n._( 'Product' ),\n\t\t\tdescription: $.i18n._( 'Description' ),\n\t\t\tqty: $.i18n._( 'QTY' ),\n\t\t\tprice: $.i18n._( 'Price' ),\n\t\t\tprorate: $.i18n._( 'ProRate' ),\n\t\t\ttotal: $.i18n._( 'Total' )\n\t\t};\n\n\t\tthis.editor = Global.loadWidgetByName( FormItemType.INSIDE_EDITOR );\n\n\t\tthis.editor.InsideEditor( {\n\t\t\taddRow: this.insideEditorAddRow,\n\t\t\tremoveRow: this.insideEditorRemoveRow,\n\t\t\tgetValue: this.insideEditorGetValue,\n\t\t\tsetValue: this.insideEditorSetValue,\n\t\t\tparent_controller: this,\n\t\t\tapi: this.transaction_api,\n\t\t\trender: getRender(),\n\t\t\trender_args: args,\n\t\t\trender_inline_html: true,\n\t\t\trow_render: getRowRender(),\n\n\t\t} );\n\n\t\tfunction getRender() {\n\t\t\treturn `\n\t\t\t<table class=\"inside-editor-render\">\n\t\t\t\t<tr class=\"title\" style=\"font-weight: bold;\">\n\t\t\t\t\t<td style=\"width: 200px\"><%= product %></td>\n\t\t\t\t\t<td style=\"width: 400px\"><%= description %></td>\n\t\t\t\t\t<td style=\"width: 50px\"><%= qty %></td>\n\t\t\t\t\t<td style=\"width: 50px\"><%= price %></td>\n\t\t\t\t\t<td style=\"width: 145px\"><%= prorate %></td>\n\t\t\t\t\t<td style=\"width: 100px\"><%= total %></td>\n\t\t\t\t</tr>\n\t\t\t</table>`;\n\t\t}\n\n\t\tfunction getRowRender() {\n\t\t\treturn `\n\t\t\t<tr class=\"inside-editor-row data-row\">\n\t\t\t\t<td class=\"\"></td>\n\t\t\t\t<td class=\"\"></td>\n\t\t\t\t<td class=\"\"></td>\n\t\t\t\t<td class=\"\"></td>\n\t\t\t\t<td class=\"\"></td>\n\t\t\t\t<td class=\"\"></td>\n\t\t\t\t<td class=\"cell control-icon\">\n\t\t\t\t\t<button class=\"plus-icon\" onclick=\"\"></button>\n\t\t\t\t</td>\n\t\t\t\t<td class=\"cell control-icon\">\n\t\t\t\t\t<button class=\"minus-icon \" onclick=\"\"></button>\n\t\t\t\t</td>\n\t\t\t</tr>`;\n\t\t}\n\n\t\tinside_editor_div.append( this.editor );\n\n\t\t// Note(private)\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_AREA );\n\n\t\tform_item_input.TTextArea( { field: 'private_note', width: 800, height: 50 } );\n\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Note(private)' ), form_item_input, tab_invoice_column3, '', null, null, true );\n\n\t\t// Note(public)\n\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_AREA );\n\n\t\tform_item_input.TTextArea( { field: 'public_note', width: 500, height: 50 } );\n\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Note(public)' ), form_item_input, tab_invoice_column3, '', null, null, true );\n\n\t\t// Email Invoice To Contact(s)\n\t\twidgetContainer = $( '<div class=\\'widget-h-box\\'></div>' );\n\t\tvar email_invoice = Global.loadWidgetByName( FormItemType.CHECKBOX );\n\t\temail_invoice.TCheckbox( { field: 'email_invoice' } );\n\t\twidgetContainer.append( email_invoice );\n\t\tlabel = $( '<span class=\\'widget-right-label\\'> ' + $.i18n._( 'CC' ) + '</span>' );\n\t\twidgetContainer.append( label );\n\t\tvar email_cc = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\temail_cc.TTextInput( { field: 'email_other_cc', width: 200 } );\n\t\twidgetContainer.append( email_cc );\n\t\tthis.addEditFieldToColumn( $.i18n._( 'Email Invoice To Contact(s)' ), [email_invoice, email_cc], tab_invoice_column3, '', widgetContainer );\n\t}\n\n\tbuildSearchFields() {\n\n\t\tsuper.buildSearchFields();\n\t\tthis.search_fields = [\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Status' ),\n\t\t\t\tin_column: 1,\n\t\t\t\tfield: 'status_id',\n\t\t\t\tmultiple: true,\n\t\t\t\tbasic_search: true,\n\t\t\t\tadv_search: true,\n\t\t\t\tlayout_name: 'global_option_column',\n\t\t\t\tform_item_type: FormItemType.AWESOME_BOX\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Client' ),\n\t\t\t\tin_column: 1,\n\t\t\t\tfield: 'client_id',\n\t\t\t\tlayout_name: 'global_client',\n\t\t\t\tapi_class: TTAPI.APIClient,\n\t\t\t\tmultiple: true,\n\t\t\t\tbasic_search: true,\n\t\t\t\tadv_search: true,\n\t\t\t\tform_item_type: FormItemType.AWESOME_BOX\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Client Group' ),\n\t\t\t\tin_column: 1,\n\t\t\t\tmultiple: true,\n\t\t\t\tfield: 'client_group_id',\n\t\t\t\tlayout_name: 'global_tree_column',\n\t\t\t\ttree_mode: true,\n\t\t\t\tbasic_search: true,\n\t\t\t\tadv_search: true,\n\t\t\t\tform_item_type: FormItemType.AWESOME_BOX\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Invoice Number' ),\n\t\t\t\tin_column: 1,\n\t\t\t\tfield: 'invoice_number',\n\t\t\t\tmultiple: true,\n\t\t\t\tbasic_search: true,\n\t\t\t\tadv_search: true,\n\t\t\t\tform_item_type: FormItemType.TEXT_INPUT\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'PO Number' ),\n\t\t\t\tin_column: 1,\n\t\t\t\tfield: 'po_number',\n\t\t\t\tmultiple: true,\n\t\t\t\tbasic_search: false,\n\t\t\t\tadv_search: true,\n\t\t\t\tform_item_type: FormItemType.TEXT_INPUT\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Sales Rep' ),\n\t\t\t\tin_column: 2,\n\t\t\t\tfield: 'sales_contact_id',\n\t\t\t\tlayout_name: 'global_user',\n\t\t\t\tapi_class: TTAPI.APIUser,\n\t\t\t\tmultiple: true,\n\t\t\t\tbasic_search: true,\n\t\t\t\tadv_search: true,\n\t\t\t\tform_item_type: FormItemType.AWESOME_BOX\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Billing Contact' ),\n\t\t\t\tin_column: 2,\n\t\t\t\tfield: 'billing_contact_id',\n\t\t\t\tlayout_name: 'global_client_contact',\n\t\t\t\tapi_class: TTAPI.APIClientContact,\n\t\t\t\tmultiple: true,\n\t\t\t\tbasic_search: false,\n\t\t\t\tadv_search: true,\n\t\t\t\tform_item_type: FormItemType.AWESOME_BOX\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Shipping Contact' ),\n\t\t\t\tin_column: 2,\n\t\t\t\tfield: 'shipping_contact_id',\n\t\t\t\tlayout_name: 'global_client_contact',\n\t\t\t\tapi_class: TTAPI.APIClientContact,\n\t\t\t\tmultiple: true,\n\t\t\t\tbasic_search: false,\n\t\t\t\tadv_search: true,\n\t\t\t\tform_item_type: FormItemType.AWESOME_BOX\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Other Contact' ),\n\t\t\t\tin_column: 2,\n\t\t\t\tfield: 'other_contact_id',\n\t\t\t\tlayout_name: 'global_client_contact',\n\t\t\t\tapi_class: TTAPI.APIClientContact,\n\t\t\t\tmultiple: true,\n\t\t\t\tbasic_search: false,\n\t\t\t\tadv_search: true,\n\t\t\t\tform_item_type: FormItemType.AWESOME_BOX\n\t\t\t} ),\n\n\t\t\tnew SearchField( {\n\t\t\t\tlabel: $.i18n._( 'Tags' ),\n\t\t\t\tfield: 'tag',\n\t\t\t\tbasic_search: true,\n\t\t\t\tadv_search: true,\n\t\t\t\tin_column: 2,\n\t\t\t\tobject_type_id: 910,\n\t\t\t\tform_item_type: FormItemType.TAG_INPUT\n\t\t\t} )\n\n\t\t];\n\t}\n\n\tsetSelectLayout() {\n\t\tif ( this.sub_view_mode ) {\n\t\t\tsuper.setSelectLayout( ['client'] );\n\t\t} else {\n\t\t\tsuper.setSelectLayout();\n\t\t}\n\t}\n\n\t_continueDoCopyAsNew() {\n\n\t\tvar $this = this;\n\n\t\tthis.setCurrentEditViewState( 'new' );\n\t\tLocalCacheData.current_doing_context_action = 'copy_as_new';\n\t\tif ( Global.isSet( this.edit_view ) ) {\n\n\t\t\tthis.current_edit_record.id = '';\n\t\t\tvar navigation_div = this.edit_view.find( '.navigation-div' );\n\t\t\tnavigation_div.css( 'display', 'none' );\n\t\t\tthis.setEditMenu();\n\t\t\tthis.setTabStatus();\n\n\t\t\tthis.detachElement( 'client' );\n\t\t\tthis.attachElement( 'client_id' );\n\t\t\tthis.edit_view_ui_dic['invoice_number'].setValue( $.i18n._( 'N/A' ) );\n\t\t\tthis.is_changed = false;\n\t\t\tProgressBar.closeOverlay();\n\n\t\t} else {\n\t\t\tsuper._continueDoCopyAsNew();\n\t\t}\n\t}\n\n\tsetCurrentEditRecordData() {\n\t\t//Set current edit record data to all widgets\n\t\tfor ( var key in this.current_edit_record ) {\n\t\t\tif ( !this.current_edit_record.hasOwnProperty( key ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tvar widget = this.edit_view_ui_dic[key];\n\t\t\tif ( Global.isSet( widget ) ) {\n\t\t\t\tswitch ( key ) {\n\t\t\t\t\tcase 'client_id':\n\t\t\t\t\t\twidget.setValue( this.current_edit_record[key] );\n\t\t\t\t\t\tthis.edit_view_ui_dic['billing_contact_id'].setSourceData( null );\n\t\t\t\t\t\tthis.edit_view_ui_dic['shipping_contact_id'].setSourceData( null );\n\t\t\t\t\t\tthis.edit_view_ui_dic['other_contact_id'].setSourceData( null );\n\n\t\t\t\t\t\tif ( !this.current_edit_record || !this.current_edit_record.id ) { //New in sub view, the client_id is set\n\t\t\t\t\t\t\tthis.getClient( this.current_edit_record[key] );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.getClient( this.current_edit_record[key], true );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'combined_shipping_policy_id':\n\t\t\t\t\t\t//set when get shipping options;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'currency_id':\n\t\t\t\t\t\tif ( !this.current_edit_record[key] ) {\n\t\t\t\t\t\t\tthis.current_edit_record[key] = LocalCacheData.getLoginUser().currency_id;\n\t\t\t\t\t\t}\n\t\t\t\t\t\twidget.setValue( this.current_edit_record[key] );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'invoice_number':\n\t\t\t\t\t\tif ( !this.current_edit_record[key] || this.copied_record_id ) {\n\t\t\t\t\t\t\twidget.setValue( $.i18n._( 'N/A' ) );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twidget.setValue( this.current_edit_record[key] );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\twidget.setValue( this.current_edit_record[key] );\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t\tthis.collectUIDataToCurrentEditRecord();\n\t\tthis.setEditViewDataDone();\n\t}\n\n\tshowClientColumn() {\n\t\tif ( this.is_edit ) {\n\t\t\tthis.attachElement( 'client' );\n\t\t\tthis.detachElement( 'client_id' );\n\t\t} else if ( this.is_add ) {\n\t\t\tthis.detachElement( 'client' );\n\t\t\tthis.attachElement( 'client_id' );\n\n\t\t}\n\t}\n\n\tsetPaymentIconDisabled() {\n\t\tlet context_btn = ContextMenuManager.getMenuModelByMenuId( this.determineContextMenuMountAttributes().id ).find( context_icon => context_icon.id === 'payment' );\n\t\tthis.setDefaultMenuPaymentIcon( context_btn );\n\t}\n\n\tonFormItemChange( target, doNotValidate ) {\n\t\tthis.setPaymentIconDisabled();\n\t\tthis.setMassEditingFieldsWhenFormChange( target );\n\t\tthis.setIsChanged( target );\n\t\tvar $this = this;\n\t\tvar key = target.getField();\n\t\tvar c_value = target.getValue();\n\t\tthis.current_edit_record[key] = target.getValue();\n\n\t\tswitch ( key ) {\n\t\t\tcase 'client_id':\n\t\t\t\tthis.edit_view_ui_dic['billing_contact_id'].setSourceData( null );\n\t\t\t\tthis.edit_view_ui_dic['shipping_contact_id'].setSourceData( null );\n\t\t\t\tthis.edit_view_ui_dic['other_contact_id'].setSourceData( null );\n\t\t\t\tthis.edit_view_ui_dic['billing_contact_id'].setValue( false );\n\t\t\t\tthis.edit_view_ui_dic['shipping_contact_id'].setValue( false );\n\t\t\t\tthis.edit_view_ui_dic['other_contact_id'].setValue( false );\n\n\t\t\t\tthis.current_edit_record['billing_contact_id'] = false;\n\t\t\t\tthis.current_edit_record['shipping_contact_id'] = false;\n\t\t\t\tthis.current_edit_record['other_contact_id'] = false;\n\t\t\t\tthis.getClient( c_value );\n\t\t\t\tbreak;\n\t\t\tcase 'billing_contact_id':\n\n\t\t\t\tif ( this.current_edit_record['billing_contact_id'] ) {\n\t\t\t\t\tthis.setDefaultCurrency();\n\t\t\t\t} else {\n\t\t\t\t\tthis.getInvoiceTotalData();\n\t\t\t\t}\n\n\t\t}\n\n\t\tswitch ( key ) {\n\t\t\tcase 'currency_id':\n\t\t\tcase 'shipping_contact_id':\n\t\t\t\tthis.getInvoiceTotalData();\n\t\t\t\tthis.getShippingOptions();\n\t\t\t\tbreak;\n\t\t\tcase 'combined_shipping_policy_id':\n\t\t\t\tthis.getInvoiceTotalData();\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( !doNotValidate ) {\n\t\t\tthis.validate();\n\t\t}\n\t}\n\n\tsetDefaultCurrency() {\n\t\tvar $this = this;\n\t\tvar args = {};\n\t\targs.filter_data = {};\n\t\targs.filter_data.id = this.current_edit_record['billing_contact_id'];\n\t\tthis.client_contact_api['get' + this.client_contact_api.key_name]( args, {\n\t\t\tonResult: function( res ) {\n\t\t\t\tvar result = res.getResult()[0];\n\t\t\t\t// FIXED JS EXCEPTION: Cannot set property 'currency_id' of null\n\t\t\t\tif ( $this.edit_view_ui_dic && $this.current_edit_record ) {\n\t\t\t\t\t//Fixed possible exception -- Error: Unable to get property 'currency_id' of undefined or null reference in /interface/html5/ line 1246\n\t\t\t\t\tif ( result ) {\n\t\t\t\t\t\t$this.current_edit_record['currency_id'] = result.currency_id;\n\t\t\t\t\t\t$this.edit_view_ui_dic['currency_id'].setValue( result.currency_id );\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$this.current_edit_record['currency_id'] = LocalCacheData.getLoginUser().currency_id;\n\t\t\t\t\t\t$this.edit_view_ui_dic['currency_id'].setValue( LocalCacheData.getLoginUser().currency_id );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t$this.getInvoiceTotalData();\n\t\t\t}\n\t\t} );\n\t}\n\n\tgetClient( client_id, filter_only ) {\n\t\tvar $this = this;\n\t\tvar filter = {};\n\t\tfilter.filter_data = { 'id': client_id };\n\t\tfilter.filter_columns = {\n\t\t\t'invoice_number': true,\n\t\t\t'default_other_contact_id': true,\n\t\t\t'client': true,\n\t\t\t'default_billing_contact_id': true,\n\t\t\t'invoice_date': true,\n\t\t\t'status': true,\n\t\t\t'default_shipping_contact_id': true\n\t\t};\n\t\tif ( client_id ) {\n\t\t\tthis.client_api['get' + this.client_api.key_name]( filter, {\n\t\t\t\tonResult: function( res ) {\n\t\t\t\t\tif ( !$this.edit_view ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar result_data = res.getResult();\n\t\t\t\t\tif ( Global.isArray( result_data ) ) {\n\t\t\t\t\t\tvar result = result_data[0];\n\n\t\t\t\t\t\t//When set it first time in setCurrentEditRecord, don't use default value\n\t\t\t\t\t\tif ( !filter_only ) {\n\n\t\t\t\t\t\t\tvar default_billing_contact_id = result.default_billing_contact_id;\n\t\t\t\t\t\t\tvar default_shipping_contact_id = result.default_shipping_contact_id;\n\t\t\t\t\t\t\tvar default_other_contact_id = result.default_other_contact_id;\n\n\t\t\t\t\t\t\t$this.edit_view_ui_dic['billing_contact_id'].setValue( default_billing_contact_id );\n\t\t\t\t\t\t\t$this.edit_view_ui_dic['shipping_contact_id'].setValue( default_shipping_contact_id );\n\t\t\t\t\t\t\t$this.edit_view_ui_dic['other_contact_id'].setValue( default_other_contact_id );\n\n\t\t\t\t\t\t\t$this.current_edit_record['billing_contact_id'] = default_billing_contact_id;\n\t\t\t\t\t\t\t$this.current_edit_record['shipping_contact_id'] = default_shipping_contact_id;\n\t\t\t\t\t\t\t$this.current_edit_record['other_contact_id'] = default_other_contact_id;\n\n\t\t\t\t\t\t\t$this.setDefaultCurrency();\n\t\t\t\t\t\t\t$this.getShippingOptions();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t$this.edit_view_ui_dic['billing_contact_id'].setDefaultArgs( { 'filter_data': { 'client_id': client_id } } );\n\t\t\t\t\t\t$this.edit_view_ui_dic['shipping_contact_id'].setDefaultArgs( { 'filter_data': { 'client_id': client_id } } );\n\t\t\t\t\t\t$this.edit_view_ui_dic['other_contact_id'].setDefaultArgs( { 'filter_data': { 'client_id': client_id } } );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t} );\n\t\t} else {\n\n\t\t\tif ( !filter_only ) {\n\t\t\t\tthis.getInvoiceTotalData();\n\t\t\t\tthis.getShippingOptions();\n\t\t\t}\n\n\t\t}\n\t}\n\n\tsetEditViewDataDone() {\n\t\tsuper.setEditViewDataDone();\n\t\tthis.showClientColumn();\n\t\tthis.initInsideEditorData();\n\t}\n\n\tinitInsideEditorData( update_status ) {\n\n\t\tvar $this = this;\n\n\t\tvar transaction_id = this.current_edit_record.id ? this.current_edit_record.id : this.copied_record_id;\n\t\tthis.copied_record_id = '';\n\n\t\tif ( !transaction_id ) {\n\n\t\t\tthis.transaction_paid_data = null;\n\n\t\t\t$this.editor.removeAllRows();\n\t\t\t$this.editor.getDefaultData();\n\n\t\t\tif ( this.total_data_render ) {\n\t\t\t\tthis.total_data_render.remove();\n\t\t\t\tthis.total_data_render = null;\n\t\t\t\tthis.total_data_row_render = null;\n\t\t\t}\n\n\t\t\tif ( this.history ) {\n\t\t\t\tthis.history.remove();\n\t\t\t\tthis.history = null;\n\t\t\t}\n\n\t\t\t$this.getInvoiceTotalData();\n\t\t\t$this.getShippingOptions();\n\n\t\t} else {\n\n\t\t\tvar filter = {};\n\t\t\tfilter.filter_data = {};\n\t\t\tfilter.filter_data.invoice_id = transaction_id;\n\t\t\tfilter.filter_data.type_id = 10;\n\t\t\tfilter.filter_data.product_type_id = [10, 20];\n\n\t\t\tthis.transaction_api['get' + this.transaction_api.key_name]( filter, true, {\n\t\t\t\tonResult: function( res ) {\n\n\t\t\t\t\tvar result = res.getResult();\n\n\t\t\t\t\t// get the paid data.\n\t\t\t\t\tfilter.filter_data = {};\n\t\t\t\t\tfilter.filter_columns = {\n\t\t\t\t\t\ttype_id: true,\n\t\t\t\t\t\tstatus_id: true,\n\t\t\t\t\t\tpayment_type: true,\n\t\t\t\t\t\tconfirm_number: true,\n\t\t\t\t\t\tid: true,\n\t\t\t\t\t\tclient_id: true,\n\t\t\t\t\t\tinvoice_id: true,\n\t\t\t\t\t\tamount: true,\n\t\t\t\t\t\tstatus: true,\n\t\t\t\t\t\tclient_payment: true\n\t\t\t\t\t};\n\t\t\t\t\tfilter.filter_data.type_id = 20;\n\t\t\t\t\tfilter.filter_data.invoice_id = transaction_id;\n\n\t\t\t\t\t$this.transaction_api['get' + $this.transaction_api.key_name]( filter, true, {\n\t\t\t\t\t\tonResult: function( paid_res ) {\n\n\t\t\t\t\t\t\tif ( !$this.edit_view ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( Global.isSet( update_status ) ) {\n\t\t\t\t\t\t\t\t$this.updateStatus();\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar paid = paid_res.getResult();\n\t\t\t\t\t\t\tif ( paid === true ) {\n\t\t\t\t\t\t\t\t$this.transaction_paid_data = null;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t$this.transaction_paid_data = paid;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$this.editor.setValue( result );\n\t\t\t\t\t\t\t$this.getInvoiceTotalData( result );\n\t\t\t\t\t\t\t$this.getShippingOptions( result );\n\t\t\t\t\t\t\t$this.setTransactionHistoryData();\n\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\t\t\t} );\n\n\t\t}\n\t}\n\n\tinsideEditorSetValue( val ) {\n\t\tvar len = val.length;\n\t\tthis.removeAllRows();\n\n\t\tif ( len > 0 ) {\n\t\t\tfor ( var i = 0; i < val.length; i++ ) {\n\t\t\t\tif ( Global.isSet( val[i] ) ) {\n\t\t\t\t\tvar row = val[i];\n\t\t\t\t\tthis.addRow( row );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.getDefaultData();\n\t\t}\n\t}\n\n\tgetInvoiceTotalData( transaction_data ) {\n\n\t\tvar $this = this;\n\t\tvar transaction_record;\n\n\t\tif ( !$this.edit_view ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( Global.isSet( transaction_data ) ) {\n\t\t\ttransaction_record = transaction_data;\n\t\t} else {\n\t\t\ttransaction_record = this.editor.getValue();\n\t\t}\n\n\t\tif ( this.transaction_paid_data ) {\n\t\t\tvar temp_transaction_record = [];\n\t\t\t$.each( transaction_record, function( key, item ) {\n\t\t\t\ttemp_transaction_record.push( item );\n\t\t\t} );\n\t\t\t$.each( this.transaction_paid_data, function( key, item ) {\n\t\t\t\ttemp_transaction_record.push( item );\n\t\t\t} );\n\n\t\t\ttransaction_record = temp_transaction_record;\n\t\t}\n\n\t\tthis.api.getInvoiceTotalData( transaction_record, this.current_edit_record, false, {\n\t\t\tonResult: function( res ) {\n\n\t\t\t\tvar result = res.getResult();\n\t\t\t\t$this.setInvoiceTotalData( result );\n\t\t\t}\n\t\t} );\n\t}\n\n\tsetTransactionHistoryData() {\n\n\t\tif ( this.transaction_paid_data ) {\n\n\t\t\tif ( this.history ) {\n\t\t\t\tthis.history.remove();\n\t\t\t}\n\n\t\t\tvar tab_invoice = this.edit_view_tab.find( '#tab_invoice' );\n\t\t\tvar inside_editor_div = tab_invoice.find( '.inside-transaction-history-div' );\n\n\t\t\tvar render = `\n\t\t\t<table class=\"inside-editor-render inside-custom-style\">\n\t\t\t\t<tr class=\"title\" style=\"font-weight: bold;\">\n\t\t\t\t\t<td style=\"width: 400px\"><%= status %></td>\n\t\t\t\t\t<td style=\"width: 300px\"><%= payment_type %></td>\n\t\t\t\t\t<td style=\"width: 200px\"><%= client_payment %></td>\n\t\t\t\t\t<td style=\"width: 200px\"><%= confirm_number %></td>\n\t\t\t\t\t<td style=\"width: 100px\"><%= amount %></td>\n\t\t\t\t</tr>\n\t\t\t</table>`;\n\t\t\tvar row_render = `\n\t\t\t<tr class=\"inside-editor-row data-row\">\n\t\t\t\t<td class=\"\"><%= status %></td>\n\t\t\t\t<td class=\"\"><%= payment_type %></td>\n\t\t\t\t<td class=\"\"><%= client_payment %></td>\n\t\t\t\t<td class=\"\"><%= confirm_number %></td>\n\t\t\t\t<td class=\"\"><%= amount %></td>\n\t\t\t</tr>`;\n\n\t\t\tvar title = {\n\t\t\t\tstatus: $.i18n._( 'Status' ),\n\t\t\t\tpayment_type: $.i18n._( 'Payment Type' ),\n\t\t\t\tclient_payment: $.i18n._( 'Payment Method' ),\n\t\t\t\tconfirm_number: $.i18n._( 'Confirmation Number' ),\n\t\t\t\tamount: $.i18n._( 'Amount' )\n\t\t\t};\n\n\t\t\tvar history = Global.loadWidgetByName( FormItemType.INSIDE_EDITOR );\n\n\t\t\tvar template = _.template( render );\n\n\t\t\tvar render_div = history.children().eq( 1 );\n\t\t\trender_div.append( template( title ) );\n\n\t\t\trender = $( render_div.find( '.inside-editor-render' ) );\n\t\t\t/* jshint ignore:start */\n\t\t\tfor ( var key in this.transaction_paid_data ) {\n\t\t\t\tvar row = this.transaction_paid_data[key];\n\t\t\t\t$.each( row, function( i, v ) {\n\t\t\t\t\trow[i] = v ? v : '--';\n\t\t\t\t} );\n\n\t\t\t\tvar tmp_template = _.template( row_render );\n\t\t\t\trender.append( tmp_template( row ) );\n\t\t\t}\n\t\t\t/* jshint ignore:end */\n\t\t\tinside_editor_div.append( render );\n\n\t\t\tthis.history = $( render );\n\t\t}\n\t}\n\n\tsetInvoiceTotalData( total_data ) {\n\n\t\tif ( !this.edit_view ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( Global.isSet( this.total_data_render ) ) {\n\t\t\tthis.total_data_render.remove();\n\t\t\tthis.total_data_render = null;\n\t\t}\n\n\t\tvar tab_invoice = this.edit_view_tab.find( '#tab_invoice' );\n\t\tvar inside_editor_div = tab_invoice.find( '.inside-total-data-editor-div' );\n\t\tthis.total_data_row_render = `\n\t\t<ul class=\"total-data-row\">\n\t\t\t<li class=\"total-data-label\"><%= label %></li>\n\t\t\t<li class=\"total-data-value\"><%= value %></li>\n\t\t</ul>`;\n\t\tthis.total_data_render = $( '<div class=\"total-data-editor\"></div>' );\n\n\t\tvar render_args = this.viewTotalDataUI( Global.removeSortPrefixFromArray( total_data ) );\n\n\t\tif ( Global.isSet( render_args ) ) {\n\t\t\tinside_editor_div.append( this.total_data_render );\n\t\t}\n\t}\n\n\tviewTotalDataUI( total_data ) {\n\n\t\tvar render_args = null;\n\n\t\tfor ( var key in total_data ) {\n\t\t\tvar row = total_data[key];\n\n\t\t\tif ( typeof row === 'object' ) {\n\t\t\t\tif ( key === 'owing' ) {\n\t\t\t\t\tthis.owing_amount = row.amount;\n\t\t\t\t}\n\t\t\t\tif ( Global.isSet( row.amount ) && ( parseFloat( row.amount ) !== 0 || ( key === 'owing' && parseFloat( total_data.paid.amount ) === 0 && parseFloat( total_data.previous_balance.amount ) !== 0 ) ) ) {\n\t\t\t\t\trender_args = { label: row.name, value: row.amount };\n\t\t\t\t\tvar template = _.template( this.total_data_row_render );\n\t\t\t\t\tthis.total_data_render.append( template( render_args ) );\n\t\t\t\t} else {\n\t\t\t\t\tthis.viewTotalDataUI( row );\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\treturn render_args;\n\t}\n\n\tgetShippingOptions( transaction_data ) {\n\t\tvar $this = this;\n\t\tvar transaction_record;\n\t\tif ( Global.isSet( transaction_data ) ) {\n\t\t\ttransaction_record = transaction_data;\n\t\t} else {\n\t\t\ttransaction_record = this.editor.getValue();\n\t\t}\n\n\t\tif ( this.transaction_paid_data ) {\n\t\t\tvar temp_transaction_record = [];\n\t\t\t$.each( transaction_record, function( key, item ) {\n\t\t\t\ttemp_transaction_record.push( item );\n\t\t\t} );\n\t\t\t$.each( this.transaction_paid_data, function( key, item ) {\n\t\t\t\ttemp_transaction_record.push( item );\n\t\t\t} );\n\n\t\t\ttransaction_record = temp_transaction_record;\n\t\t}\n\n\t\tthis.api.getShippingOptions( transaction_record, this.current_edit_record, {\n\t\t\tonResult: function( res ) {\n\n\t\t\t\tif ( !$this.edit_view ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tvar result = res.getResult();\n\t\t\t\tvar combined_shipping_policy_id = $this.current_edit_record.combined_shipping_policy_id;\n\t\t\t\t$this.edit_view_ui_dic['combined_shipping_policy_id'].setSourceData( Global.buildRecordArray( result ) );\n\t\t\t\t$this.edit_view_ui_dic['combined_shipping_policy_id'].setValue( combined_shipping_policy_id );\n\t\t\t}\n\t\t} );\n\t}\n\n\tupdateStatus() {\n\t\tvar $this = this;\n\t\tthis.api['updateStatus']( this.current_edit_record.id, {\n\t\t\tonResult: function( res ) {\n\t\t\t\tif ( res.isValid() ) {\n\t\t\t\t\tvar status_id = res.getResult();\n\t\t\t\t\t$this.edit_view_ui_dic['status_id'].setValue( status_id );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\n\tinitSubClientContactView() {\n\t\tvar $this = this;\n\n\t\tif ( !this.current_edit_record.id ) {\n\t\t\tTTPromise.resolve( 'BaseViewController', 'onTabShow' ); //Since search() isn't called in this case, and we just display the \"Please Save This Record ...\" message, resolve the promise.\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.sub_client_contact_view_controller ) {\n\t\t\tthis.sub_client_contact_view_controller.buildContextMenu( true );\n\t\t\tthis.sub_client_contact_view_controller.setDefaultMenu();\n\t\t\t$this.sub_client_contact_view_controller.parent_key = 'client_id';\n\t\t\t$this.sub_client_contact_view_controller.parent_value = $this.current_edit_record.client_id;\n\t\t\t$this.sub_client_contact_view_controller.parent_edit_record = $this.current_edit_record;\n\t\t\t$this.sub_client_contact_view_controller.initData();\n\t\t\treturn;\n\t\t}\n\n\t\tGlobal.loadScript( 'views/invoice/client_contact/ClientContactViewController.js', function() {\n\t\t\tvar tab_client_contacts = $this.edit_view_tab.find( '#tab_client_contacts' );\n\t\t\tvar firstColumn = tab_client_contacts.find( '.first-column-sub-view' );\n\n\t\t\tGlobal.trackView( 'Sub' + 'ClientContact' + 'View' );\n\t\t\tClientContactViewController.loadSubView( firstColumn, beforeLoadView, afterLoadView );\n\n\t\t} );\n\n\t\tfunction beforeLoadView() {\n\n\t\t}\n\n\t\tfunction afterLoadView( subViewController ) {\n\t\t\t$this.sub_client_contact_view_controller = subViewController;\n\t\t\t$this.sub_client_contact_view_controller.parent_key = 'client_id';\n\t\t\t$this.sub_client_contact_view_controller.parent_value = $this.current_edit_record.client_id;\n\t\t\t$this.sub_client_contact_view_controller.parent_edit_record = $this.current_edit_record;\n\t\t\t$this.sub_client_contact_view_controller.parent_view_controller = $this;\n\t\t\t$this.sub_client_contact_view_controller.postInit = function() {\n\t\t\t\tthis.initData();\n\t\t\t};\n\t\t}\n\t}\n\n\tinitSubClientPaymentView() {\n\t\tvar $this = this;\n\n\t\tif ( !this.current_edit_record.id ) {\n\t\t\tTTPromise.resolve( 'BaseViewController', 'onTabShow' ); //Since search() isn't called in this case, and we just display the \"Please Save This Record ...\" message, resolve the promise.\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.sub_client_payment_view_controller ) {\n\t\t\tthis.sub_client_payment_view_controller.buildContextMenu( true );\n\t\t\tthis.sub_client_payment_view_controller.setDefaultMenu();\n\t\t\t$this.sub_client_payment_view_controller.parent_key = 'client_id';\n\t\t\t$this.sub_client_payment_view_controller.parent_value = $this.current_edit_record.client_id;\n\t\t\t$this.sub_client_payment_view_controller.parent_edit_record = $this.current_edit_record;\n\t\t\t$this.sub_client_payment_view_controller.initData();\n\t\t\treturn;\n\t\t}\n\n\t\tGlobal.loadScript( 'views/invoice/client_payment/ClientPaymentViewController.js', function() {\n\t\t\tvar tab_payment_methods = $this.edit_view_tab.find( '#tab_payment_methods' );\n\t\t\tvar firstColumn = tab_payment_methods.find( '.first-column-sub-view' );\n\n\t\t\tGlobal.trackView( 'Sub' + 'ClientPayment' + 'View' );\n\t\t\tClientPaymentViewController.loadSubView( firstColumn, beforeLoadView, afterLoadView );\n\n\t\t} );\n\n\t\tfunction beforeLoadView() {\n\n\t\t}\n\n\t\tfunction afterLoadView( subViewController ) {\n\t\t\t$this.sub_client_payment_view_controller = subViewController;\n\t\t\t$this.sub_client_payment_view_controller.parent_key = 'client_id';\n\t\t\t$this.sub_client_payment_view_controller.parent_value = $this.current_edit_record.client_id;\n\t\t\t$this.sub_client_payment_view_controller.parent_edit_record = $this.current_edit_record;\n\t\t\t$this.sub_client_payment_view_controller.parent_view_controller = $this;\n\t\t\t$this.sub_client_payment_view_controller.postInit = function() {\n\t\t\t\tthis.initData();\n\t\t\t};\n\t\t}\n\t}\n\n\tinitSubTransactionView() {\n\t\tvar $this = this;\n\n\t\tif ( !this.current_edit_record.id ) {\n\t\t\tTTPromise.resolve( 'BaseViewController', 'onTabShow' ); //Since search() isn't called in this case, and we just display the \"Please Save This Record ...\" message, resolve the promise.\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.sub_transaction_view_controller ) {\n\t\t\tthis.sub_transaction_view_controller.buildContextMenu( true );\n\t\t\tthis.sub_transaction_view_controller.setDefaultMenu();\n\t\t\t$this.sub_transaction_view_controller.parent_key = 'invoice_id';\n\t\t\t$this.sub_transaction_view_controller.parent_value = $this.current_edit_record.id;\n\t\t\t$this.sub_transaction_view_controller.parent_edit_record = $this.current_edit_record;\n\t\t\t$this.sub_transaction_view_controller.initData();\n\t\t\treturn;\n\t\t}\n\n\t\tGlobal.loadScript( 'views/invoice/invoice_transaction/InvoiceTransactionViewController.js', function() {\n\t\t\tvar tab_transactions = $this.edit_view_tab.find( '#tab_transactions' );\n\t\t\tvar firstColumn = tab_transactions.find( '.first-column-sub-view' );\n\n\t\t\tGlobal.trackView( 'Sub' + 'InvoiceTransaction' + 'View' );\n\t\t\tInvoiceTransactionViewController.loadSubView( firstColumn, beforeLoadView, afterLoadView );\n\n\t\t} );\n\n\t\tfunction beforeLoadView() {\n\n\t\t}\n\n\t\tfunction afterLoadView( subViewController ) {\n\t\t\t$this.sub_transaction_view_controller = subViewController;\n\t\t\t$this.sub_transaction_view_controller.parent_key = 'invoice_id';\n\t\t\t$this.sub_transaction_view_controller.parent_value = $this.current_edit_record.id;\n\t\t\t$this.sub_transaction_view_controller.parent_edit_record = $this.current_edit_record;\n\t\t\t$this.sub_transaction_view_controller.parent_view_controller = $this;\n\t\t\t$this.sub_transaction_view_controller.postInit = function() {\n\t\t\t\tthis.initData();\n\t\t\t};\n\t\t}\n\t}\n\n\tremoveEditView() {\n\t\tsuper.removeEditView();\n\t\tthis.history = null;\n\t\tthis.editor = null;\n\t\tthis.total_data_render = null;\n\t\tthis.total_data_row_render = null;\n\t\tthis.transaction_paid_data = null;\n\t\tthis.sub_client_contact_view_controller = null;\n\t\tthis.sub_client_payment_view_controller = null;\n\t\tthis.sub_transaction_view_controller = null;\n\t}\n\n\tinsideEditorAddRow( data, index ) {\n\t\tvar form_item_input;\n\t\tvar widgetContainer;\n\n\t\tvar row = this.getRowRender(); //Get Row render\n\t\tvar render = this.getRender(); //get render, should be a table\n\t\tvar widgets = {}; //Save each row's widgets\n\n\t\tvar $this = this;\n\t\tif ( !data ) {\n\t\t\tthis.getDefaultData( index );\n\t\t} else {\n\n\t\t\t//Save current set item\n\t\t\twidgets.current_edit_item = data;\n\n\t\t\t//Build row widgets\n\n\t\t\t// Product\n\t\t\tvar args = {};\n\t\t\targs.filter_data = {};\n\t\t\targs.filter_data.type_id = [10, 20];\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.AWESOME_BOX );\n\t\t\tform_item_input.AComboBox( {\n\t\t\t\twidth: 203,\n\t\t\t\tis_static_width: true,\n\t\t\t\tapi_class: TTAPI.APIProduct,\n\t\t\t\tallow_multiple_selection: false,\n\t\t\t\tlayout_name: 'global_product',\n\t\t\t\tshow_search_inputs: true,\n\t\t\t\tset_empty: true,\n\t\t\t\tfield: 'product_id'\n\t\t\t} );\n\t\t\tform_item_input.setDefaultArgs( args );\n\t\t\tform_item_input.setValue( data.product_id ? data.product_id : '' );\n\t\t\twidgets[form_item_input.getField()] = form_item_input;\n\t\t\trow.children().eq( 0 ).append( form_item_input );\n\n\t\t\tthis.setWidgetEnableBaseOnParentController( form_item_input );\n\n\t\t\tform_item_input.bind( 'formItemChange', function( e, target ) {\n\t\t\t\t$this.parent_controller.onRowChanges( $( this ).parent().parent().index() - 1, target );\n\t\t\t} );\n\n\t\t\t// Description\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tform_item_input.TTextInput( { field: 'description', width: 500 } );\n\t\t\tform_item_input.setValue( data.description ? data.description : '' );\n\t\t\twidgets[form_item_input.getField()] = form_item_input;\n\t\t\trow.children().eq( 1 ).append( form_item_input );\n\n\t\t\tthis.setWidgetEnableBaseOnParentController( form_item_input );\n\n\t\t\t// QTY\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tform_item_input.TTextInput( { field: 'quantity', width: 50, no_validate_timer_sec: 100 } );\n\t\t\tform_item_input.setValue( data.quantity ? data.quantity : '' );\n\n\t\t\tform_item_input.bind( 'formItemChange', function( e, target, doNotValidate ) {\n\t\t\t\tif ( doNotValidate ) {\n\t\t\t\t\t$this.parent_controller.onRowChanges( $( this ).parent().parent().index() - 1, target );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\twidgets[form_item_input.getField()] = form_item_input;\n\t\t\trow.children().eq( 2 ).append( form_item_input );\n\n\t\t\tthis.setWidgetEnableBaseOnParentController( form_item_input );\n\n\t\t\t// Price\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tform_item_input.TTextInput( { field: 'unit_price', width: 50, no_validate_timer_sec: 100 } );\n\t\t\tform_item_input.setValue( data.unit_price ? data.unit_price : '' );\n\n\t\t\tform_item_input.bind( 'formItemChange', function( e, target, doNotValidate ) {\n\t\t\t\tif ( doNotValidate ) {\n\t\t\t\t\t$this.parent_controller.onRowChanges( $( this ).parent().parent().index() - 1, target );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\twidgets[form_item_input.getField()] = form_item_input;\n\t\t\trow.children().eq( 3 ).append( form_item_input );\n\n\t\t\tthis.setWidgetEnableBaseOnParentController( form_item_input );\n\n\t\t\t// ProRate\n\t\t\twidgetContainer = $( '<div class=\\'widget-h-box\\'></div>' );\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tform_item_input.TTextInput( { field: 'pro_rate_numerator', width: 50, no_validate_timer_sec: 100 } );\n\t\t\tform_item_input.setValue( data.pro_rate_numerator ? data.pro_rate_numerator : 1 );\n\t\t\tform_item_input.attr( 'maxlength', 3 );\n\n\t\t\tform_item_input.bind( 'formItemChange', function( e, target, doNotValidate ) {\n\t\t\t\tif ( doNotValidate ) {\n\t\t\t\t\t$this.parent_controller.onRowChanges( $( this ).parent().parent().parent().index() - 1, target );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\twidgets[form_item_input.getField()] = form_item_input;\n\t\t\twidgetContainer.append( form_item_input );\n\n\t\t\tvar label = $( '<span class=\\'widget-right-label\\'>/</span>' );\n\t\t\twidgetContainer.append( label );\n\n\t\t\tthis.setWidgetEnableBaseOnParentController( form_item_input );\n\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tform_item_input.TTextInput( { field: 'pro_rate_denominator', width: 50, no_validate_timer_sec: 100 } );\n\t\t\tform_item_input.setValue( data.pro_rate_denominator ? data.pro_rate_denominator : 1 );\n\t\t\tform_item_input.attr( 'maxlength', 3 );\n\n\t\t\tform_item_input.bind( 'formItemChange', function( e, target, doNotValidate ) {\n\t\t\t\tif ( doNotValidate ) {\n\t\t\t\t\t$this.parent_controller.onRowChanges( $( this ).parent().parent().parent().index() - 1, target );\n\t\t\t\t}\n\t\t\t} );\n\n\t\t\twidgets[form_item_input.getField()] = form_item_input;\n\t\t\twidgetContainer.append( form_item_input );\n\n\t\t\trow.children().eq( 4 ).append( widgetContainer );\n\n\t\t\tthis.setWidgetEnableBaseOnParentController( form_item_input );\n\n\t\t\t// Total\n\t\t\tform_item_input = Global.loadWidgetByName( FormItemType.TEXT_INPUT );\n\t\t\tform_item_input.TTextInput( { field: 'amount', width: 100 } );\n\t\t\tform_item_input.setValue( data.amount ? data.amount : '' );\n\t\t\tform_item_input.setReadOnly( true );\n//\t\t\tform_item_input.attr( 'readonly', 'readonly' );\n\n\t\t\twidgets[form_item_input.getField()] = form_item_input;\n\t\t\trow.children().eq( 5 ).append( form_item_input );\n\n\t\t\tif ( typeof index != 'undefined' ) {\n\n\t\t\t\trow.insertAfter( $( render ).find( 'tr' ).eq( index ) );\n\t\t\t\tthis.rows_widgets_array.splice( ( index ), 0, widgets );\n\n\t\t\t} else {\n\t\t\t\t$( render ).append( row );\n\t\t\t\tthis.rows_widgets_array.push( widgets );\n\t\t\t}\n\t\t\tif ( this.parent_controller.is_viewing ) {\n\t\t\t\trow.find( '.control-icon' ).hide();\n\t\t\t}\n\n\t\t\tthis.setWidgetEnableBaseOnParentController( form_item_input );\n\n\t\t\tvar plus_icon = row.find( '.plus-icon' );\n\t\t\tvar minus_icon = row.find( '.minus-icon' );\n\n\t\t\tplus_icon.click( function() {\n\t\t\t\t$this.parent_controller.setPaymentIconDisabled();\n\t\t\t\t$this.addRow( null, $( this ).parent().parent().index() );\n\t\t\t} );\n\n\t\t\tminus_icon.click( function() {\n\t\t\t\t$this.parent_controller.setPaymentIconDisabled();\n\t\t\t\t$this.removeRow( row );\n\n\t\t\t\tif ( render.find( 'tr' ).length === 1 ) {\n\t\t\t\t\t$this.addRow();\n\t\t\t\t}\n\n\t\t\t} );\n\n//\t\t\tthis.addIconsEvent( row ); //Bind event to add and minus icon\n\t\t\tthis.removeLastRowLine();\n\t\t}\n\n\t\tif ( data && TTUUID.isUUID( data.product_id ) && data.product_id != TTUUID.zero_id ) {\n\t\t\tvar filter = {};\n\t\t\tfilter.filter_data = {};\n\t\t\tfilter.filter_data.id = data.product_id;\n\t\t\tfilter.filter_columns = { id: true, price_locked: true, description_locked: true };\n\t\t\tthis.parent_controller.product_api['get' + this.parent_controller.product_api.key_name]( filter, {\n\t\t\t\tonResult: function( res ) {\n\t\t\t\t\tvar result = res.getResult()[0];\n\t\t\t\t\twidgets['description'].setReadOnly( result.description_locked );\n\t\t\t\t\twidgets['unit_price'].setReadOnly( result.price_locked );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t}\n\n\tinsideEditorRemoveRow( row ) {\n\t\tvar index = row[0].rowIndex - 1;\n\t\tvar remove_id = this.rows_widgets_array[index].current_edit_item.id;\n\t\tif ( TTUUID.isUUID( remove_id ) && remove_id != TTUUID.zero_id && remove_id != TTUUID.not_exist_id ) {\n\t\t\tthis.delete_ids.push( remove_id );\n\t\t}\n\t\trow.remove();\n\t\tthis.rows_widgets_array.splice( index, 1 );\n\t\tthis.parent_controller.getInvoiceTotalData();\n\t\tthis.removeLastRowLine();\n\t}\n\n\tonRowChanges( index, target ) {\n\t\tthis.setPaymentIconDisabled();\n\t\tvar $this = this;\n\t\tvar current_row = this.editor.rows_widgets_array[index];\n\t\tvar key = target.getField();\n\t\tvar value = target.getValue();\n\t\tvar filter = {};\n\t\tfilter.filter_data = {};\n\t\tfilter.filter_columns = {};\n\t\tfilter.filter_columns.description = true;\n\t\tfilter.filter_columns.name = true;\n\t\tfilter.filter_columns.part_number = true;\n\t\tfilter.filter_columns.type_id = true;\n\t\tfilter.filter_columns.currency_id = true;\n\t\tfilter.filter_columns.id = true;\n\t\tfilter.filter_columns.price_locked = true;\n\t\tfilter.filter_columns.description_locked = true;\n\n\t\tswitch ( key ) {\n\t\t\tcase 'quantity':\n\t\t\tcase 'product_id':\n\t\t\t\tvar product_id;\n\t\t\t\tvar quantity;\n\t\t\t\tif ( key === 'product_id' ) {\n\t\t\t\t\tquantity = 1;\n\t\t\t\t\tproduct_id = value;\n\t\t\t\t} else {\n\t\t\t\t\tquantity = value;\n\t\t\t\t\tproduct_id = current_row['product_id'].getValue();\n\t\t\t\t}\n\t\t\t\tif ( TTUUID.isUUID( product_id ) && product_id != TTUUID.zero_id ) {\n\t\t\t\t\tfilter.filter_data.id = product_id;\n\t\t\t\t\tthis.product_api['get' + this.product_api.key_name]( filter, {\n\t\t\t\t\t\tonResult: function( p_res ) {\n\t\t\t\t\t\t\tvar result_data = p_res.getResult()[0];\n\t\t\t\t\t\t\tif ( key === 'product_id' ) {\n\t\t\t\t\t\t\t\tcurrent_row['description'].setValue( result_data['description'] );\n\t\t\t\t\t\t\t\tcurrent_row['description'].setReadOnly( result_data['description_locked'] );\n\t\t\t\t\t\t\t\tcurrent_row['unit_price'].setReadOnly( result_data['price_locked'] );\n\n\t\t\t\t\t\t\t\tcurrent_row['current_edit_item']['product_type_id'] = result_data['type_id'];\n\t\t\t\t\t\t\t\tcurrent_row['current_edit_item']['product_name'] = result_data['name'];\n\t\t\t\t\t\t\t\tcurrent_row['current_edit_item']['product_part_number'] = result_data['part_number'];\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( result_data.id && $this.current_edit_record && $this.current_edit_record['currency_id'] ) {\n\t\t\t\t\t\t\t\t$this.product_api['getProductQuantityUnitPrice']( result_data.id, quantity, $this.current_edit_record['currency_id'], {\n\t\t\t\t\t\t\t\t\tonResult: function( u_res ) {\n\t\t\t\t\t\t\t\t\t\tvar unit_price = u_res.getResult();\n\t\t\t\t\t\t\t\t\t\tif ( key === 'product_id' ) {\n\t\t\t\t\t\t\t\t\t\t\tcurrent_row['quantity'].setValue( quantity );\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tcurrent_row['unit_price'].setValue( unit_price );\n\t\t\t\t\t\t\t\t\t\t$this.calcTransactionRowTotal( current_row );\n\t\t\t\t\t\t\t\t\t\tif ( $this.editor && $this.editor.rows_widgets_array ) {\n\t\t\t\t\t\t\t\t\t\t\t$this.editor.rows_widgets_array[index] = current_row;\n\t\t\t\t\t\t\t\t\t\t\tvar transaction_data = $this.editor.getValue();\n\t\t\t\t\t\t\t\t\t\t\t$this.getInvoiceTotalData( transaction_data );\n\t\t\t\t\t\t\t\t\t\t\t$this.getShippingOptions( transaction_data );\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'pro_rate_numerator':\n\t\t\tcase 'pro_rate_denominator':\n\t\t\tcase 'unit_price':\n\t\t\t\tthis.calcTransactionRowTotal( current_row );\n\t\t\t\tvar transaction_data = $this.editor.getValue();\n\t\t\t\tthis.getInvoiceTotalData( transaction_data );\n\t\t\t\tthis.getShippingOptions( transaction_data );\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tcalcTransactionRowTotal( current_row ) {\n\t\tvar total = 0.00;\n\t\tvar pro_rate_numerator = parseFloat( current_row['pro_rate_numerator'].getValue() );\n\t\tvar pro_rate_denominator = parseFloat( current_row['pro_rate_denominator'].getValue() );\n\t\tvar quantity = parseFloat( current_row['quantity'].getValue() );\n\t\tvar unit_price = parseFloat( current_row['unit_price'].getValue() );\n\n\t\tif ( ( !isNaN( quantity ) && isFinite( quantity ) ) && ( !isNaN( unit_price ) && isFinite( unit_price ) ) ) {\n\t\t\ttotal = ( quantity * unit_price );\n\t\t}\n\n\t\tif ( ( !isNaN( pro_rate_numerator ) && isFinite( pro_rate_numerator ) && pro_rate_numerator != 0 ) && ( !isNaN( pro_rate_denominator ) && isFinite( pro_rate_denominator ) && pro_rate_denominator != 0 ) ) {\n\t\t\ttotal = ( total * ( pro_rate_numerator / pro_rate_denominator ) );\n\t\t}\n\n\t\tcurrent_row['amount'].setValue( parseFloat( total ).toFixed( 2 ) );\n\t}\n\n\tinsideEditorGetValue( current_edit_item_id ) {\n\t\tvar len = this.rows_widgets_array.length;\n\n\t\tvar result = [];\n\n\t\tfor ( var i = 0; i < len; i++ ) {\n\n\t\t\tvar row = this.rows_widgets_array[i];\n\t\t\tvar data = {};\n\t\t\tdata['status_id'] = row.current_edit_item['status_id'];\n\t\t\tdata['product_part_number'] = row.current_edit_item['product_part_number'];\n\t\t\tdata['id'] = row.current_edit_item['id'];\n\t\t\tdata['description'] = row.current_edit_item['description'];\n\t\t\tdata['product_name'] = row.current_edit_item['product_name'];\n\t\t\tdata['amount'] = row.current_edit_item['amount'];\n\t\t\tdata['unit_price'] = row.current_edit_item['unit_price'];\n\t\t\tdata['product_type_id'] = row.current_edit_item['product_type_id'];\n\t\t\tdata['type_id'] = row.current_edit_item['type_id'];\n\t\t\tdata['pro_rate_denominator'] = row.current_edit_item['pro_rate_denominator'];\n\t\t\tdata['client_id'] = row.current_edit_item['client_id'];\n\t\t\tdata['quantity'] = row.current_edit_item['quantity'];\n\t\t\tdata['product_id'] = row.current_edit_item['product_id'];\n\t\t\tdata['invoice_id'] = row.current_edit_item['invoice_id'];\n\t\t\tdata['pro_rate_numerator'] = row.current_edit_item['pro_rate_numerator'];\n\t\t\tdata['effective_date'] = row.current_edit_item['effective_date'];\n\n\t\t\tvar product_id = row['product_id'].getValue();\n\n\t\t\tif ( typeof current_edit_item_id !== 'undefined' && ( current_edit_item_id === '' || current_edit_item_id === false ) ) {\n\t\t\t\tdata['id'] = '';\n\t\t\t\tdata['invoice_id'] = '';\n\t\t\t\tdata['type_id'] = 10;\n\t\t\t\tdata['effective_date'] = new Date().format();\n\t\t\t}\n\n\t\t\tif ( typeof data.effective_date === 'undefined' ) {\n\t\t\t\tdata['effective_date'] = new Date().format();\n\t\t\t}\n\n\t\t\tif ( typeof data.type_id === 'undefined' ) {\n\t\t\t\tdata['type_id'] = 10;\n\t\t\t}\n\n\t\t\tif ( TTUUID.isUUID( product_id ) && product_id != TTUUID.zero_id ) {\n\t\t\t\tdata['product_id'] = product_id;\n\t\t\t\tdata['quantity'] = row['quantity'].getValue();\n\t\t\t\tdata['pro_rate_numerator'] = row['pro_rate_numerator'].getValue();\n\t\t\t\tdata['description'] = row['description'].getValue();\n\t\t\t\tdata['pro_rate_denominator'] = row['pro_rate_denominator'].getValue();\n\t\t\t\tdata['amount'] = row['amount'].getValue();\n\t\t\t\tdata['unit_price'] = row['unit_price'].getValue();\n\t\t\t\tdata['client_id'] = this.parent_controller.current_edit_record['client_id'];\n\n\t\t\t\tresult.push( data );\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tuniformVariable( record ) {\n\n\t\tif ( !Global.isSet( record ) ) {\n\t\t\trecord = {};\n\t\t}\n\t\tvar transaction_data = this.editor.getValue( this.current_edit_record.id );\n\t\tif ( transaction_data.length > 0 ) {\n\t\t\trecord.transactions = transaction_data;\n\t\t}\n\n\t\treturn record;\n\t}\n\n\tonCopyAsNewResult( result ) {\n\t\tvar $this = this;\n\t\tvar result_data = result.getResult();\n\t\tif ( !result_data ) {\n\t\t\tTAlertManager.showAlert( $.i18n._( 'Record does not exist' ) );\n\t\t\t$this.onCancelClick();\n\t\t\treturn;\n\t\t}\n\n\t\t$this.openEditView(); // Put it here is to avoid if the selected one is not existed in data or have deleted by other pragram. in this case, the edit view should not be opend.\n\n\t\tresult_data = result_data[0];\n\t\tthis.copied_record_id = result_data.id;\n\n\t\tresult_data.id = '';\n\n\t\tif ( $this.sub_view_mode && $this.parent_key ) {\n\t\t\tresult_data[$this.parent_key] = $this.parent_value;\n\t\t}\n\n\t\t$this.current_edit_record = result_data;\n\t\t$this.initEditView();\n\t}\n\n\tgetInvoiceTabHtml() {\n\t\treturn `<div id=\"tab_invoice\" class=\"edit-view-tab-outside\">\n\t\t\t\t\t<div class=\"edit-view-tab\" id=\"tab_invoice_content_div\">\n\t\t\t\t\t\t<div class=\"first-column\"></div>\n\t\t\t\t\t\t<div class=\"second-column\"></div>\n\t\t\t\t\t\t<div class=\"inside-editor-div full-width-column\" style=\"margin-bottom: 10px;\"></div>\n\t\t\t\t\t\t<div class=\"inside-total-data-editor-div\"></div>\n\t\t\t\t\t\t<div class=\"inside-transaction-history-div\"></div>\n\t\t\t\t\t\t<div class=\"third-column full-width-column\"></div>\n\t\t\t\t\t</div>\n\t\t\t\t</div>`;\n\t}\n\n}\n\nInvoiceViewController.loadSubView = function( container, beforeViewLoadedFun, afterViewLoadedFun ) {\n\n\tGlobal.loadViewSource( 'Invoice', 'SubInvoiceView.html', function( result ) {\n\t\tvar args = {};\n\t\tvar template = _.template( result );\n\n\t\tif ( Global.isSet( beforeViewLoadedFun ) ) {\n\t\t\tbeforeViewLoadedFun();\n\t\t}\n\n\t\tif ( Global.isSet( container ) ) {\n\t\t\tcontainer.html( template( args ) );\n\t\t\tif ( Global.isSet( afterViewLoadedFun ) ) {\n\t\t\t\tafterViewLoadedFun( sub_invoice_view_controller );\n\t\t\t}\n\t\t}\n\t} );\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiNDU4NS5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7QUFBTztBQUNQLDJCQUEyQjtBQUMzQixFQUFFLENBQUM7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQSxJQUFJOztBQUVKO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLENBQUM7QUFDNUIsMEJBQTBCLENBQUM7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLENBQUM7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLFlBQVksQ0FBQztBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsWUFBWSxDQUFDO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLENBQUM7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0EsV0FBVyxDQUFDO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07O0FBRU47QUFDQSxXQUFXLENBQUM7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0EsV0FBVyxDQUFDO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07O0FBRU47QUFDQSxXQUFXLENBQUM7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTs7QUFFTjtBQUNBLFdBQVcsQ0FBQztBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLG9CQUFvQixTQUFTO0FBQzdCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsR0FBRyxDQUFDO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxlQUFlLGVBQWU7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxDQUFDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxDQUFDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxDQUFDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxDQUFDO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBO0FBQ0E7QUFDQSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsSUFBSTtBQUNKOztBQUVBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxhQUFhLENBQUM7QUFDZDtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsYUFBYSxDQUFDO0FBQ2Q7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLGFBQWEsQ0FBQztBQUNkO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxhQUFhLENBQUM7QUFDZDtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSiw2QkFBNkIsQ0FBQzs7QUFFOUI7QUFDQTtBQUNBLDJCQUEyQixrQkFBa0I7QUFDN0MsNkJBQTZCLENBQUM7O0FBRTlCO0FBQ0E7QUFDQSwrQkFBK0IscUJBQXFCO0FBQ3BEO0FBQ0EsNkJBQTZCLENBQUM7O0FBRTlCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osNkJBQTZCLENBQUM7O0FBRTlCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osNkJBQTZCLENBQUM7O0FBRTlCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osNkJBQTZCLENBQUM7O0FBRTlCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLDZCQUE2QixDQUFDOztBQUU5QjtBQUNBOztBQUVBLGdDQUFnQyxpQ0FBaUM7QUFDakUsNkJBQTZCLENBQUM7O0FBRTlCO0FBQ0E7O0FBRUEsK0JBQStCLG9DQUFvQztBQUNuRSw2QkFBNkIsQ0FBQzs7QUFFOUI7QUFDQTtBQUNBLDJCQUEyQiwwQkFBMEI7QUFDckQsNkJBQTZCLENBQUM7O0FBRTlCO0FBQ0E7O0FBRUEsaUNBQWlDLHdCQUF3QjtBQUN6RCw2QkFBNkIsQ0FBQzs7QUFFOUI7QUFDQTs7QUFFQSxpQ0FBaUMsc0JBQXNCO0FBQ3ZELDZCQUE2QixDQUFDOztBQUU5QjtBQUNBOztBQUVBLGlDQUFpQyx5QkFBeUI7QUFDMUQsNkJBQTZCLENBQUM7O0FBRTlCO0FBQ0E7O0FBRUEsaUNBQWlDLHdCQUF3QjtBQUN6RCw2QkFBNkIsQ0FBQzs7QUFFOUI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSiw2QkFBNkIsQ0FBQzs7QUFFOUI7QUFDQTs7QUFFQSxnQ0FBZ0MsMkJBQTJCO0FBQzNELDZCQUE2QixDQUFDOztBQUU5QjtBQUNBO0FBQ0EsK0JBQStCLHVDQUF1QztBQUN0RSw2QkFBNkIsQ0FBQzs7QUFFOUI7O0FBRUE7O0FBRUE7QUFDQSxZQUFZLENBQUM7QUFDYixnQkFBZ0IsQ0FBQztBQUNqQixRQUFRLENBQUM7QUFDVCxVQUFVLENBQUM7QUFDWCxZQUFZLENBQUM7QUFDYixVQUFVLENBQUM7QUFDWDs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0EsK0NBQStDO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEsK0JBQStCLGdEQUFnRDs7QUFFL0UsNkJBQTZCLENBQUM7O0FBRTlCO0FBQ0E7O0FBRUEsK0JBQStCLCtDQUErQzs7QUFFOUUsNkJBQTZCLENBQUM7O0FBRTlCO0FBQ0Esb0JBQW9CLENBQUM7QUFDckI7QUFDQSw2QkFBNkIseUJBQXlCO0FBQ3REO0FBQ0EsVUFBVSxDQUFDLDJDQUEyQyxDQUFDO0FBQ3ZEO0FBQ0E7QUFDQSx5QkFBeUIsc0NBQXNDO0FBQy9EO0FBQ0EsNkJBQTZCLENBQUM7QUFDOUI7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLFdBQVcsQ0FBQztBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLFdBQVcsQ0FBQztBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0EsV0FBVyxDQUFDO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQSxXQUFXLENBQUM7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0EsV0FBVyxDQUFDO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLFdBQVcsQ0FBQztBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0EsV0FBVyxDQUFDO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQSxXQUFXLENBQUM7QUFDWjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBLFdBQVcsQ0FBQztBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0EsV0FBVyxDQUFDO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHFEQUFxRCxDQUFDO0FBQ3REO0FBQ0E7O0FBRUEsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx5RUFBeUU7QUFDekU7QUFDQSxRQUFRO0FBQ1I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsQ0FBQztBQUN6QixRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxxRUFBcUUsaUJBQWlCLDJCQUEyQjtBQUNqSCxzRUFBc0UsaUJBQWlCLDJCQUEyQjtBQUNsSCxtRUFBbUUsaUJBQWlCLDJCQUEyQjs7QUFFL0c7O0FBRUE7QUFDQSxLQUFLO0FBQ0wsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxPQUFPOztBQUVQO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLG9CQUFvQixnQkFBZ0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHLENBQUM7QUFDSjtBQUNBLEtBQUs7QUFDTCxHQUFHLENBQUM7QUFDSjtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsK0NBQStDO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFlBQVksQ0FBQztBQUNiLGtCQUFrQixDQUFDO0FBQ25CLG9CQUFvQixDQUFDO0FBQ3JCLG9CQUFvQixDQUFDO0FBQ3JCLFlBQVksQ0FBQztBQUNiOztBQUVBOztBQUVBLGtCQUFrQixDQUFDOztBQUVuQjtBQUNBOztBQUVBLFlBQVksQ0FBQztBQUNiO0FBQ0E7QUFDQTtBQUNBLElBQUksQ0FBQztBQUNMO0FBQ0EsTUFBTTs7QUFFTix1QkFBdUIsQ0FBQztBQUN4QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxrQkFBa0IsQ0FBQztBQUNuQjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixDQUFDOztBQUU1Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckIsb0JBQW9CLENBQUM7QUFDckI7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHLENBQUM7QUFDSjtBQUNBLEtBQUs7QUFDTCxHQUFHLENBQUM7QUFDSjtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMkRBQTJEO0FBQzNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7O0FBRUo7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMkRBQTJEO0FBQzNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7O0FBRUo7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsMkRBQTJEO0FBQzNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7O0FBRUo7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxpQ0FBaUM7QUFDakMsaUNBQWlDO0FBQ2pDLG9CQUFvQjs7QUFFcEI7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSwwQ0FBMEMsQ0FBQztBQUMzQyxLQUFLOztBQUVMO0FBQ0E7QUFDQSxpQ0FBaUMsbUNBQW1DO0FBQ3BFO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsaUNBQWlDLDJEQUEyRDtBQUM1Rjs7QUFFQTtBQUNBO0FBQ0EsMkNBQTJDLENBQUM7QUFDNUM7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLGlDQUFpQyw2REFBNkQ7QUFDOUY7O0FBRUE7QUFDQTtBQUNBLDJDQUEyQyxDQUFDO0FBQzVDO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBOztBQUVBO0FBQ0EscUJBQXFCLENBQUM7QUFDdEI7QUFDQSxpQ0FBaUMscUVBQXFFO0FBQ3RHO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDJDQUEyQyxDQUFDO0FBQzVDO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBLGVBQWUsQ0FBQztBQUNoQjs7QUFFQTs7QUFFQTtBQUNBLGlDQUFpQyx1RUFBdUU7QUFDeEc7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsMkNBQTJDLENBQUM7QUFDNUM7QUFDQSxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLGlDQUFpQyw4QkFBOEI7QUFDL0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUEscUJBQXFCLENBQUM7QUFDdEI7O0FBRUEsS0FBSztBQUNMLElBQUksQ0FBQztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCLENBQUM7QUFDekIsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLEtBQUs7O0FBRUwsZ0NBQWdDO0FBQ2hDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQSxtQkFBbUIsU0FBUzs7QUFFNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLENBQUM7QUFDN0I7QUFDQTtBQUNBOztBQUVBLHdCQUF3Qjs7QUFFeEI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRkFBa0Y7QUFDbEY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUIsQ0FBQzs7QUFFbEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL2ludGVyZmFjZS9odG1sNS92aWV3cy9pbnZvaWNlL2ludm9pY2UvSW52b2ljZVZpZXdDb250cm9sbGVyLmpzPzY0ZjgiXSwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIEludm9pY2VWaWV3Q29udHJvbGxlciBleHRlbmRzIEJhc2VWaWV3Q29udHJvbGxlciB7XG5cdGNvbnN0cnVjdG9yKCBvcHRpb25zID0ge30gKSB7XG5cdFx0Xy5kZWZhdWx0cyggb3B0aW9ucywge1xuXHRcdFx0c3RhdHVzX2FycmF5OiBudWxsLFxuXG5cdFx0XHRjbGllbnRfZ3JvdXBfYXJyYXk6IG51bGwsXG5cdFx0XHRjbGllbnRfZ3JvdXBfYXBpOiBudWxsLFxuXHRcdFx0Y2xpZW50X2FwaTogbnVsbCxcblx0XHRcdGNsaWVudF9jb250YWN0X2FwaTogbnVsbCxcblx0XHRcdHByb2R1Y3RfYXBpOiBudWxsLFxuXHRcdFx0dHJhbnNhY3Rpb25fYXBpOiBudWxsLFxuXG5cdFx0XHRlbDogJyNpbnZvaWNlX3ZpZXdfY29udGFpbmVyJyxcblxuXHRcdFx0c3ViX2NsaWVudF9jb250YWN0X3ZpZXdfY29udHJvbGxlcjogbnVsbCxcblx0XHRcdHN1Yl9jbGllbnRfcGF5bWVudF92aWV3X2NvbnRyb2xsZXI6IG51bGwsXG5cdFx0XHRzdWJfdHJhbnNhY3Rpb25fdmlld19jb250cm9sbGVyOiBudWxsLFxuXG5cdFx0XHR0b3RhbF9kYXRhX3JlbmRlcjogbnVsbCxcblx0XHRcdHRvdGFsX2RhdGFfcm93X3JlbmRlcjogbnVsbCxcblxuXHRcdFx0b3dpbmdfYW1vdW50OiBudWxsLFxuXG5cdFx0XHR0cmFuc2FjdGlvbl9wYWlkX2RhdGE6IG51bGwsXG5cblx0XHRcdGhpc3Rvcnk6IG51bGwsXG5cblx0XHRcdGVkaXRvcjogbnVsbFxuXHRcdH0gKTtcblxuXHRcdHN1cGVyKCBvcHRpb25zICk7XG5cdH1cblxuXHRpbml0KCBvcHRpb25zICkge1xuXG5cdFx0Ly90aGlzLl9zdXBlcignaW5pdGlhbGl6ZScsIG9wdGlvbnMgKTtcblx0XHR0aGlzLmVkaXRfdmlld190cGwgPSAnSW52b2ljZUVkaXRWaWV3Lmh0bWwnO1xuXHRcdHRoaXMucGVybWlzc2lvbl9pZCA9ICdpbnZvaWNlJztcblx0XHR0aGlzLnZpZXdJZCA9ICdJbnZvaWNlJztcblx0XHR0aGlzLnNjcmlwdF9uYW1lID0gJ0ludm9pY2VWaWV3Jztcblx0XHR0aGlzLnRhYmxlX25hbWVfa2V5ID0gJ2ludm9pY2UnO1xuXHRcdHRoaXMuY29udGV4dF9tZW51X25hbWUgPSAkLmkxOG4uXyggJ0ludm9pY2VzJyApO1xuXHRcdHRoaXMubmF2aWdhdGlvbl9sYWJlbCA9ICQuaTE4bi5fKCAnSW52b2ljZScgKTtcblx0XHR0aGlzLmFwaSA9IFRUQVBJLkFQSUludm9pY2U7XG5cdFx0dGhpcy5jbGllbnRfZ3JvdXBfYXBpID0gVFRBUEkuQVBJQ2xpZW50R3JvdXA7XG5cdFx0dGhpcy5jbGllbnRfYXBpID0gVFRBUEkuQVBJQ2xpZW50O1xuXHRcdHRoaXMucHJvZHVjdF9hcGkgPSBUVEFQSS5BUElQcm9kdWN0O1xuXHRcdHRoaXMudHJhbnNhY3Rpb25fYXBpID0gVFRBUEkuQVBJVHJhbnNhY3Rpb247XG5cdFx0dGhpcy5jbGllbnRfY29udGFjdF9hcGkgPSBUVEFQSS5BUElDbGllbnRDb250YWN0O1xuXG5cdFx0dGhpcy5yZW5kZXIoKTtcblxuXHRcdHRoaXMuYnVpbGRDb250ZXh0TWVudSgpO1xuXG5cdFx0aWYgKCAhdGhpcy5zdWJfdmlld19tb2RlICkge1xuXHRcdFx0dGhpcy5pbml0RGF0YSgpO1xuXHRcdH1cblx0fVxuXG5cdGdldEN1c3RvbUNvbnRleHRNZW51TW9kZWwoKSB7XG5cdFx0dmFyIGNvbnRleHRfbWVudV9tb2RlbCA9IHtcblx0XHRcdGV4Y2x1ZGU6IFsnbWFzc19lZGl0J10sXG5cdFx0XHRpbmNsdWRlOiBbXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRsYWJlbDogJC5pMThuLl8oICdWaWV3OiBJbnZvaWNlJyApLFxuXHRcdFx0XHRcdGlkOiAndmlldycsXG5cdFx0XHRcdFx0YWN0aW9uX2dyb3VwOiAndmlldycsXG5cdFx0XHRcdFx0dnVlX2ljb246ICd0dGljb24gdHRpY29uLXZpc2liaWxpdHlfYmxhY2tfMjRkcCcsXG5cdFx0XHRcdFx0c29ydF9vcmRlcjogMTAxMFxuXHRcdFx0XHR9LFxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnVmlldzogUGFja2luZyBTbGlwJyApLFxuXHRcdFx0XHRcdGlkOiAncGFja2luZ19zbGlwJyxcblx0XHRcdFx0XHRhY3Rpb25fZ3JvdXA6ICd2aWV3Jyxcblx0XHRcdFx0XHR2dWVfaWNvbjogJ3R0aWNvbiB0dGljb24tdmlzaWJpbGl0eV9ibGFja18yNGRwJyxcblx0XHRcdFx0XHRzb3J0X29yZGVyOiAxMDEyLCAvL0FmdGVyIFZpZXcgaWNvbi5cblx0XHRcdFx0fSxcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGxhYmVsOiAkLmkxOG4uXyggJ1BheW1lbnQnICksXG5cdFx0XHRcdFx0aWQ6ICdwYXltZW50Jyxcblx0XHRcdFx0XHR2dWVfaWNvbjogJ3R0aWNvbiB0dGljb24tYXR0YWNoX21vbmV5X2JsYWNrXzI0ZHAnLFxuXHRcdFx0XHRcdG1lbnVfYWxpZ246ICdyaWdodCdcblx0XHRcdFx0fVxuXHRcdFx0XVxuXHRcdH07XG5cblx0XHRpZiAoICF0aGlzLnN1Yl92aWV3X21vZGUgKSB7XG5cdFx0XHRjb250ZXh0X21lbnVfbW9kZWxbJ2luY2x1ZGUnXS5wdXNoKCB7XG5cdFx0XHRcdGxhYmVsOiAkLmkxOG4uXyggJ0p1bXAgVG8nICksXG5cdFx0XHRcdGlkOiAnanVtcF90b19oZWFkZXInLFxuXHRcdFx0XHRtZW51X2FsaWduOiAncmlnaHQnLFxuXHRcdFx0XHRhY3Rpb25fZ3JvdXA6ICdqdW1wX3RvJyxcblx0XHRcdFx0YWN0aW9uX2dyb3VwX2hlYWRlcjogdHJ1ZSxcblx0XHRcdFx0cGVybWlzc2lvbl9yZXN1bHQ6IGZhbHNlLCAvLyB0byBoaWRlIGl0IGluIGxlZ2FjeSBjb250ZXh0IG1lbnUgYW5kIGF2b2lkIGVycm9ycyBpbiBsZWdhY3kgcGFyc2Vycy5cblx0XHRcdFx0c29ydF9vcmRlcjogOTA1MCxcblx0XHRcdH0gKTtcblxuXHRcdFx0Y29udGV4dF9tZW51X21vZGVsWydpbmNsdWRlJ10ucHVzaCgge1xuXHRcdFx0XHRsYWJlbDogJC5pMThuLl8oICdFZGl0IENsaWVudCcgKSxcblx0XHRcdFx0aWQ6ICdlZGl0X2NsaWVudCcsXG5cdFx0XHRcdG1lbnVfYWxpZ246ICdyaWdodCcsXG5cdFx0XHRcdGFjdGlvbl9ncm91cDogJ2p1bXBfdG8nLFxuXHRcdFx0XHRncm91cDogJ25hdmlnYXRpb24nLFxuXHRcdFx0XHRzb3J0X29yZGVyOiA5MDUwLFxuXHRcdFx0XHR9ICk7XG5cblx0XHRcdGNvbnRleHRfbWVudV9tb2RlbFsnaW5jbHVkZSddLnB1c2goIHtcblx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnQ2xpZW50cycgKSxcblx0XHRcdFx0aWQ6ICdjbGllbnQnLFxuXHRcdFx0XHRtZW51X2FsaWduOiAncmlnaHQnLFxuXHRcdFx0XHRhY3Rpb25fZ3JvdXA6ICdqdW1wX3RvJyxcblx0XHRcdFx0Z3JvdXA6ICduYXZpZ2F0aW9uJyxcblx0XHRcdFx0aWNvbjogJ2NsaWVudF9ncm91cHMtMzV4MzUucG5nJyxcblx0XHRcdFx0c29ydF9vcmRlcjogOTA1MCxcblx0XHRcdH0gKTtcblxuXHRcdFx0Y29udGV4dF9tZW51X21vZGVsWydpbmNsdWRlJ10ucHVzaCgge1xuXHRcdFx0XHRsYWJlbDogJC5pMThuLl8oICdDbGllbnQgQ29udGFjdHMnICksXG5cdFx0XHRcdGlkOiAnY2xpZW50X2NvbnRhY3QnLFxuXHRcdFx0XHRtZW51X2FsaWduOiAncmlnaHQnLFxuXHRcdFx0XHRhY3Rpb25fZ3JvdXA6ICdqdW1wX3RvJyxcblx0XHRcdFx0Z3JvdXA6ICduYXZpZ2F0aW9uJyxcblx0XHRcdFx0c29ydF9vcmRlcjogOTA1MCxcblx0XHRcdFx0fSApO1xuXG5cdFx0XHRjb250ZXh0X21lbnVfbW9kZWxbJ2luY2x1ZGUnXS5wdXNoKCB7XG5cdFx0XHRcdGxhYmVsOiAkLmkxOG4uXyggJ1RyYW5zYWN0aW9ucycgKSxcblx0XHRcdFx0aWQ6ICd0cmFuc2FjdGlvbicsXG5cdFx0XHRcdG1lbnVfYWxpZ246ICdyaWdodCcsXG5cdFx0XHRcdGFjdGlvbl9ncm91cDogJ2p1bXBfdG8nLFxuXHRcdFx0XHRncm91cDogJ25hdmlnYXRpb24nLFxuXHRcdFx0XHRzb3J0X29yZGVyOiA5MDUwLFxuXHRcdFx0XHR9ICk7XG5cblx0XHRcdGNvbnRleHRfbWVudV9tb2RlbFsnaW5jbHVkZSddLnB1c2goIHtcblx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnUGF5bWVudCBNZXRob2RzJyApLFxuXHRcdFx0XHRpZDogJ3BheW1lbnRfbWV0aG9kJyxcblx0XHRcdFx0bWVudV9hbGlnbjogJ3JpZ2h0Jyxcblx0XHRcdFx0YWN0aW9uX2dyb3VwOiAnanVtcF90bycsXG5cdFx0XHRcdGdyb3VwOiAnbmF2aWdhdGlvbicsXG5cdFx0XHRcdHNvcnRfb3JkZXI6IDkwNTAsXG5cdFx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gY29udGV4dF9tZW51X21vZGVsO1xuXHR9XG5cblx0c2V0Q3VzdG9tRGVmYXVsdE1lbnVJY29uKCBpZCwgY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoICkge1xuXHRcdHN3aXRjaCAoIGlkICkge1xuXHRcdFx0Y2FzZSAncGFja2luZ19zbGlwJzpcblx0XHRcdFx0dGhpcy5zZXREZWZhdWx0TWVudVBhY2tpbmdTbGlwSWNvbiggY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAncGF5bWVudCc6XG5cdFx0XHRcdHRoaXMuc2V0RGVmYXVsdE1lbnVQYXltZW50SWNvbiggY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnZWRpdF9jbGllbnQnOlxuXHRcdFx0XHR0aGlzLnNldERlZmF1bHRNZW51RWRpdENsaWVudEljb24oIGNvbnRleHRfYnRuLCBncmlkX3NlbGVjdGVkX2xlbmd0aCApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ2NsaWVudCc6XG5cdFx0XHRcdHRoaXMuc2V0RGVmYXVsdE1lbnVDbGllbnRJY29uKCBjb250ZXh0X2J0biwgZ3JpZF9zZWxlY3RlZF9sZW5ndGggKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdjbGllbnRfY29udGFjdCc6XG5cdFx0XHRcdHRoaXMuc2V0RGVmYXVsdE1lbnVDbGllbnRDb250YWN0SWNvbiggY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAndHJhbnNhY3Rpb24nOlxuXHRcdFx0XHR0aGlzLnNldERlZmF1bHRNZW51VHJhbnNhY3Rpb25JY29uKCBjb250ZXh0X2J0biwgZ3JpZF9zZWxlY3RlZF9sZW5ndGggKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdwYXltZW50X21ldGhvZCc6XG5cdFx0XHRcdHRoaXMuc2V0RGVmYXVsdE1lbnVQYXltZW50TWV0aG9kSWNvbiggY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXG5cdHNldEN1c3RvbUVkaXRNZW51SWNvbiggaWQsIGNvbnRleHRfYnRuICkge1xuXHRcdHN3aXRjaCAoIGlkICkge1xuXHRcdFx0Y2FzZSAncGFja2luZ19zbGlwJzpcblx0XHRcdFx0dGhpcy5zZXRFZGl0TWVudVBhY2tpbmdTbGlwSWNvbiggY29udGV4dF9idG4gKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdwYXltZW50Jzpcblx0XHRcdFx0dGhpcy5zZXRFZGl0TWVudVBheW1lbnRJY29uKCBjb250ZXh0X2J0biApO1xuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHRzZXRFZGl0TWVudVBhY2tpbmdTbGlwSWNvbiggY29udGV4dF9idG4sIHBJZCApIHtcblxuXHRcdGlmICggIXRoaXMuY3VycmVudF9lZGl0X3JlY29yZCB8fCAhdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmlkICkge1xuXHRcdFx0Q29udGV4dE1lbnVNYW5hZ2VyLmRpc2FibGVNZW51SXRlbSggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkLCBjb250ZXh0X2J0bi5pZCwgZmFsc2UgKTtcblx0XHR9XG5cdH1cblxuXHRzZXRFZGl0TWVudVBheW1lbnRJY29uKCBjb250ZXh0X2J0biwgcElkICkge1xuXHRcdGlmICggIXRoaXMuY3VycmVudF9lZGl0X3JlY29yZCB8fCAhdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmlkICkge1xuXHRcdFx0Q29udGV4dE1lbnVNYW5hZ2VyLmRpc2FibGVNZW51SXRlbSggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkLCBjb250ZXh0X2J0bi5pZCwgZmFsc2UgKTtcblx0XHR9XG5cdH1cblxuXHRzZXREZWZhdWx0TWVudVZpZXdJY29uKCBjb250ZXh0X2J0biwgZ3JpZF9zZWxlY3RlZF9sZW5ndGgsIHBJZCApIHtcblx0XHRpZiAoICF0aGlzLnZpZXdQZXJtaXNzaW9uVmFsaWRhdGUoIHBJZCApIHx8IHRoaXMuZWRpdF9vbmx5X21vZGUgKSB7XG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuaGlkZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApXG5cdFx0fVxuXG5cdFx0aWYgKCBncmlkX3NlbGVjdGVkX2xlbmd0aCA+IDAgJiYgdGhpcy52aWV3T3duZXJPckNoaWxkUGVybWlzc2lvblZhbGlkYXRlKCkgKSB7XG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuZGlzYWJsZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCB0cnVlICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIGZhbHNlICk7XG5cdFx0fVxuXHR9XG5cblx0c2V0RGVmYXVsdE1lbnVQYWNraW5nU2xpcEljb24oIGNvbnRleHRfYnRuLCBncmlkX3NlbGVjdGVkX2xlbmd0aCwgcElkICkge1xuXG5cdFx0aWYgKCBncmlkX3NlbGVjdGVkX2xlbmd0aCA+IDAgKSB7XG5cdFx0XHRDb250ZXh0TWVudU1hbmFnZXIuZGlzYWJsZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCB0cnVlICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIGZhbHNlICk7XG5cdFx0fVxuXHR9XG5cblx0c2V0RGVmYXVsdE1lbnVQYXltZW50SWNvbiggY29udGV4dF9idG4sIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoLCBwSWQgKSB7XG5cblx0XHRDb250ZXh0TWVudU1hbmFnZXIuZGlzYWJsZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCBmYWxzZSApO1xuXHRcdENvbnRleHRNZW51TWFuYWdlci5oaWRlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIGZhbHNlICk7XG5cdH1cblxuXHRzZXREZWZhdWx0TWVudUVkaXRDbGllbnRJY29uKCBjb250ZXh0X2J0biwgZ3JpZF9zZWxlY3RlZF9sZW5ndGgsIHBJZCApIHtcblx0XHRpZiAoIGdyaWRfc2VsZWN0ZWRfbGVuZ3RoID4gMCApIHtcblx0XHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIHRydWUgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Q29udGV4dE1lbnVNYW5hZ2VyLmRpc2FibGVNZW51SXRlbSggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkLCBjb250ZXh0X2J0bi5pZCwgZmFsc2UgKTtcblx0XHR9XG5cdH1cblxuXHRzZXREZWZhdWx0TWVudUNsaWVudEljb24oIGNvbnRleHRfYnRuLCBncmlkX3NlbGVjdGVkX2xlbmd0aCwgcElkICkge1xuXHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIHRydWUgKTtcblx0fVxuXG5cdHNldERlZmF1bHRNZW51Q2xpZW50Q29udGFjdEljb24oIGNvbnRleHRfYnRuLCBncmlkX3NlbGVjdGVkX2xlbmd0aCwgcElkICkge1xuXHRcdENvbnRleHRNZW51TWFuYWdlci5kaXNhYmxlTWVudUl0ZW0oIHRoaXMuZGV0ZXJtaW5lQ29udGV4dE1lbnVNb3VudEF0dHJpYnV0ZXMoKS5pZCwgY29udGV4dF9idG4uaWQsIHRydWUgKTtcblx0fVxuXG5cdHNldERlZmF1bHRNZW51VHJhbnNhY3Rpb25JY29uKCBjb250ZXh0X2J0biwgZ3JpZF9zZWxlY3RlZF9sZW5ndGgsIHBJZCApIHtcblx0XHRDb250ZXh0TWVudU1hbmFnZXIuZGlzYWJsZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCB0cnVlICk7XG5cdH1cblxuXHRzZXREZWZhdWx0TWVudVBheW1lbnRNZXRob2RJY29uKCBjb250ZXh0X2J0biwgZ3JpZF9zZWxlY3RlZF9sZW5ndGgsIHBJZCApIHtcblx0XHRDb250ZXh0TWVudU1hbmFnZXIuZGlzYWJsZU1lbnVJdGVtKCB0aGlzLmRldGVybWluZUNvbnRleHRNZW51TW91bnRBdHRyaWJ1dGVzKCkuaWQsIGNvbnRleHRfYnRuLmlkLCB0cnVlICk7XG5cdH1cblxuXHRnZXRGaWx0ZXJDb2x1bW5zRnJvbURpc3BsYXlDb2x1bW5zKCkge1xuXHRcdHZhciBjb2x1bW5fZmlsdGVyID0ge307XG5cdFx0Y29sdW1uX2ZpbHRlci5pc19vd25lciA9IHRydWU7XG5cdFx0Y29sdW1uX2ZpbHRlci5pZCA9IHRydWU7XG5cdFx0Y29sdW1uX2ZpbHRlci5pc19jaGlsZCA9IHRydWU7XG5cdFx0Y29sdW1uX2ZpbHRlci5pbl91c2UgPSB0cnVlO1xuXHRcdGNvbHVtbl9maWx0ZXIuZmlyc3RfbmFtZSA9IHRydWU7XG5cdFx0Y29sdW1uX2ZpbHRlci5sYXN0X25hbWUgPSB0cnVlO1xuXHRcdGNvbHVtbl9maWx0ZXIuY2xpZW50X2lkID0gdHJ1ZTtcblxuXHRcdC8vIEVycm9yOiBVbmFibGUgdG8gZ2V0IHByb3BlcnR5ICdnZXRHcmlkUGFyYW0nIG9mIHVuZGVmaW5lZCBvciBudWxsIHJlZmVyZW5jZVxuXHRcdHZhciBkaXNwbGF5X2NvbHVtbnMgPSBbXTtcblx0XHRpZiAoIHRoaXMuZ3JpZCApIHtcblx0XHRcdGRpc3BsYXlfY29sdW1ucyA9IHRoaXMuZ3JpZC5nZXRHcmlkUGFyYW0oICdjb2xNb2RlbCcgKTtcblx0XHR9XG5cblx0XHRpZiAoIGRpc3BsYXlfY29sdW1ucyApIHtcblx0XHRcdHZhciBsZW4gPSBkaXNwbGF5X2NvbHVtbnMubGVuZ3RoO1xuXG5cdFx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0dmFyIGNvbHVtbl9pbmZvID0gZGlzcGxheV9jb2x1bW5zW2ldO1xuXHRcdFx0XHRjb2x1bW5fZmlsdGVyW2NvbHVtbl9pbmZvLm5hbWVdID0gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gY29sdW1uX2ZpbHRlcjtcblx0fVxuXG5cdG9uQ3VzdG9tQ29udGV4dENsaWNrKCBpZCApIHtcblx0XHRzd2l0Y2ggKCBpZCApIHtcblx0XHRcdGNhc2UgJ2VkaXRfY2xpZW50Jzpcblx0XHRcdGNhc2UgJ2NsaWVudCc6XG5cdFx0XHRjYXNlICdjbGllbnRfY29udGFjdCc6XG5cdFx0XHRjYXNlICd0cmFuc2FjdGlvbic6XG5cdFx0XHRjYXNlICdwYXltZW50X21ldGhvZCc6XG5cdFx0XHRjYXNlICdwYXltZW50Jzpcblx0XHRcdGNhc2UgJ3ZpZXcnOlxuXHRcdFx0Y2FzZSAncGFja2luZ19zbGlwJzpcblx0XHRcdFx0dGhpcy5vbk5hdmlnYXRpb25DbGljayggaWQgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG5cblx0b25WaWV3Q2xpY2soKSB7XG5cdFx0cmV0dXJuIHRoaXMub25OYXZpZ2F0aW9uQ2xpY2soICd2aWV3JyApO1xuXHR9XG5cblx0b25OYXZpZ2F0aW9uQ2xpY2soIGljb25OYW1lICkge1xuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cdFx0dmFyIGdyaWRfc2VsZWN0ZWRfaWRfYXJyYXk7XG5cdFx0dmFyIGZpbHRlciA9IHsgZmlsdGVyX2RhdGE6IHt9IH07XG5cdFx0dmFyIGlkcyA9IFtdO1xuXHRcdHZhciBjbGllbnRfaWRzID0gW107XG5cdFx0dmFyIGludm9pY2VfaWQ7XG5cdFx0dmFyIGN1cnJlbmN5X2lkO1xuXHRcdGlmICggJHRoaXMuZWRpdF92aWV3ICkge1xuXHRcdFx0aWYgKCAkdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmNsaWVudF9pZCApIHtcblx0XHRcdFx0Y2xpZW50X2lkcy5wdXNoKCAkdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmNsaWVudF9pZCApO1xuXHRcdFx0fVxuXHRcdFx0Y3VycmVuY3lfaWQgPSAkdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmN1cnJlbmN5X2lkO1xuXHRcdFx0aWYgKCAkdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmlkICkge1xuXHRcdFx0XHRpbnZvaWNlX2lkID0gJHRoaXMuY3VycmVudF9lZGl0X3JlY29yZC5pZDtcblx0XHRcdFx0aWRzLnB1c2goICR0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQuaWQgKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0Z3JpZF9zZWxlY3RlZF9pZF9hcnJheSA9IHRoaXMuZ2V0R3JpZFNlbGVjdElkQXJyYXkoKTtcblx0XHRcdCQuZWFjaCggZ3JpZF9zZWxlY3RlZF9pZF9hcnJheSwgZnVuY3Rpb24oIGluZGV4LCB2YWx1ZSApIHtcblx0XHRcdFx0dmFyIGdyaWRfc2VsZWN0ZWRfcm93ID0gJHRoaXMuZ2V0UmVjb3JkRnJvbUdyaWRCeUlkKCB2YWx1ZSApO1xuXHRcdFx0XHRpZHMucHVzaCggZ3JpZF9zZWxlY3RlZF9yb3cuaWQgKTtcblx0XHRcdFx0Y2xpZW50X2lkcy5wdXNoKCBncmlkX3NlbGVjdGVkX3Jvdy5jbGllbnRfaWQgKTtcblx0XHRcdH0gKTtcblx0XHR9XG5cdFx0ZmlsdGVyLmZpbHRlcl9kYXRhLmNsaWVudF9pZCA9IGNsaWVudF9pZHM7XG5cdFx0dmFyIGFyZ3MgPSB7IGZpbHRlcl9kYXRhOiB7IGlkOiBpZHMgfSB9O1xuXHRcdHZhciBwb3N0X2RhdGE7XG5cdFx0c3dpdGNoICggaWNvbk5hbWUgKSB7XG5cdFx0XHRjYXNlICdlZGl0X2NsaWVudCc6XG5cdFx0XHRcdGlmICggY2xpZW50X2lkcy5sZW5ndGggPiAwICkge1xuXHRcdFx0XHRcdEluZGV4Vmlld0NvbnRyb2xsZXIub3BlbkVkaXRWaWV3KCB0aGlzLCAnQ2xpZW50JywgY2xpZW50X2lkc1swXSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAncGF5bWVudCc6XG5cdFx0XHRcdGlmICggaW52b2ljZV9pZCApIHtcblx0XHRcdFx0XHRJbmRleFZpZXdDb250cm9sbGVyLm9wZW5FZGl0VmlldyggdGhpcywgJ0ludm9pY2VUcmFuc2FjdGlvbicsIHtcblx0XHRcdFx0XHRcdHR5cGVfaWQ6IDIwLFxuXHRcdFx0XHRcdFx0aW52b2ljZV9pZDogaW52b2ljZV9pZCxcblx0XHRcdFx0XHRcdGNsaWVudF9pZDogY2xpZW50X2lkc1swXSxcblx0XHRcdFx0XHRcdGN1cnJlbmN5X2lkOiBjdXJyZW5jeV9pZCxcblx0XHRcdFx0XHRcdGlzX2FkZDogdHJ1ZSxcblx0XHRcdFx0XHRcdG93aW5nX2Ftb3VudDogdGhpcy5vd2luZ19hbW91bnRcblx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdjbGllbnQnOlxuXHRcdFx0XHRmaWx0ZXIuZmlsdGVyX2RhdGEuaWQgPSBmaWx0ZXIuZmlsdGVyX2RhdGEuY2xpZW50X2lkO1xuXHRcdFx0XHRkZWxldGUgZmlsdGVyLmZpbHRlcl9kYXRhLmNsaWVudF9pZDtcblx0XHRcdFx0R2xvYmFsLmFkZFZpZXdUYWIoICR0aGlzLnZpZXdJZCwgJC5pMThuLl8oICdJbnZvaWNlcycgKSwgd2luZG93LmxvY2F0aW9uLmhyZWYgKTtcblx0XHRcdFx0SW5kZXhWaWV3Q29udHJvbGxlci5nb1RvVmlldyggJ0NsaWVudCcsIGZpbHRlciApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGNhc2UgJ2NsaWVudF9jb250YWN0Jzpcblx0XHRcdFx0R2xvYmFsLmFkZFZpZXdUYWIoICR0aGlzLnZpZXdJZCwgJC5pMThuLl8oICdJbnZvaWNlcycgKSwgd2luZG93LmxvY2F0aW9uLmhyZWYgKTtcblx0XHRcdFx0SW5kZXhWaWV3Q29udHJvbGxlci5nb1RvVmlldyggJ0NsaWVudENvbnRhY3QnLCBmaWx0ZXIgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICd0cmFuc2FjdGlvbic6XG5cdFx0XHRcdEdsb2JhbC5hZGRWaWV3VGFiKCAkdGhpcy52aWV3SWQsICQuaTE4bi5fKCAnSW52b2ljZXMnICksIHdpbmRvdy5sb2NhdGlvbi5ocmVmICk7XG5cdFx0XHRcdEluZGV4Vmlld0NvbnRyb2xsZXIuZ29Ub1ZpZXcoICdJbnZvaWNlVHJhbnNhY3Rpb24nLCBmaWx0ZXIgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdwYXltZW50X21ldGhvZCc6XG5cdFx0XHRcdEdsb2JhbC5hZGRWaWV3VGFiKCAkdGhpcy52aWV3SWQsICQuaTE4bi5fKCAnSW52b2ljZXMnICksIHdpbmRvdy5sb2NhdGlvbi5ocmVmICk7XG5cdFx0XHRcdEluZGV4Vmlld0NvbnRyb2xsZXIuZ29Ub1ZpZXcoICdDbGllbnRQYXltZW50JywgZmlsdGVyICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAndmlldyc6XG5cdFx0XHRcdHBvc3RfZGF0YSA9IHsgMDogYXJncywgMTogZmFsc2UsIDI6ICdwZGYnIH07XG5cdFx0XHRcdHRoaXMuZG9Gb3JtSUZyYW1lQ2FsbCggcG9zdF9kYXRhICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAncGFja2luZ19zbGlwJzpcblx0XHRcdFx0cG9zdF9kYXRhID0geyAwOiBhcmdzLCAxOiBmYWxzZSwgMjogJ3BkZl9wYWNraW5nX3NsaXAnIH07XG5cdFx0XHRcdHRoaXMuZG9Gb3JtSUZyYW1lQ2FsbCggcG9zdF9kYXRhICk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXG5cdGRvRm9ybUlGcmFtZUNhbGwoIHBvc3REYXRhICkge1xuXHRcdEdsb2JhbC5BUElGaWxlRG93bmxvYWQoIHRoaXMuYXBpLmNsYXNzTmFtZSwgJ2dldCcgKyB0aGlzLmFwaS5rZXlfbmFtZSwgcG9zdERhdGEgKTtcblx0fVxuXG5cdGluaXRPcHRpb25zKCkge1xuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cblx0XHR0aGlzLmluaXREcm9wRG93bk9wdGlvbiggJ3N0YXR1cycgKTtcblx0XHR0aGlzLmNsaWVudF9ncm91cF9hcGkuZ2V0Q2xpZW50R3JvdXAoICcnLCBmYWxzZSwgZmFsc2UsIHtcblx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzICkge1xuXHRcdFx0XHRyZXMgPSByZXMuZ2V0UmVzdWx0KCk7XG5cdFx0XHRcdHJlcyA9IEdsb2JhbC5idWlsZFRyZWVSZWNvcmQoIHJlcyApO1xuXHRcdFx0XHRpZiAoICEkdGhpcy5lZGl0X29ubHlfbW9kZSAmJiAhJHRoaXMuc3ViX3ZpZXdfbW9kZSApIHtcblx0XHRcdFx0XHQkdGhpcy5iYXNpY19zZWFyY2hfZmllbGRfdWlfZGljWydjbGllbnRfZ3JvdXBfaWQnXS5zZXRTb3VyY2VEYXRhKCByZXMgKTtcblx0XHRcdFx0XHQkdGhpcy5hZHZfc2VhcmNoX2ZpZWxkX3VpX2RpY1snY2xpZW50X2dyb3VwX2lkJ10uc2V0U291cmNlRGF0YSggcmVzICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQkdGhpcy5jbGllbnRfZ3JvdXBfYXJyYXkgPSByZXM7XG5cblx0XHRcdH1cblx0XHR9ICk7XG5cdH1cblxuXHRidWlsZEVkaXRWaWV3VUkoKSB7XG5cblx0XHRzdXBlci5idWlsZEVkaXRWaWV3VUkoKTtcblxuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cblx0XHR0aGlzLmVkaXRfdmlldy5jaGlsZHJlbigpLmVxKCAwICkuY3NzKCAnbWluLXdpZHRoJywgMTA1MCApO1xuXG5cdFx0dmFyIHRhYl9tb2RlbCA9IHtcblx0XHRcdCd0YWJfaW52b2ljZSc6IHtcblx0XHRcdFx0J2xhYmVsJzogJC5pMThuLl8oICdJbnZvaWNlJyApLFxuXHRcdFx0XHQnaHRtbF90ZW1wbGF0ZSc6IHRoaXMuZ2V0SW52b2ljZVRhYkh0bWwoKSxcblx0XHRcdFx0J2lzX211bHRpX2NvbHVtbic6IHRydWVcblx0XHRcdH0sXG5cdFx0XHQndGFiX2NsaWVudF9jb250YWN0cyc6IHtcblx0XHRcdFx0J2xhYmVsJzogJC5pMThuLl8oICdDbGllbnQgQ29udGFjdHMnICksXG5cdFx0XHRcdCdpbml0X2NhbGxiYWNrJzogJ2luaXRTdWJDbGllbnRDb250YWN0VmlldycsXG5cdFx0XHRcdCdkaXNwbGF5X29uX21hc3NfZWRpdCc6IGZhbHNlXG5cdFx0XHR9LFxuXHRcdFx0J3RhYl9wYXltZW50X21ldGhvZHMnOiB7XG5cdFx0XHRcdCdsYWJlbCc6ICQuaTE4bi5fKCAnUGF5bWVudCBNZXRob2RzJyApLFxuXHRcdFx0XHQnaW5pdF9jYWxsYmFjayc6ICdpbml0U3ViQ2xpZW50UGF5bWVudFZpZXcnLFxuXHRcdFx0XHQnZGlzcGxheV9vbl9tYXNzX2VkaXQnOiBmYWxzZVxuXHRcdFx0fSxcblx0XHRcdCd0YWJfdHJhbnNhY3Rpb25zJzoge1xuXHRcdFx0XHQnbGFiZWwnOiAkLmkxOG4uXyggJ1RyYW5zYWN0aW9ucycgKSxcblx0XHRcdFx0J2luaXRfY2FsbGJhY2snOiAnaW5pdFN1YlRyYW5zYWN0aW9uVmlldycsXG5cdFx0XHRcdCdkaXNwbGF5X29uX21hc3NfZWRpdCc6IGZhbHNlXG5cdFx0XHR9LFxuXHRcdFx0J3RhYl9hdWRpdCc6IHRydWUsXG5cdFx0fTtcblx0XHR0aGlzLnNldFRhYk1vZGVsKCB0YWJfbW9kZWwgKTtcblxuXHRcdHRoaXMubmF2aWdhdGlvbi5BQ29tYm9Cb3goIHtcblx0XHRcdGFwaV9jbGFzczogVFRBUEkuQVBJSW52b2ljZSxcblx0XHRcdGlkOiB0aGlzLnNjcmlwdF9uYW1lICsgJ19uYXZpZ2F0aW9uJyxcblx0XHRcdGFsbG93X211bHRpcGxlX3NlbGVjdGlvbjogZmFsc2UsXG5cdFx0XHRsYXlvdXRfbmFtZTogJ2dsb2JhbF9pbnZvaWNlJyxcblx0XHRcdG5hdmlnYXRpb25fbW9kZTogdHJ1ZSxcblx0XHRcdHNob3dfc2VhcmNoX2lucHV0czogdHJ1ZVxuXHRcdH0gKTtcblxuXHRcdHRoaXMuc2V0TmF2aWdhdGlvbigpO1xuXG5cdFx0Ly9UYWIgMCBzdGFydFxuXG5cdFx0dmFyIHRhYl9pbnZvaWNlID0gdGhpcy5lZGl0X3ZpZXdfdGFiLmZpbmQoICcjdGFiX2ludm9pY2UnICk7XG5cblx0XHR2YXIgdGFiX2ludm9pY2VfY29sdW1uMSA9IHRhYl9pbnZvaWNlLmZpbmQoICcuZmlyc3QtY29sdW1uJyApO1xuXHRcdHZhciB0YWJfaW52b2ljZV9jb2x1bW4yID0gdGFiX2ludm9pY2UuZmluZCggJy5zZWNvbmQtY29sdW1uJyApO1xuXHRcdHZhciB0YWJfaW52b2ljZV9jb2x1bW4zID0gdGFiX2ludm9pY2UuZmluZCggJy50aGlyZC1jb2x1bW4nICk7XG5cblx0XHR0aGlzLmVkaXRfdmlld190YWJzWzBdID0gW107XG5cblx0XHR0aGlzLmVkaXRfdmlld190YWJzWzBdLnB1c2goIHRhYl9pbnZvaWNlX2NvbHVtbjEgKTtcblx0XHR0aGlzLmVkaXRfdmlld190YWJzWzBdLnB1c2goIHRhYl9pbnZvaWNlX2NvbHVtbjIgKTtcblx0XHR0aGlzLmVkaXRfdmlld190YWJzWzBdLnB1c2goIHRhYl9pbnZvaWNlX2NvbHVtbjMgKTtcblxuXHRcdHZhciBmb3JtX2l0ZW1faW5wdXQ7XG5cdFx0dmFyIHdpZGdldENvbnRhaW5lcjtcblx0XHR2YXIgbGFiZWw7XG5cblx0XHQvLyBDbGllbnRcblx0XHRmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLkFXRVNPTUVfQk9YICk7XG5cblx0XHRmb3JtX2l0ZW1faW5wdXQuQUNvbWJvQm94KCB7XG5cdFx0XHRhcGlfY2xhc3M6IFRUQVBJLkFQSUNsaWVudCxcblx0XHRcdGFsbG93X211bHRpcGxlX3NlbGVjdGlvbjogZmFsc2UsXG5cdFx0XHRsYXlvdXRfbmFtZTogJ2dsb2JhbF9jbGllbnQnLFxuXHRcdFx0c2hvd19zZWFyY2hfaW5wdXRzOiB0cnVlLFxuXHRcdFx0c2V0X2VtcHR5OiB0cnVlLFxuXHRcdFx0ZmllbGQ6ICdjbGllbnRfaWQnXG5cdFx0fSApO1xuXHRcdHRoaXMuYWRkRWRpdEZpZWxkVG9Db2x1bW4oICQuaTE4bi5fKCAnQ2xpZW50JyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9pbnZvaWNlX2NvbHVtbjEsICcnLCBudWxsLCB0cnVlICk7XG5cblx0XHQvLyBDbGllbnRcblx0XHRmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLlRFWFQgKTtcblx0XHRmb3JtX2l0ZW1faW5wdXQuVFRleHQoIHsgZmllbGQ6ICdjbGllbnQnIH0gKTtcblx0XHR0aGlzLmFkZEVkaXRGaWVsZFRvQ29sdW1uKCAkLmkxOG4uXyggJ0NsaWVudCcgKSwgZm9ybV9pdGVtX2lucHV0LCB0YWJfaW52b2ljZV9jb2x1bW4xLCAnJywgbnVsbCwgdHJ1ZSApO1xuXG5cdFx0Ly8gU3RhdHVzXG5cdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5DT01CT19CT1ggKTtcblx0XHRmb3JtX2l0ZW1faW5wdXQuVENvbWJvQm94KCB7IGZpZWxkOiAnc3RhdHVzX2lkJyB9ICk7XG5cdFx0Zm9ybV9pdGVtX2lucHV0LnNldFNvdXJjZURhdGEoICR0aGlzLnN0YXR1c19hcnJheSApO1xuXHRcdHRoaXMuYWRkRWRpdEZpZWxkVG9Db2x1bW4oICQuaTE4bi5fKCAnU3RhdHVzJyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9pbnZvaWNlX2NvbHVtbjEgKTtcblxuXHRcdC8vIEJpbGxpbmcgQ29udGFjdFxuXHRcdGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuQVdFU09NRV9CT1ggKTtcblxuXHRcdGZvcm1faXRlbV9pbnB1dC5BQ29tYm9Cb3goIHtcblx0XHRcdGFwaV9jbGFzczogVFRBUEkuQVBJQ2xpZW50Q29udGFjdCxcblx0XHRcdGFsbG93X211bHRpcGxlX3NlbGVjdGlvbjogZmFsc2UsXG5cdFx0XHRsYXlvdXRfbmFtZTogJ2dsb2JhbF9jbGllbnRfY29udGFjdCcsXG5cdFx0XHRzaG93X3NlYXJjaF9pbnB1dHM6IHRydWUsXG5cdFx0XHRzZXRfZW1wdHk6IHRydWUsXG5cdFx0XHRmaWVsZDogJ2JpbGxpbmdfY29udGFjdF9pZCdcblx0XHR9ICk7XG5cdFx0dGhpcy5hZGRFZGl0RmllbGRUb0NvbHVtbiggJC5pMThuLl8oICdCaWxsaW5nIENvbnRhY3QnICksIGZvcm1faXRlbV9pbnB1dCwgdGFiX2ludm9pY2VfY29sdW1uMSApO1xuXG5cdFx0Ly8gU2hpcHBpbmcgQ29udGFjdFxuXHRcdGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuQVdFU09NRV9CT1ggKTtcblxuXHRcdGZvcm1faXRlbV9pbnB1dC5BQ29tYm9Cb3goIHtcblx0XHRcdGFwaV9jbGFzczogVFRBUEkuQVBJQ2xpZW50Q29udGFjdCxcblx0XHRcdGFsbG93X211bHRpcGxlX3NlbGVjdGlvbjogZmFsc2UsXG5cdFx0XHRsYXlvdXRfbmFtZTogJ2dsb2JhbF9jbGllbnRfY29udGFjdCcsXG5cdFx0XHRzaG93X3NlYXJjaF9pbnB1dHM6IHRydWUsXG5cdFx0XHRzZXRfZW1wdHk6IHRydWUsXG5cdFx0XHRmaWVsZDogJ3NoaXBwaW5nX2NvbnRhY3RfaWQnXG5cdFx0fSApO1xuXHRcdHRoaXMuYWRkRWRpdEZpZWxkVG9Db2x1bW4oICQuaTE4bi5fKCAnU2hpcHBpbmcgQ29udGFjdCcgKSwgZm9ybV9pdGVtX2lucHV0LCB0YWJfaW52b2ljZV9jb2x1bW4xICk7XG5cblx0XHQvLyBPdGhlciBDb250YWN0XG5cdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5BV0VTT01FX0JPWCApO1xuXG5cdFx0Zm9ybV9pdGVtX2lucHV0LkFDb21ib0JveCgge1xuXHRcdFx0YXBpX2NsYXNzOiBUVEFQSS5BUElDbGllbnRDb250YWN0LFxuXHRcdFx0YWxsb3dfbXVsdGlwbGVfc2VsZWN0aW9uOiBmYWxzZSxcblx0XHRcdGxheW91dF9uYW1lOiAnZ2xvYmFsX2NsaWVudF9jb250YWN0Jyxcblx0XHRcdHNob3dfc2VhcmNoX2lucHV0czogdHJ1ZSxcblx0XHRcdHNldF9lbXB0eTogdHJ1ZSxcblx0XHRcdGZpZWxkOiAnb3RoZXJfY29udGFjdF9pZCdcblx0XHR9ICk7XG5cdFx0dGhpcy5hZGRFZGl0RmllbGRUb0NvbHVtbiggJC5pMThuLl8oICdPdGhlciBDb250YWN0JyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9pbnZvaWNlX2NvbHVtbjEgKTtcblxuXHRcdC8vIEN1cnJlbmN5XG5cdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5BV0VTT01FX0JPWCApO1xuXG5cdFx0Zm9ybV9pdGVtX2lucHV0LkFDb21ib0JveCgge1xuXHRcdFx0YXBpX2NsYXNzOiBUVEFQSS5BUElDdXJyZW5jeSxcblx0XHRcdGFsbG93X211bHRpcGxlX3NlbGVjdGlvbjogZmFsc2UsXG5cdFx0XHRsYXlvdXRfbmFtZTogJ2dsb2JhbF9jdXJyZW5jeScsXG5cdFx0XHRzaG93X3NlYXJjaF9pbnB1dHM6IHRydWUsXG5cdFx0XHRmaWVsZDogJ2N1cnJlbmN5X2lkJ1xuXHRcdH0gKTtcblx0XHR0aGlzLmFkZEVkaXRGaWVsZFRvQ29sdW1uKCAkLmkxOG4uXyggJ0N1cnJlbmN5JyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9pbnZvaWNlX2NvbHVtbjEgKTtcblxuXHRcdC8vIFBPIE51bWJlclxuXHRcdGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuVEVYVF9JTlBVVCApO1xuXG5cdFx0Zm9ybV9pdGVtX2lucHV0LlRUZXh0SW5wdXQoIHsgZmllbGQ6ICdwb19udW1iZXInLCB3aWR0aDogMTAwIH0gKTtcblx0XHR0aGlzLmFkZEVkaXRGaWVsZFRvQ29sdW1uKCAkLmkxOG4uXyggJ1BPIE51bWJlcicgKSwgZm9ybV9pdGVtX2lucHV0LCB0YWJfaW52b2ljZV9jb2x1bW4xICk7XG5cblx0XHQvLyBUYWdzXG5cdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5UQUdfSU5QVVQgKTtcblxuXHRcdGZvcm1faXRlbV9pbnB1dC5UVGFnSW5wdXQoIHsgZmllbGQ6ICd0YWcnLCBvYmplY3RfdHlwZV9pZDogOTEwIH0gKTtcblx0XHR0aGlzLmFkZEVkaXRGaWVsZFRvQ29sdW1uKCAkLmkxOG4uXyggJ1RhZ3MnICksIGZvcm1faXRlbV9pbnB1dCwgdGFiX2ludm9pY2VfY29sdW1uMSwgJycsIG51bGwsIG51bGwsIHRydWUgKTtcblxuXHRcdC8vIEludm9pY2UgI1xuXHRcdGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuVEVYVCApO1xuXHRcdGZvcm1faXRlbV9pbnB1dC5UVGV4dCggeyBmaWVsZDogJ2ludm9pY2VfbnVtYmVyJyB9ICk7XG5cdFx0dGhpcy5hZGRFZGl0RmllbGRUb0NvbHVtbiggJC5pMThuLl8oICdJbnZvaWNlICMnICksIGZvcm1faXRlbV9pbnB1dCwgdGFiX2ludm9pY2VfY29sdW1uMiwgJycgKTtcblxuXHRcdC8vIEludm9pY2UgRGF0ZVxuXHRcdGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuREFURV9QSUNLRVIgKTtcblxuXHRcdGZvcm1faXRlbV9pbnB1dC5URGF0ZVBpY2tlciggeyBmaWVsZDogJ2ludm9pY2VfZGF0ZScgfSApO1xuXHRcdHRoaXMuYWRkRWRpdEZpZWxkVG9Db2x1bW4oICQuaTE4bi5fKCAnSW52b2ljZSBEYXRlJyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9pbnZvaWNlX2NvbHVtbjIgKTtcblxuXHRcdC8vIE9yZGVyIERhdGVcblx0XHRmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLkRBVEVfUElDS0VSICk7XG5cblx0XHRmb3JtX2l0ZW1faW5wdXQuVERhdGVQaWNrZXIoIHsgZmllbGQ6ICdvcmRlcl9kYXRlJyB9ICk7XG5cdFx0dGhpcy5hZGRFZGl0RmllbGRUb0NvbHVtbiggJC5pMThuLl8oICdPcmRlciBEYXRlJyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9pbnZvaWNlX2NvbHVtbjIgKTtcblxuXHRcdC8vIFBheW1lbnQgUmVxdWlyZWRcblx0XHRmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLkRBVEVfUElDS0VSICk7XG5cblx0XHRmb3JtX2l0ZW1faW5wdXQuVERhdGVQaWNrZXIoIHsgZmllbGQ6ICdyZXF1aXJlZF9kYXRlJyB9ICk7XG5cdFx0dGhpcy5hZGRFZGl0RmllbGRUb0NvbHVtbiggJC5pMThuLl8oICdQYXltZW50IFJlcXVpcmVkJyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9pbnZvaWNlX2NvbHVtbjIgKTtcblxuXHRcdC8vIFNoaXBwZWQgRGF0ZVxuXHRcdGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuREFURV9QSUNLRVIgKTtcblxuXHRcdGZvcm1faXRlbV9pbnB1dC5URGF0ZVBpY2tlciggeyBmaWVsZDogJ3NoaXBwZWRfZGF0ZScgfSApO1xuXHRcdHRoaXMuYWRkRWRpdEZpZWxkVG9Db2x1bW4oICQuaTE4bi5fKCAnU2hpcHBlZCBEYXRlJyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9pbnZvaWNlX2NvbHVtbjIgKTtcblxuXHRcdC8vIFNhbGVzIFJlcFxuXHRcdGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuQVdFU09NRV9CT1ggKTtcblxuXHRcdGZvcm1faXRlbV9pbnB1dC5BQ29tYm9Cb3goIHtcblx0XHRcdGFwaV9jbGFzczogVFRBUEkuQVBJVXNlcixcblx0XHRcdGFsbG93X211bHRpcGxlX3NlbGVjdGlvbjogZmFsc2UsXG5cdFx0XHRsYXlvdXRfbmFtZTogJ2dsb2JhbF91c2VyJyxcblx0XHRcdHNob3dfc2VhcmNoX2lucHV0czogdHJ1ZSxcblx0XHRcdHNldF9lbXB0eTogdHJ1ZSxcblx0XHRcdGZpZWxkOiAnc2FsZXNfY29udGFjdF9pZCdcblx0XHR9ICk7XG5cdFx0dGhpcy5hZGRFZGl0RmllbGRUb0NvbHVtbiggJC5pMThuLl8oICdTYWxlcyBSZXAnICksIGZvcm1faXRlbV9pbnB1dCwgdGFiX2ludm9pY2VfY29sdW1uMiApO1xuXG5cdFx0Ly8gVHJhY2tpbmcgTnVtYmVyXG5cdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5URVhUX0lOUFVUICk7XG5cblx0XHRmb3JtX2l0ZW1faW5wdXQuVFRleHRJbnB1dCggeyBmaWVsZDogJ3RyYWNraW5nX251bWJlcicgfSApO1xuXHRcdHRoaXMuYWRkRWRpdEZpZWxkVG9Db2x1bW4oICQuaTE4bi5fKCAnVHJhY2tpbmcgTnVtYmVyJyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9pbnZvaWNlX2NvbHVtbjIgKTtcblxuXHRcdC8vIFNoaXBwaW5nIFBvbGljeVxuXHRcdGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuQ09NQk9fQk9YICk7XG5cdFx0Zm9ybV9pdGVtX2lucHV0LlRDb21ib0JveCggeyBmaWVsZDogJ2NvbWJpbmVkX3NoaXBwaW5nX3BvbGljeV9pZCcgfSApO1xuXHRcdHRoaXMuYWRkRWRpdEZpZWxkVG9Db2x1bW4oICQuaTE4bi5fKCAnU2hpcHBpbmcgUG9saWN5JyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9pbnZvaWNlX2NvbHVtbjIsICcnICk7XG5cblx0XHQvL0luc2lkZSBlZGl0b3JcblxuXHRcdHZhciBpbnNpZGVfZWRpdG9yX2RpdiA9IHRhYl9pbnZvaWNlLmZpbmQoICcuaW5zaWRlLWVkaXRvci1kaXYnICk7XG5cblx0XHR2YXIgYXJncyA9IHtcblx0XHRcdHByb2R1Y3Q6ICQuaTE4bi5fKCAnUHJvZHVjdCcgKSxcblx0XHRcdGRlc2NyaXB0aW9uOiAkLmkxOG4uXyggJ0Rlc2NyaXB0aW9uJyApLFxuXHRcdFx0cXR5OiAkLmkxOG4uXyggJ1FUWScgKSxcblx0XHRcdHByaWNlOiAkLmkxOG4uXyggJ1ByaWNlJyApLFxuXHRcdFx0cHJvcmF0ZTogJC5pMThuLl8oICdQcm9SYXRlJyApLFxuXHRcdFx0dG90YWw6ICQuaTE4bi5fKCAnVG90YWwnIClcblx0XHR9O1xuXG5cdFx0dGhpcy5lZGl0b3IgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLklOU0lERV9FRElUT1IgKTtcblxuXHRcdHRoaXMuZWRpdG9yLkluc2lkZUVkaXRvcigge1xuXHRcdFx0YWRkUm93OiB0aGlzLmluc2lkZUVkaXRvckFkZFJvdyxcblx0XHRcdHJlbW92ZVJvdzogdGhpcy5pbnNpZGVFZGl0b3JSZW1vdmVSb3csXG5cdFx0XHRnZXRWYWx1ZTogdGhpcy5pbnNpZGVFZGl0b3JHZXRWYWx1ZSxcblx0XHRcdHNldFZhbHVlOiB0aGlzLmluc2lkZUVkaXRvclNldFZhbHVlLFxuXHRcdFx0cGFyZW50X2NvbnRyb2xsZXI6IHRoaXMsXG5cdFx0XHRhcGk6IHRoaXMudHJhbnNhY3Rpb25fYXBpLFxuXHRcdFx0cmVuZGVyOiBnZXRSZW5kZXIoKSxcblx0XHRcdHJlbmRlcl9hcmdzOiBhcmdzLFxuXHRcdFx0cmVuZGVyX2lubGluZV9odG1sOiB0cnVlLFxuXHRcdFx0cm93X3JlbmRlcjogZ2V0Um93UmVuZGVyKCksXG5cblx0XHR9ICk7XG5cblx0XHRmdW5jdGlvbiBnZXRSZW5kZXIoKSB7XG5cdFx0XHRyZXR1cm4gYFxuXHRcdFx0PHRhYmxlIGNsYXNzPVwiaW5zaWRlLWVkaXRvci1yZW5kZXJcIj5cblx0XHRcdFx0PHRyIGNsYXNzPVwidGl0bGVcIiBzdHlsZT1cImZvbnQtd2VpZ2h0OiBib2xkO1wiPlxuXHRcdFx0XHRcdDx0ZCBzdHlsZT1cIndpZHRoOiAyMDBweFwiPjwlPSBwcm9kdWN0ICU+PC90ZD5cblx0XHRcdFx0XHQ8dGQgc3R5bGU9XCJ3aWR0aDogNDAwcHhcIj48JT0gZGVzY3JpcHRpb24gJT48L3RkPlxuXHRcdFx0XHRcdDx0ZCBzdHlsZT1cIndpZHRoOiA1MHB4XCI+PCU9IHF0eSAlPjwvdGQ+XG5cdFx0XHRcdFx0PHRkIHN0eWxlPVwid2lkdGg6IDUwcHhcIj48JT0gcHJpY2UgJT48L3RkPlxuXHRcdFx0XHRcdDx0ZCBzdHlsZT1cIndpZHRoOiAxNDVweFwiPjwlPSBwcm9yYXRlICU+PC90ZD5cblx0XHRcdFx0XHQ8dGQgc3R5bGU9XCJ3aWR0aDogMTAwcHhcIj48JT0gdG90YWwgJT48L3RkPlxuXHRcdFx0XHQ8L3RyPlxuXHRcdFx0PC90YWJsZT5gO1xuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGdldFJvd1JlbmRlcigpIHtcblx0XHRcdHJldHVybiBgXG5cdFx0XHQ8dHIgY2xhc3M9XCJpbnNpZGUtZWRpdG9yLXJvdyBkYXRhLXJvd1wiPlxuXHRcdFx0XHQ8dGQgY2xhc3M9XCJcIj48L3RkPlxuXHRcdFx0XHQ8dGQgY2xhc3M9XCJcIj48L3RkPlxuXHRcdFx0XHQ8dGQgY2xhc3M9XCJcIj48L3RkPlxuXHRcdFx0XHQ8dGQgY2xhc3M9XCJcIj48L3RkPlxuXHRcdFx0XHQ8dGQgY2xhc3M9XCJcIj48L3RkPlxuXHRcdFx0XHQ8dGQgY2xhc3M9XCJcIj48L3RkPlxuXHRcdFx0XHQ8dGQgY2xhc3M9XCJjZWxsIGNvbnRyb2wtaWNvblwiPlxuXHRcdFx0XHRcdDxidXR0b24gY2xhc3M9XCJwbHVzLWljb25cIiBvbmNsaWNrPVwiXCI+PC9idXR0b24+XG5cdFx0XHRcdDwvdGQ+XG5cdFx0XHRcdDx0ZCBjbGFzcz1cImNlbGwgY29udHJvbC1pY29uXCI+XG5cdFx0XHRcdFx0PGJ1dHRvbiBjbGFzcz1cIm1pbnVzLWljb24gXCIgb25jbGljaz1cIlwiPjwvYnV0dG9uPlxuXHRcdFx0XHQ8L3RkPlxuXHRcdFx0PC90cj5gO1xuXHRcdH1cblxuXHRcdGluc2lkZV9lZGl0b3JfZGl2LmFwcGVuZCggdGhpcy5lZGl0b3IgKTtcblxuXHRcdC8vIE5vdGUocHJpdmF0ZSlcblx0XHRmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLlRFWFRfQVJFQSApO1xuXG5cdFx0Zm9ybV9pdGVtX2lucHV0LlRUZXh0QXJlYSggeyBmaWVsZDogJ3ByaXZhdGVfbm90ZScsIHdpZHRoOiA4MDAsIGhlaWdodDogNTAgfSApO1xuXG5cdFx0dGhpcy5hZGRFZGl0RmllbGRUb0NvbHVtbiggJC5pMThuLl8oICdOb3RlKHByaXZhdGUpJyApLCBmb3JtX2l0ZW1faW5wdXQsIHRhYl9pbnZvaWNlX2NvbHVtbjMsICcnLCBudWxsLCBudWxsLCB0cnVlICk7XG5cblx0XHQvLyBOb3RlKHB1YmxpYylcblx0XHRmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLlRFWFRfQVJFQSApO1xuXG5cdFx0Zm9ybV9pdGVtX2lucHV0LlRUZXh0QXJlYSggeyBmaWVsZDogJ3B1YmxpY19ub3RlJywgd2lkdGg6IDUwMCwgaGVpZ2h0OiA1MCB9ICk7XG5cblx0XHR0aGlzLmFkZEVkaXRGaWVsZFRvQ29sdW1uKCAkLmkxOG4uXyggJ05vdGUocHVibGljKScgKSwgZm9ybV9pdGVtX2lucHV0LCB0YWJfaW52b2ljZV9jb2x1bW4zLCAnJywgbnVsbCwgbnVsbCwgdHJ1ZSApO1xuXG5cdFx0Ly8gRW1haWwgSW52b2ljZSBUbyBDb250YWN0KHMpXG5cdFx0d2lkZ2V0Q29udGFpbmVyID0gJCggJzxkaXYgY2xhc3M9XFwnd2lkZ2V0LWgtYm94XFwnPjwvZGl2PicgKTtcblx0XHR2YXIgZW1haWxfaW52b2ljZSA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuQ0hFQ0tCT1ggKTtcblx0XHRlbWFpbF9pbnZvaWNlLlRDaGVja2JveCggeyBmaWVsZDogJ2VtYWlsX2ludm9pY2UnIH0gKTtcblx0XHR3aWRnZXRDb250YWluZXIuYXBwZW5kKCBlbWFpbF9pbnZvaWNlICk7XG5cdFx0bGFiZWwgPSAkKCAnPHNwYW4gY2xhc3M9XFwnd2lkZ2V0LXJpZ2h0LWxhYmVsXFwnPiAnICsgJC5pMThuLl8oICdDQycgKSArICc8L3NwYW4+JyApO1xuXHRcdHdpZGdldENvbnRhaW5lci5hcHBlbmQoIGxhYmVsICk7XG5cdFx0dmFyIGVtYWlsX2NjID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5URVhUX0lOUFVUICk7XG5cdFx0ZW1haWxfY2MuVFRleHRJbnB1dCggeyBmaWVsZDogJ2VtYWlsX290aGVyX2NjJywgd2lkdGg6IDIwMCB9ICk7XG5cdFx0d2lkZ2V0Q29udGFpbmVyLmFwcGVuZCggZW1haWxfY2MgKTtcblx0XHR0aGlzLmFkZEVkaXRGaWVsZFRvQ29sdW1uKCAkLmkxOG4uXyggJ0VtYWlsIEludm9pY2UgVG8gQ29udGFjdChzKScgKSwgW2VtYWlsX2ludm9pY2UsIGVtYWlsX2NjXSwgdGFiX2ludm9pY2VfY29sdW1uMywgJycsIHdpZGdldENvbnRhaW5lciApO1xuXHR9XG5cblx0YnVpbGRTZWFyY2hGaWVsZHMoKSB7XG5cblx0XHRzdXBlci5idWlsZFNlYXJjaEZpZWxkcygpO1xuXHRcdHRoaXMuc2VhcmNoX2ZpZWxkcyA9IFtcblxuXHRcdFx0bmV3IFNlYXJjaEZpZWxkKCB7XG5cdFx0XHRcdGxhYmVsOiAkLmkxOG4uXyggJ1N0YXR1cycgKSxcblx0XHRcdFx0aW5fY29sdW1uOiAxLFxuXHRcdFx0XHRmaWVsZDogJ3N0YXR1c19pZCcsXG5cdFx0XHRcdG11bHRpcGxlOiB0cnVlLFxuXHRcdFx0XHRiYXNpY19zZWFyY2g6IHRydWUsXG5cdFx0XHRcdGFkdl9zZWFyY2g6IHRydWUsXG5cdFx0XHRcdGxheW91dF9uYW1lOiAnZ2xvYmFsX29wdGlvbl9jb2x1bW4nLFxuXHRcdFx0XHRmb3JtX2l0ZW1fdHlwZTogRm9ybUl0ZW1UeXBlLkFXRVNPTUVfQk9YXG5cdFx0XHR9ICksXG5cblx0XHRcdG5ldyBTZWFyY2hGaWVsZCgge1xuXHRcdFx0XHRsYWJlbDogJC5pMThuLl8oICdDbGllbnQnICksXG5cdFx0XHRcdGluX2NvbHVtbjogMSxcblx0XHRcdFx0ZmllbGQ6ICdjbGllbnRfaWQnLFxuXHRcdFx0XHRsYXlvdXRfbmFtZTogJ2dsb2JhbF9jbGllbnQnLFxuXHRcdFx0XHRhcGlfY2xhc3M6IFRUQVBJLkFQSUNsaWVudCxcblx0XHRcdFx0bXVsdGlwbGU6IHRydWUsXG5cdFx0XHRcdGJhc2ljX3NlYXJjaDogdHJ1ZSxcblx0XHRcdFx0YWR2X3NlYXJjaDogdHJ1ZSxcblx0XHRcdFx0Zm9ybV9pdGVtX3R5cGU6IEZvcm1JdGVtVHlwZS5BV0VTT01FX0JPWFxuXHRcdFx0fSApLFxuXG5cdFx0XHRuZXcgU2VhcmNoRmllbGQoIHtcblx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnQ2xpZW50IEdyb3VwJyApLFxuXHRcdFx0XHRpbl9jb2x1bW46IDEsXG5cdFx0XHRcdG11bHRpcGxlOiB0cnVlLFxuXHRcdFx0XHRmaWVsZDogJ2NsaWVudF9ncm91cF9pZCcsXG5cdFx0XHRcdGxheW91dF9uYW1lOiAnZ2xvYmFsX3RyZWVfY29sdW1uJyxcblx0XHRcdFx0dHJlZV9tb2RlOiB0cnVlLFxuXHRcdFx0XHRiYXNpY19zZWFyY2g6IHRydWUsXG5cdFx0XHRcdGFkdl9zZWFyY2g6IHRydWUsXG5cdFx0XHRcdGZvcm1faXRlbV90eXBlOiBGb3JtSXRlbVR5cGUuQVdFU09NRV9CT1hcblx0XHRcdH0gKSxcblxuXHRcdFx0bmV3IFNlYXJjaEZpZWxkKCB7XG5cdFx0XHRcdGxhYmVsOiAkLmkxOG4uXyggJ0ludm9pY2UgTnVtYmVyJyApLFxuXHRcdFx0XHRpbl9jb2x1bW46IDEsXG5cdFx0XHRcdGZpZWxkOiAnaW52b2ljZV9udW1iZXInLFxuXHRcdFx0XHRtdWx0aXBsZTogdHJ1ZSxcblx0XHRcdFx0YmFzaWNfc2VhcmNoOiB0cnVlLFxuXHRcdFx0XHRhZHZfc2VhcmNoOiB0cnVlLFxuXHRcdFx0XHRmb3JtX2l0ZW1fdHlwZTogRm9ybUl0ZW1UeXBlLlRFWFRfSU5QVVRcblx0XHRcdH0gKSxcblxuXHRcdFx0bmV3IFNlYXJjaEZpZWxkKCB7XG5cdFx0XHRcdGxhYmVsOiAkLmkxOG4uXyggJ1BPIE51bWJlcicgKSxcblx0XHRcdFx0aW5fY29sdW1uOiAxLFxuXHRcdFx0XHRmaWVsZDogJ3BvX251bWJlcicsXG5cdFx0XHRcdG11bHRpcGxlOiB0cnVlLFxuXHRcdFx0XHRiYXNpY19zZWFyY2g6IGZhbHNlLFxuXHRcdFx0XHRhZHZfc2VhcmNoOiB0cnVlLFxuXHRcdFx0XHRmb3JtX2l0ZW1fdHlwZTogRm9ybUl0ZW1UeXBlLlRFWFRfSU5QVVRcblx0XHRcdH0gKSxcblxuXHRcdFx0bmV3IFNlYXJjaEZpZWxkKCB7XG5cdFx0XHRcdGxhYmVsOiAkLmkxOG4uXyggJ1NhbGVzIFJlcCcgKSxcblx0XHRcdFx0aW5fY29sdW1uOiAyLFxuXHRcdFx0XHRmaWVsZDogJ3NhbGVzX2NvbnRhY3RfaWQnLFxuXHRcdFx0XHRsYXlvdXRfbmFtZTogJ2dsb2JhbF91c2VyJyxcblx0XHRcdFx0YXBpX2NsYXNzOiBUVEFQSS5BUElVc2VyLFxuXHRcdFx0XHRtdWx0aXBsZTogdHJ1ZSxcblx0XHRcdFx0YmFzaWNfc2VhcmNoOiB0cnVlLFxuXHRcdFx0XHRhZHZfc2VhcmNoOiB0cnVlLFxuXHRcdFx0XHRmb3JtX2l0ZW1fdHlwZTogRm9ybUl0ZW1UeXBlLkFXRVNPTUVfQk9YXG5cdFx0XHR9ICksXG5cblx0XHRcdG5ldyBTZWFyY2hGaWVsZCgge1xuXHRcdFx0XHRsYWJlbDogJC5pMThuLl8oICdCaWxsaW5nIENvbnRhY3QnICksXG5cdFx0XHRcdGluX2NvbHVtbjogMixcblx0XHRcdFx0ZmllbGQ6ICdiaWxsaW5nX2NvbnRhY3RfaWQnLFxuXHRcdFx0XHRsYXlvdXRfbmFtZTogJ2dsb2JhbF9jbGllbnRfY29udGFjdCcsXG5cdFx0XHRcdGFwaV9jbGFzczogVFRBUEkuQVBJQ2xpZW50Q29udGFjdCxcblx0XHRcdFx0bXVsdGlwbGU6IHRydWUsXG5cdFx0XHRcdGJhc2ljX3NlYXJjaDogZmFsc2UsXG5cdFx0XHRcdGFkdl9zZWFyY2g6IHRydWUsXG5cdFx0XHRcdGZvcm1faXRlbV90eXBlOiBGb3JtSXRlbVR5cGUuQVdFU09NRV9CT1hcblx0XHRcdH0gKSxcblxuXHRcdFx0bmV3IFNlYXJjaEZpZWxkKCB7XG5cdFx0XHRcdGxhYmVsOiAkLmkxOG4uXyggJ1NoaXBwaW5nIENvbnRhY3QnICksXG5cdFx0XHRcdGluX2NvbHVtbjogMixcblx0XHRcdFx0ZmllbGQ6ICdzaGlwcGluZ19jb250YWN0X2lkJyxcblx0XHRcdFx0bGF5b3V0X25hbWU6ICdnbG9iYWxfY2xpZW50X2NvbnRhY3QnLFxuXHRcdFx0XHRhcGlfY2xhc3M6IFRUQVBJLkFQSUNsaWVudENvbnRhY3QsXG5cdFx0XHRcdG11bHRpcGxlOiB0cnVlLFxuXHRcdFx0XHRiYXNpY19zZWFyY2g6IGZhbHNlLFxuXHRcdFx0XHRhZHZfc2VhcmNoOiB0cnVlLFxuXHRcdFx0XHRmb3JtX2l0ZW1fdHlwZTogRm9ybUl0ZW1UeXBlLkFXRVNPTUVfQk9YXG5cdFx0XHR9ICksXG5cblx0XHRcdG5ldyBTZWFyY2hGaWVsZCgge1xuXHRcdFx0XHRsYWJlbDogJC5pMThuLl8oICdPdGhlciBDb250YWN0JyApLFxuXHRcdFx0XHRpbl9jb2x1bW46IDIsXG5cdFx0XHRcdGZpZWxkOiAnb3RoZXJfY29udGFjdF9pZCcsXG5cdFx0XHRcdGxheW91dF9uYW1lOiAnZ2xvYmFsX2NsaWVudF9jb250YWN0Jyxcblx0XHRcdFx0YXBpX2NsYXNzOiBUVEFQSS5BUElDbGllbnRDb250YWN0LFxuXHRcdFx0XHRtdWx0aXBsZTogdHJ1ZSxcblx0XHRcdFx0YmFzaWNfc2VhcmNoOiBmYWxzZSxcblx0XHRcdFx0YWR2X3NlYXJjaDogdHJ1ZSxcblx0XHRcdFx0Zm9ybV9pdGVtX3R5cGU6IEZvcm1JdGVtVHlwZS5BV0VTT01FX0JPWFxuXHRcdFx0fSApLFxuXG5cdFx0XHRuZXcgU2VhcmNoRmllbGQoIHtcblx0XHRcdFx0bGFiZWw6ICQuaTE4bi5fKCAnVGFncycgKSxcblx0XHRcdFx0ZmllbGQ6ICd0YWcnLFxuXHRcdFx0XHRiYXNpY19zZWFyY2g6IHRydWUsXG5cdFx0XHRcdGFkdl9zZWFyY2g6IHRydWUsXG5cdFx0XHRcdGluX2NvbHVtbjogMixcblx0XHRcdFx0b2JqZWN0X3R5cGVfaWQ6IDkxMCxcblx0XHRcdFx0Zm9ybV9pdGVtX3R5cGU6IEZvcm1JdGVtVHlwZS5UQUdfSU5QVVRcblx0XHRcdH0gKVxuXG5cdFx0XTtcblx0fVxuXG5cdHNldFNlbGVjdExheW91dCgpIHtcblx0XHRpZiAoIHRoaXMuc3ViX3ZpZXdfbW9kZSApIHtcblx0XHRcdHN1cGVyLnNldFNlbGVjdExheW91dCggWydjbGllbnQnXSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRzdXBlci5zZXRTZWxlY3RMYXlvdXQoKTtcblx0XHR9XG5cdH1cblxuXHRfY29udGludWVEb0NvcHlBc05ldygpIHtcblxuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cblx0XHR0aGlzLnNldEN1cnJlbnRFZGl0Vmlld1N0YXRlKCAnbmV3JyApO1xuXHRcdExvY2FsQ2FjaGVEYXRhLmN1cnJlbnRfZG9pbmdfY29udGV4dF9hY3Rpb24gPSAnY29weV9hc19uZXcnO1xuXHRcdGlmICggR2xvYmFsLmlzU2V0KCB0aGlzLmVkaXRfdmlldyApICkge1xuXG5cdFx0XHR0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQuaWQgPSAnJztcblx0XHRcdHZhciBuYXZpZ2F0aW9uX2RpdiA9IHRoaXMuZWRpdF92aWV3LmZpbmQoICcubmF2aWdhdGlvbi1kaXYnICk7XG5cdFx0XHRuYXZpZ2F0aW9uX2Rpdi5jc3MoICdkaXNwbGF5JywgJ25vbmUnICk7XG5cdFx0XHR0aGlzLnNldEVkaXRNZW51KCk7XG5cdFx0XHR0aGlzLnNldFRhYlN0YXR1cygpO1xuXG5cdFx0XHR0aGlzLmRldGFjaEVsZW1lbnQoICdjbGllbnQnICk7XG5cdFx0XHR0aGlzLmF0dGFjaEVsZW1lbnQoICdjbGllbnRfaWQnICk7XG5cdFx0XHR0aGlzLmVkaXRfdmlld191aV9kaWNbJ2ludm9pY2VfbnVtYmVyJ10uc2V0VmFsdWUoICQuaTE4bi5fKCAnTi9BJyApICk7XG5cdFx0XHR0aGlzLmlzX2NoYW5nZWQgPSBmYWxzZTtcblx0XHRcdFByb2dyZXNzQmFyLmNsb3NlT3ZlcmxheSgpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdHN1cGVyLl9jb250aW51ZURvQ29weUFzTmV3KCk7XG5cdFx0fVxuXHR9XG5cblx0c2V0Q3VycmVudEVkaXRSZWNvcmREYXRhKCkge1xuXHRcdC8vU2V0IGN1cnJlbnQgZWRpdCByZWNvcmQgZGF0YSB0byBhbGwgd2lkZ2V0c1xuXHRcdGZvciAoIHZhciBrZXkgaW4gdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkICkge1xuXHRcdFx0aWYgKCAhdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmhhc093blByb3BlcnR5KCBrZXkgKSApIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdHZhciB3aWRnZXQgPSB0aGlzLmVkaXRfdmlld191aV9kaWNba2V5XTtcblx0XHRcdGlmICggR2xvYmFsLmlzU2V0KCB3aWRnZXQgKSApIHtcblx0XHRcdFx0c3dpdGNoICgga2V5ICkge1xuXHRcdFx0XHRcdGNhc2UgJ2NsaWVudF9pZCc6XG5cdFx0XHRcdFx0XHR3aWRnZXQuc2V0VmFsdWUoIHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFtrZXldICk7XG5cdFx0XHRcdFx0XHR0aGlzLmVkaXRfdmlld191aV9kaWNbJ2JpbGxpbmdfY29udGFjdF9pZCddLnNldFNvdXJjZURhdGEoIG51bGwgKTtcblx0XHRcdFx0XHRcdHRoaXMuZWRpdF92aWV3X3VpX2RpY1snc2hpcHBpbmdfY29udGFjdF9pZCddLnNldFNvdXJjZURhdGEoIG51bGwgKTtcblx0XHRcdFx0XHRcdHRoaXMuZWRpdF92aWV3X3VpX2RpY1snb3RoZXJfY29udGFjdF9pZCddLnNldFNvdXJjZURhdGEoIG51bGwgKTtcblxuXHRcdFx0XHRcdFx0aWYgKCAhdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkIHx8ICF0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQuaWQgKSB7IC8vTmV3IGluIHN1YiB2aWV3LCB0aGUgY2xpZW50X2lkIGlzIHNldFxuXHRcdFx0XHRcdFx0XHR0aGlzLmdldENsaWVudCggdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkW2tleV0gKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdHRoaXMuZ2V0Q2xpZW50KCB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmRba2V5XSwgdHJ1ZSApO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdjb21iaW5lZF9zaGlwcGluZ19wb2xpY3lfaWQnOlxuXHRcdFx0XHRcdFx0Ly9zZXQgd2hlbiBnZXQgc2hpcHBpbmcgb3B0aW9ucztcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ2N1cnJlbmN5X2lkJzpcblx0XHRcdFx0XHRcdGlmICggIXRoaXMuY3VycmVudF9lZGl0X3JlY29yZFtrZXldICkge1xuXHRcdFx0XHRcdFx0XHR0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmRba2V5XSA9IExvY2FsQ2FjaGVEYXRhLmdldExvZ2luVXNlcigpLmN1cnJlbmN5X2lkO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0d2lkZ2V0LnNldFZhbHVlKCB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmRba2V5XSApO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnaW52b2ljZV9udW1iZXInOlxuXHRcdFx0XHRcdFx0aWYgKCAhdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkW2tleV0gfHwgdGhpcy5jb3BpZWRfcmVjb3JkX2lkICkge1xuXHRcdFx0XHRcdFx0XHR3aWRnZXQuc2V0VmFsdWUoICQuaTE4bi5fKCAnTi9BJyApICk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHR3aWRnZXQuc2V0VmFsdWUoIHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFtrZXldICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRcdFx0d2lkZ2V0LnNldFZhbHVlKCB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmRba2V5XSApO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMuY29sbGVjdFVJRGF0YVRvQ3VycmVudEVkaXRSZWNvcmQoKTtcblx0XHR0aGlzLnNldEVkaXRWaWV3RGF0YURvbmUoKTtcblx0fVxuXG5cdHNob3dDbGllbnRDb2x1bW4oKSB7XG5cdFx0aWYgKCB0aGlzLmlzX2VkaXQgKSB7XG5cdFx0XHR0aGlzLmF0dGFjaEVsZW1lbnQoICdjbGllbnQnICk7XG5cdFx0XHR0aGlzLmRldGFjaEVsZW1lbnQoICdjbGllbnRfaWQnICk7XG5cdFx0fSBlbHNlIGlmICggdGhpcy5pc19hZGQgKSB7XG5cdFx0XHR0aGlzLmRldGFjaEVsZW1lbnQoICdjbGllbnQnICk7XG5cdFx0XHR0aGlzLmF0dGFjaEVsZW1lbnQoICdjbGllbnRfaWQnICk7XG5cblx0XHR9XG5cdH1cblxuXHRzZXRQYXltZW50SWNvbkRpc2FibGVkKCkge1xuXHRcdGxldCBjb250ZXh0X2J0biA9IENvbnRleHRNZW51TWFuYWdlci5nZXRNZW51TW9kZWxCeU1lbnVJZCggdGhpcy5kZXRlcm1pbmVDb250ZXh0TWVudU1vdW50QXR0cmlidXRlcygpLmlkICkuZmluZCggY29udGV4dF9pY29uID0+IGNvbnRleHRfaWNvbi5pZCA9PT0gJ3BheW1lbnQnICk7XG5cdFx0dGhpcy5zZXREZWZhdWx0TWVudVBheW1lbnRJY29uKCBjb250ZXh0X2J0biApO1xuXHR9XG5cblx0b25Gb3JtSXRlbUNoYW5nZSggdGFyZ2V0LCBkb05vdFZhbGlkYXRlICkge1xuXHRcdHRoaXMuc2V0UGF5bWVudEljb25EaXNhYmxlZCgpO1xuXHRcdHRoaXMuc2V0TWFzc0VkaXRpbmdGaWVsZHNXaGVuRm9ybUNoYW5nZSggdGFyZ2V0ICk7XG5cdFx0dGhpcy5zZXRJc0NoYW5nZWQoIHRhcmdldCApO1xuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cdFx0dmFyIGtleSA9IHRhcmdldC5nZXRGaWVsZCgpO1xuXHRcdHZhciBjX3ZhbHVlID0gdGFyZ2V0LmdldFZhbHVlKCk7XG5cdFx0dGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkW2tleV0gPSB0YXJnZXQuZ2V0VmFsdWUoKTtcblxuXHRcdHN3aXRjaCAoIGtleSApIHtcblx0XHRcdGNhc2UgJ2NsaWVudF9pZCc6XG5cdFx0XHRcdHRoaXMuZWRpdF92aWV3X3VpX2RpY1snYmlsbGluZ19jb250YWN0X2lkJ10uc2V0U291cmNlRGF0YSggbnVsbCApO1xuXHRcdFx0XHR0aGlzLmVkaXRfdmlld191aV9kaWNbJ3NoaXBwaW5nX2NvbnRhY3RfaWQnXS5zZXRTb3VyY2VEYXRhKCBudWxsICk7XG5cdFx0XHRcdHRoaXMuZWRpdF92aWV3X3VpX2RpY1snb3RoZXJfY29udGFjdF9pZCddLnNldFNvdXJjZURhdGEoIG51bGwgKTtcblx0XHRcdFx0dGhpcy5lZGl0X3ZpZXdfdWlfZGljWydiaWxsaW5nX2NvbnRhY3RfaWQnXS5zZXRWYWx1ZSggZmFsc2UgKTtcblx0XHRcdFx0dGhpcy5lZGl0X3ZpZXdfdWlfZGljWydzaGlwcGluZ19jb250YWN0X2lkJ10uc2V0VmFsdWUoIGZhbHNlICk7XG5cdFx0XHRcdHRoaXMuZWRpdF92aWV3X3VpX2RpY1snb3RoZXJfY29udGFjdF9pZCddLnNldFZhbHVlKCBmYWxzZSApO1xuXG5cdFx0XHRcdHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFsnYmlsbGluZ19jb250YWN0X2lkJ10gPSBmYWxzZTtcblx0XHRcdFx0dGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkWydzaGlwcGluZ19jb250YWN0X2lkJ10gPSBmYWxzZTtcblx0XHRcdFx0dGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkWydvdGhlcl9jb250YWN0X2lkJ10gPSBmYWxzZTtcblx0XHRcdFx0dGhpcy5nZXRDbGllbnQoIGNfdmFsdWUgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdiaWxsaW5nX2NvbnRhY3RfaWQnOlxuXG5cdFx0XHRcdGlmICggdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkWydiaWxsaW5nX2NvbnRhY3RfaWQnXSApIHtcblx0XHRcdFx0XHR0aGlzLnNldERlZmF1bHRDdXJyZW5jeSgpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRoaXMuZ2V0SW52b2ljZVRvdGFsRGF0YSgpO1xuXHRcdFx0XHR9XG5cblx0XHR9XG5cblx0XHRzd2l0Y2ggKCBrZXkgKSB7XG5cdFx0XHRjYXNlICdjdXJyZW5jeV9pZCc6XG5cdFx0XHRjYXNlICdzaGlwcGluZ19jb250YWN0X2lkJzpcblx0XHRcdFx0dGhpcy5nZXRJbnZvaWNlVG90YWxEYXRhKCk7XG5cdFx0XHRcdHRoaXMuZ2V0U2hpcHBpbmdPcHRpb25zKCk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSAnY29tYmluZWRfc2hpcHBpbmdfcG9saWN5X2lkJzpcblx0XHRcdFx0dGhpcy5nZXRJbnZvaWNlVG90YWxEYXRhKCk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdH1cblxuXHRcdGlmICggIWRvTm90VmFsaWRhdGUgKSB7XG5cdFx0XHR0aGlzLnZhbGlkYXRlKCk7XG5cdFx0fVxuXHR9XG5cblx0c2V0RGVmYXVsdEN1cnJlbmN5KCkge1xuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cdFx0dmFyIGFyZ3MgPSB7fTtcblx0XHRhcmdzLmZpbHRlcl9kYXRhID0ge307XG5cdFx0YXJncy5maWx0ZXJfZGF0YS5pZCA9IHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFsnYmlsbGluZ19jb250YWN0X2lkJ107XG5cdFx0dGhpcy5jbGllbnRfY29udGFjdF9hcGlbJ2dldCcgKyB0aGlzLmNsaWVudF9jb250YWN0X2FwaS5rZXlfbmFtZV0oIGFyZ3MsIHtcblx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzICkge1xuXHRcdFx0XHR2YXIgcmVzdWx0ID0gcmVzLmdldFJlc3VsdCgpWzBdO1xuXHRcdFx0XHQvLyBGSVhFRCBKUyBFWENFUFRJT046IENhbm5vdCBzZXQgcHJvcGVydHkgJ2N1cnJlbmN5X2lkJyBvZiBudWxsXG5cdFx0XHRcdGlmICggJHRoaXMuZWRpdF92aWV3X3VpX2RpYyAmJiAkdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkICkge1xuXHRcdFx0XHRcdC8vRml4ZWQgcG9zc2libGUgZXhjZXB0aW9uIC0tIEVycm9yOiBVbmFibGUgdG8gZ2V0IHByb3BlcnR5ICdjdXJyZW5jeV9pZCcgb2YgdW5kZWZpbmVkIG9yIG51bGwgcmVmZXJlbmNlIGluIC9pbnRlcmZhY2UvaHRtbDUvIGxpbmUgMTI0NlxuXHRcdFx0XHRcdGlmICggcmVzdWx0ICkge1xuXHRcdFx0XHRcdFx0JHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFsnY3VycmVuY3lfaWQnXSA9IHJlc3VsdC5jdXJyZW5jeV9pZDtcblx0XHRcdFx0XHRcdCR0aGlzLmVkaXRfdmlld191aV9kaWNbJ2N1cnJlbmN5X2lkJ10uc2V0VmFsdWUoIHJlc3VsdC5jdXJyZW5jeV9pZCApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHQkdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkWydjdXJyZW5jeV9pZCddID0gTG9jYWxDYWNoZURhdGEuZ2V0TG9naW5Vc2VyKCkuY3VycmVuY3lfaWQ7XG5cdFx0XHRcdFx0XHQkdGhpcy5lZGl0X3ZpZXdfdWlfZGljWydjdXJyZW5jeV9pZCddLnNldFZhbHVlKCBMb2NhbENhY2hlRGF0YS5nZXRMb2dpblVzZXIoKS5jdXJyZW5jeV9pZCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdCR0aGlzLmdldEludm9pY2VUb3RhbERhdGEoKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH1cblxuXHRnZXRDbGllbnQoIGNsaWVudF9pZCwgZmlsdGVyX29ubHkgKSB7XG5cdFx0dmFyICR0aGlzID0gdGhpcztcblx0XHR2YXIgZmlsdGVyID0ge307XG5cdFx0ZmlsdGVyLmZpbHRlcl9kYXRhID0geyAnaWQnOiBjbGllbnRfaWQgfTtcblx0XHRmaWx0ZXIuZmlsdGVyX2NvbHVtbnMgPSB7XG5cdFx0XHQnaW52b2ljZV9udW1iZXInOiB0cnVlLFxuXHRcdFx0J2RlZmF1bHRfb3RoZXJfY29udGFjdF9pZCc6IHRydWUsXG5cdFx0XHQnY2xpZW50JzogdHJ1ZSxcblx0XHRcdCdkZWZhdWx0X2JpbGxpbmdfY29udGFjdF9pZCc6IHRydWUsXG5cdFx0XHQnaW52b2ljZV9kYXRlJzogdHJ1ZSxcblx0XHRcdCdzdGF0dXMnOiB0cnVlLFxuXHRcdFx0J2RlZmF1bHRfc2hpcHBpbmdfY29udGFjdF9pZCc6IHRydWVcblx0XHR9O1xuXHRcdGlmICggY2xpZW50X2lkICkge1xuXHRcdFx0dGhpcy5jbGllbnRfYXBpWydnZXQnICsgdGhpcy5jbGllbnRfYXBpLmtleV9uYW1lXSggZmlsdGVyLCB7XG5cdFx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzICkge1xuXHRcdFx0XHRcdGlmICggISR0aGlzLmVkaXRfdmlldyApIHtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR2YXIgcmVzdWx0X2RhdGEgPSByZXMuZ2V0UmVzdWx0KCk7XG5cdFx0XHRcdFx0aWYgKCBHbG9iYWwuaXNBcnJheSggcmVzdWx0X2RhdGEgKSApIHtcblx0XHRcdFx0XHRcdHZhciByZXN1bHQgPSByZXN1bHRfZGF0YVswXTtcblxuXHRcdFx0XHRcdFx0Ly9XaGVuIHNldCBpdCBmaXJzdCB0aW1lIGluIHNldEN1cnJlbnRFZGl0UmVjb3JkLCBkb24ndCB1c2UgZGVmYXVsdCB2YWx1ZVxuXHRcdFx0XHRcdFx0aWYgKCAhZmlsdGVyX29ubHkgKSB7XG5cblx0XHRcdFx0XHRcdFx0dmFyIGRlZmF1bHRfYmlsbGluZ19jb250YWN0X2lkID0gcmVzdWx0LmRlZmF1bHRfYmlsbGluZ19jb250YWN0X2lkO1xuXHRcdFx0XHRcdFx0XHR2YXIgZGVmYXVsdF9zaGlwcGluZ19jb250YWN0X2lkID0gcmVzdWx0LmRlZmF1bHRfc2hpcHBpbmdfY29udGFjdF9pZDtcblx0XHRcdFx0XHRcdFx0dmFyIGRlZmF1bHRfb3RoZXJfY29udGFjdF9pZCA9IHJlc3VsdC5kZWZhdWx0X290aGVyX2NvbnRhY3RfaWQ7XG5cblx0XHRcdFx0XHRcdFx0JHRoaXMuZWRpdF92aWV3X3VpX2RpY1snYmlsbGluZ19jb250YWN0X2lkJ10uc2V0VmFsdWUoIGRlZmF1bHRfYmlsbGluZ19jb250YWN0X2lkICk7XG5cdFx0XHRcdFx0XHRcdCR0aGlzLmVkaXRfdmlld191aV9kaWNbJ3NoaXBwaW5nX2NvbnRhY3RfaWQnXS5zZXRWYWx1ZSggZGVmYXVsdF9zaGlwcGluZ19jb250YWN0X2lkICk7XG5cdFx0XHRcdFx0XHRcdCR0aGlzLmVkaXRfdmlld191aV9kaWNbJ290aGVyX2NvbnRhY3RfaWQnXS5zZXRWYWx1ZSggZGVmYXVsdF9vdGhlcl9jb250YWN0X2lkICk7XG5cblx0XHRcdFx0XHRcdFx0JHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFsnYmlsbGluZ19jb250YWN0X2lkJ10gPSBkZWZhdWx0X2JpbGxpbmdfY29udGFjdF9pZDtcblx0XHRcdFx0XHRcdFx0JHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFsnc2hpcHBpbmdfY29udGFjdF9pZCddID0gZGVmYXVsdF9zaGlwcGluZ19jb250YWN0X2lkO1xuXHRcdFx0XHRcdFx0XHQkdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkWydvdGhlcl9jb250YWN0X2lkJ10gPSBkZWZhdWx0X290aGVyX2NvbnRhY3RfaWQ7XG5cblx0XHRcdFx0XHRcdFx0JHRoaXMuc2V0RGVmYXVsdEN1cnJlbmN5KCk7XG5cdFx0XHRcdFx0XHRcdCR0aGlzLmdldFNoaXBwaW5nT3B0aW9ucygpO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQkdGhpcy5lZGl0X3ZpZXdfdWlfZGljWydiaWxsaW5nX2NvbnRhY3RfaWQnXS5zZXREZWZhdWx0QXJncyggeyAnZmlsdGVyX2RhdGEnOiB7ICdjbGllbnRfaWQnOiBjbGllbnRfaWQgfSB9ICk7XG5cdFx0XHRcdFx0XHQkdGhpcy5lZGl0X3ZpZXdfdWlfZGljWydzaGlwcGluZ19jb250YWN0X2lkJ10uc2V0RGVmYXVsdEFyZ3MoIHsgJ2ZpbHRlcl9kYXRhJzogeyAnY2xpZW50X2lkJzogY2xpZW50X2lkIH0gfSApO1xuXHRcdFx0XHRcdFx0JHRoaXMuZWRpdF92aWV3X3VpX2RpY1snb3RoZXJfY29udGFjdF9pZCddLnNldERlZmF1bHRBcmdzKCB7ICdmaWx0ZXJfZGF0YSc6IHsgJ2NsaWVudF9pZCc6IGNsaWVudF9pZCB9IH0gKTtcblxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0aWYgKCAhZmlsdGVyX29ubHkgKSB7XG5cdFx0XHRcdHRoaXMuZ2V0SW52b2ljZVRvdGFsRGF0YSgpO1xuXHRcdFx0XHR0aGlzLmdldFNoaXBwaW5nT3B0aW9ucygpO1xuXHRcdFx0fVxuXG5cdFx0fVxuXHR9XG5cblx0c2V0RWRpdFZpZXdEYXRhRG9uZSgpIHtcblx0XHRzdXBlci5zZXRFZGl0Vmlld0RhdGFEb25lKCk7XG5cdFx0dGhpcy5zaG93Q2xpZW50Q29sdW1uKCk7XG5cdFx0dGhpcy5pbml0SW5zaWRlRWRpdG9yRGF0YSgpO1xuXHR9XG5cblx0aW5pdEluc2lkZUVkaXRvckRhdGEoIHVwZGF0ZV9zdGF0dXMgKSB7XG5cblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXG5cdFx0dmFyIHRyYW5zYWN0aW9uX2lkID0gdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmlkID8gdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmlkIDogdGhpcy5jb3BpZWRfcmVjb3JkX2lkO1xuXHRcdHRoaXMuY29waWVkX3JlY29yZF9pZCA9ICcnO1xuXG5cdFx0aWYgKCAhdHJhbnNhY3Rpb25faWQgKSB7XG5cblx0XHRcdHRoaXMudHJhbnNhY3Rpb25fcGFpZF9kYXRhID0gbnVsbDtcblxuXHRcdFx0JHRoaXMuZWRpdG9yLnJlbW92ZUFsbFJvd3MoKTtcblx0XHRcdCR0aGlzLmVkaXRvci5nZXREZWZhdWx0RGF0YSgpO1xuXG5cdFx0XHRpZiAoIHRoaXMudG90YWxfZGF0YV9yZW5kZXIgKSB7XG5cdFx0XHRcdHRoaXMudG90YWxfZGF0YV9yZW5kZXIucmVtb3ZlKCk7XG5cdFx0XHRcdHRoaXMudG90YWxfZGF0YV9yZW5kZXIgPSBudWxsO1xuXHRcdFx0XHR0aGlzLnRvdGFsX2RhdGFfcm93X3JlbmRlciA9IG51bGw7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggdGhpcy5oaXN0b3J5ICkge1xuXHRcdFx0XHR0aGlzLmhpc3RvcnkucmVtb3ZlKCk7XG5cdFx0XHRcdHRoaXMuaGlzdG9yeSA9IG51bGw7XG5cdFx0XHR9XG5cblx0XHRcdCR0aGlzLmdldEludm9pY2VUb3RhbERhdGEoKTtcblx0XHRcdCR0aGlzLmdldFNoaXBwaW5nT3B0aW9ucygpO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0dmFyIGZpbHRlciA9IHt9O1xuXHRcdFx0ZmlsdGVyLmZpbHRlcl9kYXRhID0ge307XG5cdFx0XHRmaWx0ZXIuZmlsdGVyX2RhdGEuaW52b2ljZV9pZCA9IHRyYW5zYWN0aW9uX2lkO1xuXHRcdFx0ZmlsdGVyLmZpbHRlcl9kYXRhLnR5cGVfaWQgPSAxMDtcblx0XHRcdGZpbHRlci5maWx0ZXJfZGF0YS5wcm9kdWN0X3R5cGVfaWQgPSBbMTAsIDIwXTtcblxuXHRcdFx0dGhpcy50cmFuc2FjdGlvbl9hcGlbJ2dldCcgKyB0aGlzLnRyYW5zYWN0aW9uX2FwaS5rZXlfbmFtZV0oIGZpbHRlciwgdHJ1ZSwge1xuXHRcdFx0XHRvblJlc3VsdDogZnVuY3Rpb24oIHJlcyApIHtcblxuXHRcdFx0XHRcdHZhciByZXN1bHQgPSByZXMuZ2V0UmVzdWx0KCk7XG5cblx0XHRcdFx0XHQvLyBnZXQgdGhlIHBhaWQgZGF0YS5cblx0XHRcdFx0XHRmaWx0ZXIuZmlsdGVyX2RhdGEgPSB7fTtcblx0XHRcdFx0XHRmaWx0ZXIuZmlsdGVyX2NvbHVtbnMgPSB7XG5cdFx0XHRcdFx0XHR0eXBlX2lkOiB0cnVlLFxuXHRcdFx0XHRcdFx0c3RhdHVzX2lkOiB0cnVlLFxuXHRcdFx0XHRcdFx0cGF5bWVudF90eXBlOiB0cnVlLFxuXHRcdFx0XHRcdFx0Y29uZmlybV9udW1iZXI6IHRydWUsXG5cdFx0XHRcdFx0XHRpZDogdHJ1ZSxcblx0XHRcdFx0XHRcdGNsaWVudF9pZDogdHJ1ZSxcblx0XHRcdFx0XHRcdGludm9pY2VfaWQ6IHRydWUsXG5cdFx0XHRcdFx0XHRhbW91bnQ6IHRydWUsXG5cdFx0XHRcdFx0XHRzdGF0dXM6IHRydWUsXG5cdFx0XHRcdFx0XHRjbGllbnRfcGF5bWVudDogdHJ1ZVxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0ZmlsdGVyLmZpbHRlcl9kYXRhLnR5cGVfaWQgPSAyMDtcblx0XHRcdFx0XHRmaWx0ZXIuZmlsdGVyX2RhdGEuaW52b2ljZV9pZCA9IHRyYW5zYWN0aW9uX2lkO1xuXG5cdFx0XHRcdFx0JHRoaXMudHJhbnNhY3Rpb25fYXBpWydnZXQnICsgJHRoaXMudHJhbnNhY3Rpb25fYXBpLmtleV9uYW1lXSggZmlsdGVyLCB0cnVlLCB7XG5cdFx0XHRcdFx0XHRvblJlc3VsdDogZnVuY3Rpb24oIHBhaWRfcmVzICkge1xuXG5cdFx0XHRcdFx0XHRcdGlmICggISR0aGlzLmVkaXRfdmlldyApIHtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRpZiAoIEdsb2JhbC5pc1NldCggdXBkYXRlX3N0YXR1cyApICkge1xuXHRcdFx0XHRcdFx0XHRcdCR0aGlzLnVwZGF0ZVN0YXR1cygpO1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0dmFyIHBhaWQgPSBwYWlkX3Jlcy5nZXRSZXN1bHQoKTtcblx0XHRcdFx0XHRcdFx0aWYgKCBwYWlkID09PSB0cnVlICkge1xuXHRcdFx0XHRcdFx0XHRcdCR0aGlzLnRyYW5zYWN0aW9uX3BhaWRfZGF0YSA9IG51bGw7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0JHRoaXMudHJhbnNhY3Rpb25fcGFpZF9kYXRhID0gcGFpZDtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdCR0aGlzLmVkaXRvci5zZXRWYWx1ZSggcmVzdWx0ICk7XG5cdFx0XHRcdFx0XHRcdCR0aGlzLmdldEludm9pY2VUb3RhbERhdGEoIHJlc3VsdCApO1xuXHRcdFx0XHRcdFx0XHQkdGhpcy5nZXRTaGlwcGluZ09wdGlvbnMoIHJlc3VsdCApO1xuXHRcdFx0XHRcdFx0XHQkdGhpcy5zZXRUcmFuc2FjdGlvbkhpc3RvcnlEYXRhKCk7XG5cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9ICk7XG5cblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXG5cdFx0fVxuXHR9XG5cblx0aW5zaWRlRWRpdG9yU2V0VmFsdWUoIHZhbCApIHtcblx0XHR2YXIgbGVuID0gdmFsLmxlbmd0aDtcblx0XHR0aGlzLnJlbW92ZUFsbFJvd3MoKTtcblxuXHRcdGlmICggbGVuID4gMCApIHtcblx0XHRcdGZvciAoIHZhciBpID0gMDsgaSA8IHZhbC5sZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIHZhbFtpXSApICkge1xuXHRcdFx0XHRcdHZhciByb3cgPSB2YWxbaV07XG5cdFx0XHRcdFx0dGhpcy5hZGRSb3coIHJvdyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuZ2V0RGVmYXVsdERhdGEoKTtcblx0XHR9XG5cdH1cblxuXHRnZXRJbnZvaWNlVG90YWxEYXRhKCB0cmFuc2FjdGlvbl9kYXRhICkge1xuXG5cdFx0dmFyICR0aGlzID0gdGhpcztcblx0XHR2YXIgdHJhbnNhY3Rpb25fcmVjb3JkO1xuXG5cdFx0aWYgKCAhJHRoaXMuZWRpdF92aWV3ICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICggR2xvYmFsLmlzU2V0KCB0cmFuc2FjdGlvbl9kYXRhICkgKSB7XG5cdFx0XHR0cmFuc2FjdGlvbl9yZWNvcmQgPSB0cmFuc2FjdGlvbl9kYXRhO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0cmFuc2FjdGlvbl9yZWNvcmQgPSB0aGlzLmVkaXRvci5nZXRWYWx1ZSgpO1xuXHRcdH1cblxuXHRcdGlmICggdGhpcy50cmFuc2FjdGlvbl9wYWlkX2RhdGEgKSB7XG5cdFx0XHR2YXIgdGVtcF90cmFuc2FjdGlvbl9yZWNvcmQgPSBbXTtcblx0XHRcdCQuZWFjaCggdHJhbnNhY3Rpb25fcmVjb3JkLCBmdW5jdGlvbigga2V5LCBpdGVtICkge1xuXHRcdFx0XHR0ZW1wX3RyYW5zYWN0aW9uX3JlY29yZC5wdXNoKCBpdGVtICk7XG5cdFx0XHR9ICk7XG5cdFx0XHQkLmVhY2goIHRoaXMudHJhbnNhY3Rpb25fcGFpZF9kYXRhLCBmdW5jdGlvbigga2V5LCBpdGVtICkge1xuXHRcdFx0XHR0ZW1wX3RyYW5zYWN0aW9uX3JlY29yZC5wdXNoKCBpdGVtICk7XG5cdFx0XHR9ICk7XG5cblx0XHRcdHRyYW5zYWN0aW9uX3JlY29yZCA9IHRlbXBfdHJhbnNhY3Rpb25fcmVjb3JkO1xuXHRcdH1cblxuXHRcdHRoaXMuYXBpLmdldEludm9pY2VUb3RhbERhdGEoIHRyYW5zYWN0aW9uX3JlY29yZCwgdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLCBmYWxzZSwge1xuXHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCByZXMgKSB7XG5cblx0XHRcdFx0dmFyIHJlc3VsdCA9IHJlcy5nZXRSZXN1bHQoKTtcblx0XHRcdFx0JHRoaXMuc2V0SW52b2ljZVRvdGFsRGF0YSggcmVzdWx0ICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9XG5cblx0c2V0VHJhbnNhY3Rpb25IaXN0b3J5RGF0YSgpIHtcblxuXHRcdGlmICggdGhpcy50cmFuc2FjdGlvbl9wYWlkX2RhdGEgKSB7XG5cblx0XHRcdGlmICggdGhpcy5oaXN0b3J5ICkge1xuXHRcdFx0XHR0aGlzLmhpc3RvcnkucmVtb3ZlKCk7XG5cdFx0XHR9XG5cblx0XHRcdHZhciB0YWJfaW52b2ljZSA9IHRoaXMuZWRpdF92aWV3X3RhYi5maW5kKCAnI3RhYl9pbnZvaWNlJyApO1xuXHRcdFx0dmFyIGluc2lkZV9lZGl0b3JfZGl2ID0gdGFiX2ludm9pY2UuZmluZCggJy5pbnNpZGUtdHJhbnNhY3Rpb24taGlzdG9yeS1kaXYnICk7XG5cblx0XHRcdHZhciByZW5kZXIgPSBgXG5cdFx0XHQ8dGFibGUgY2xhc3M9XCJpbnNpZGUtZWRpdG9yLXJlbmRlciBpbnNpZGUtY3VzdG9tLXN0eWxlXCI+XG5cdFx0XHRcdDx0ciBjbGFzcz1cInRpdGxlXCIgc3R5bGU9XCJmb250LXdlaWdodDogYm9sZDtcIj5cblx0XHRcdFx0XHQ8dGQgc3R5bGU9XCJ3aWR0aDogNDAwcHhcIj48JT0gc3RhdHVzICU+PC90ZD5cblx0XHRcdFx0XHQ8dGQgc3R5bGU9XCJ3aWR0aDogMzAwcHhcIj48JT0gcGF5bWVudF90eXBlICU+PC90ZD5cblx0XHRcdFx0XHQ8dGQgc3R5bGU9XCJ3aWR0aDogMjAwcHhcIj48JT0gY2xpZW50X3BheW1lbnQgJT48L3RkPlxuXHRcdFx0XHRcdDx0ZCBzdHlsZT1cIndpZHRoOiAyMDBweFwiPjwlPSBjb25maXJtX251bWJlciAlPjwvdGQ+XG5cdFx0XHRcdFx0PHRkIHN0eWxlPVwid2lkdGg6IDEwMHB4XCI+PCU9IGFtb3VudCAlPjwvdGQ+XG5cdFx0XHRcdDwvdHI+XG5cdFx0XHQ8L3RhYmxlPmA7XG5cdFx0XHR2YXIgcm93X3JlbmRlciA9IGBcblx0XHRcdDx0ciBjbGFzcz1cImluc2lkZS1lZGl0b3Itcm93IGRhdGEtcm93XCI+XG5cdFx0XHRcdDx0ZCBjbGFzcz1cIlwiPjwlPSBzdGF0dXMgJT48L3RkPlxuXHRcdFx0XHQ8dGQgY2xhc3M9XCJcIj48JT0gcGF5bWVudF90eXBlICU+PC90ZD5cblx0XHRcdFx0PHRkIGNsYXNzPVwiXCI+PCU9IGNsaWVudF9wYXltZW50ICU+PC90ZD5cblx0XHRcdFx0PHRkIGNsYXNzPVwiXCI+PCU9IGNvbmZpcm1fbnVtYmVyICU+PC90ZD5cblx0XHRcdFx0PHRkIGNsYXNzPVwiXCI+PCU9IGFtb3VudCAlPjwvdGQ+XG5cdFx0XHQ8L3RyPmA7XG5cblx0XHRcdHZhciB0aXRsZSA9IHtcblx0XHRcdFx0c3RhdHVzOiAkLmkxOG4uXyggJ1N0YXR1cycgKSxcblx0XHRcdFx0cGF5bWVudF90eXBlOiAkLmkxOG4uXyggJ1BheW1lbnQgVHlwZScgKSxcblx0XHRcdFx0Y2xpZW50X3BheW1lbnQ6ICQuaTE4bi5fKCAnUGF5bWVudCBNZXRob2QnICksXG5cdFx0XHRcdGNvbmZpcm1fbnVtYmVyOiAkLmkxOG4uXyggJ0NvbmZpcm1hdGlvbiBOdW1iZXInICksXG5cdFx0XHRcdGFtb3VudDogJC5pMThuLl8oICdBbW91bnQnIClcblx0XHRcdH07XG5cblx0XHRcdHZhciBoaXN0b3J5ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5JTlNJREVfRURJVE9SICk7XG5cblx0XHRcdHZhciB0ZW1wbGF0ZSA9IF8udGVtcGxhdGUoIHJlbmRlciApO1xuXG5cdFx0XHR2YXIgcmVuZGVyX2RpdiA9IGhpc3RvcnkuY2hpbGRyZW4oKS5lcSggMSApO1xuXHRcdFx0cmVuZGVyX2Rpdi5hcHBlbmQoIHRlbXBsYXRlKCB0aXRsZSApICk7XG5cblx0XHRcdHJlbmRlciA9ICQoIHJlbmRlcl9kaXYuZmluZCggJy5pbnNpZGUtZWRpdG9yLXJlbmRlcicgKSApO1xuXHRcdFx0LyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuXHRcdFx0Zm9yICggdmFyIGtleSBpbiB0aGlzLnRyYW5zYWN0aW9uX3BhaWRfZGF0YSApIHtcblx0XHRcdFx0dmFyIHJvdyA9IHRoaXMudHJhbnNhY3Rpb25fcGFpZF9kYXRhW2tleV07XG5cdFx0XHRcdCQuZWFjaCggcm93LCBmdW5jdGlvbiggaSwgdiApIHtcblx0XHRcdFx0XHRyb3dbaV0gPSB2ID8gdiA6ICctLSc7XG5cdFx0XHRcdH0gKTtcblxuXHRcdFx0XHR2YXIgdG1wX3RlbXBsYXRlID0gXy50ZW1wbGF0ZSggcm93X3JlbmRlciApO1xuXHRcdFx0XHRyZW5kZXIuYXBwZW5kKCB0bXBfdGVtcGxhdGUoIHJvdyApICk7XG5cdFx0XHR9XG5cdFx0XHQvKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXHRcdFx0aW5zaWRlX2VkaXRvcl9kaXYuYXBwZW5kKCByZW5kZXIgKTtcblxuXHRcdFx0dGhpcy5oaXN0b3J5ID0gJCggcmVuZGVyICk7XG5cdFx0fVxuXHR9XG5cblx0c2V0SW52b2ljZVRvdGFsRGF0YSggdG90YWxfZGF0YSApIHtcblxuXHRcdGlmICggIXRoaXMuZWRpdF92aWV3ICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICggR2xvYmFsLmlzU2V0KCB0aGlzLnRvdGFsX2RhdGFfcmVuZGVyICkgKSB7XG5cdFx0XHR0aGlzLnRvdGFsX2RhdGFfcmVuZGVyLnJlbW92ZSgpO1xuXHRcdFx0dGhpcy50b3RhbF9kYXRhX3JlbmRlciA9IG51bGw7XG5cdFx0fVxuXG5cdFx0dmFyIHRhYl9pbnZvaWNlID0gdGhpcy5lZGl0X3ZpZXdfdGFiLmZpbmQoICcjdGFiX2ludm9pY2UnICk7XG5cdFx0dmFyIGluc2lkZV9lZGl0b3JfZGl2ID0gdGFiX2ludm9pY2UuZmluZCggJy5pbnNpZGUtdG90YWwtZGF0YS1lZGl0b3ItZGl2JyApO1xuXHRcdHRoaXMudG90YWxfZGF0YV9yb3dfcmVuZGVyID0gYFxuXHRcdDx1bCBjbGFzcz1cInRvdGFsLWRhdGEtcm93XCI+XG5cdFx0XHQ8bGkgY2xhc3M9XCJ0b3RhbC1kYXRhLWxhYmVsXCI+PCU9IGxhYmVsICU+PC9saT5cblx0XHRcdDxsaSBjbGFzcz1cInRvdGFsLWRhdGEtdmFsdWVcIj48JT0gdmFsdWUgJT48L2xpPlxuXHRcdDwvdWw+YDtcblx0XHR0aGlzLnRvdGFsX2RhdGFfcmVuZGVyID0gJCggJzxkaXYgY2xhc3M9XCJ0b3RhbC1kYXRhLWVkaXRvclwiPjwvZGl2PicgKTtcblxuXHRcdHZhciByZW5kZXJfYXJncyA9IHRoaXMudmlld1RvdGFsRGF0YVVJKCBHbG9iYWwucmVtb3ZlU29ydFByZWZpeEZyb21BcnJheSggdG90YWxfZGF0YSApICk7XG5cblx0XHRpZiAoIEdsb2JhbC5pc1NldCggcmVuZGVyX2FyZ3MgKSApIHtcblx0XHRcdGluc2lkZV9lZGl0b3JfZGl2LmFwcGVuZCggdGhpcy50b3RhbF9kYXRhX3JlbmRlciApO1xuXHRcdH1cblx0fVxuXG5cdHZpZXdUb3RhbERhdGFVSSggdG90YWxfZGF0YSApIHtcblxuXHRcdHZhciByZW5kZXJfYXJncyA9IG51bGw7XG5cblx0XHRmb3IgKCB2YXIga2V5IGluIHRvdGFsX2RhdGEgKSB7XG5cdFx0XHR2YXIgcm93ID0gdG90YWxfZGF0YVtrZXldO1xuXG5cdFx0XHRpZiAoIHR5cGVvZiByb3cgPT09ICdvYmplY3QnICkge1xuXHRcdFx0XHRpZiAoIGtleSA9PT0gJ293aW5nJyApIHtcblx0XHRcdFx0XHR0aGlzLm93aW5nX2Ftb3VudCA9IHJvdy5hbW91bnQ7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCBHbG9iYWwuaXNTZXQoIHJvdy5hbW91bnQgKSAmJiAoIHBhcnNlRmxvYXQoIHJvdy5hbW91bnQgKSAhPT0gMCB8fCAoIGtleSA9PT0gJ293aW5nJyAmJiBwYXJzZUZsb2F0KCB0b3RhbF9kYXRhLnBhaWQuYW1vdW50ICkgPT09IDAgJiYgcGFyc2VGbG9hdCggdG90YWxfZGF0YS5wcmV2aW91c19iYWxhbmNlLmFtb3VudCApICE9PSAwICkgKSApIHtcblx0XHRcdFx0XHRyZW5kZXJfYXJncyA9IHsgbGFiZWw6IHJvdy5uYW1lLCB2YWx1ZTogcm93LmFtb3VudCB9O1xuXHRcdFx0XHRcdHZhciB0ZW1wbGF0ZSA9IF8udGVtcGxhdGUoIHRoaXMudG90YWxfZGF0YV9yb3dfcmVuZGVyICk7XG5cdFx0XHRcdFx0dGhpcy50b3RhbF9kYXRhX3JlbmRlci5hcHBlbmQoIHRlbXBsYXRlKCByZW5kZXJfYXJncyApICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0dGhpcy52aWV3VG90YWxEYXRhVUkoIHJvdyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gcmVuZGVyX2FyZ3M7XG5cdH1cblxuXHRnZXRTaGlwcGluZ09wdGlvbnMoIHRyYW5zYWN0aW9uX2RhdGEgKSB7XG5cdFx0dmFyICR0aGlzID0gdGhpcztcblx0XHR2YXIgdHJhbnNhY3Rpb25fcmVjb3JkO1xuXHRcdGlmICggR2xvYmFsLmlzU2V0KCB0cmFuc2FjdGlvbl9kYXRhICkgKSB7XG5cdFx0XHR0cmFuc2FjdGlvbl9yZWNvcmQgPSB0cmFuc2FjdGlvbl9kYXRhO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0cmFuc2FjdGlvbl9yZWNvcmQgPSB0aGlzLmVkaXRvci5nZXRWYWx1ZSgpO1xuXHRcdH1cblxuXHRcdGlmICggdGhpcy50cmFuc2FjdGlvbl9wYWlkX2RhdGEgKSB7XG5cdFx0XHR2YXIgdGVtcF90cmFuc2FjdGlvbl9yZWNvcmQgPSBbXTtcblx0XHRcdCQuZWFjaCggdHJhbnNhY3Rpb25fcmVjb3JkLCBmdW5jdGlvbigga2V5LCBpdGVtICkge1xuXHRcdFx0XHR0ZW1wX3RyYW5zYWN0aW9uX3JlY29yZC5wdXNoKCBpdGVtICk7XG5cdFx0XHR9ICk7XG5cdFx0XHQkLmVhY2goIHRoaXMudHJhbnNhY3Rpb25fcGFpZF9kYXRhLCBmdW5jdGlvbigga2V5LCBpdGVtICkge1xuXHRcdFx0XHR0ZW1wX3RyYW5zYWN0aW9uX3JlY29yZC5wdXNoKCBpdGVtICk7XG5cdFx0XHR9ICk7XG5cblx0XHRcdHRyYW5zYWN0aW9uX3JlY29yZCA9IHRlbXBfdHJhbnNhY3Rpb25fcmVjb3JkO1xuXHRcdH1cblxuXHRcdHRoaXMuYXBpLmdldFNoaXBwaW5nT3B0aW9ucyggdHJhbnNhY3Rpb25fcmVjb3JkLCB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQsIHtcblx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzICkge1xuXG5cdFx0XHRcdGlmICggISR0aGlzLmVkaXRfdmlldyApIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR2YXIgcmVzdWx0ID0gcmVzLmdldFJlc3VsdCgpO1xuXHRcdFx0XHR2YXIgY29tYmluZWRfc2hpcHBpbmdfcG9saWN5X2lkID0gJHRoaXMuY3VycmVudF9lZGl0X3JlY29yZC5jb21iaW5lZF9zaGlwcGluZ19wb2xpY3lfaWQ7XG5cdFx0XHRcdCR0aGlzLmVkaXRfdmlld191aV9kaWNbJ2NvbWJpbmVkX3NoaXBwaW5nX3BvbGljeV9pZCddLnNldFNvdXJjZURhdGEoIEdsb2JhbC5idWlsZFJlY29yZEFycmF5KCByZXN1bHQgKSApO1xuXHRcdFx0XHQkdGhpcy5lZGl0X3ZpZXdfdWlfZGljWydjb21iaW5lZF9zaGlwcGluZ19wb2xpY3lfaWQnXS5zZXRWYWx1ZSggY29tYmluZWRfc2hpcHBpbmdfcG9saWN5X2lkICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9XG5cblx0dXBkYXRlU3RhdHVzKCkge1xuXHRcdHZhciAkdGhpcyA9IHRoaXM7XG5cdFx0dGhpcy5hcGlbJ3VwZGF0ZVN0YXR1cyddKCB0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQuaWQsIHtcblx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzICkge1xuXHRcdFx0XHRpZiAoIHJlcy5pc1ZhbGlkKCkgKSB7XG5cdFx0XHRcdFx0dmFyIHN0YXR1c19pZCA9IHJlcy5nZXRSZXN1bHQoKTtcblx0XHRcdFx0XHQkdGhpcy5lZGl0X3ZpZXdfdWlfZGljWydzdGF0dXNfaWQnXS5zZXRWYWx1ZSggc3RhdHVzX2lkICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9ICk7XG5cdH1cblxuXHRpbml0U3ViQ2xpZW50Q29udGFjdFZpZXcoKSB7XG5cdFx0dmFyICR0aGlzID0gdGhpcztcblxuXHRcdGlmICggIXRoaXMuY3VycmVudF9lZGl0X3JlY29yZC5pZCApIHtcblx0XHRcdFRUUHJvbWlzZS5yZXNvbHZlKCAnQmFzZVZpZXdDb250cm9sbGVyJywgJ29uVGFiU2hvdycgKTsgLy9TaW5jZSBzZWFyY2goKSBpc24ndCBjYWxsZWQgaW4gdGhpcyBjYXNlLCBhbmQgd2UganVzdCBkaXNwbGF5IHRoZSBcIlBsZWFzZSBTYXZlIFRoaXMgUmVjb3JkIC4uLlwiIG1lc3NhZ2UsIHJlc29sdmUgdGhlIHByb21pc2UuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCB0aGlzLnN1Yl9jbGllbnRfY29udGFjdF92aWV3X2NvbnRyb2xsZXIgKSB7XG5cdFx0XHR0aGlzLnN1Yl9jbGllbnRfY29udGFjdF92aWV3X2NvbnRyb2xsZXIuYnVpbGRDb250ZXh0TWVudSggdHJ1ZSApO1xuXHRcdFx0dGhpcy5zdWJfY2xpZW50X2NvbnRhY3Rfdmlld19jb250cm9sbGVyLnNldERlZmF1bHRNZW51KCk7XG5cdFx0XHQkdGhpcy5zdWJfY2xpZW50X2NvbnRhY3Rfdmlld19jb250cm9sbGVyLnBhcmVudF9rZXkgPSAnY2xpZW50X2lkJztcblx0XHRcdCR0aGlzLnN1Yl9jbGllbnRfY29udGFjdF92aWV3X2NvbnRyb2xsZXIucGFyZW50X3ZhbHVlID0gJHRoaXMuY3VycmVudF9lZGl0X3JlY29yZC5jbGllbnRfaWQ7XG5cdFx0XHQkdGhpcy5zdWJfY2xpZW50X2NvbnRhY3Rfdmlld19jb250cm9sbGVyLnBhcmVudF9lZGl0X3JlY29yZCA9ICR0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQ7XG5cdFx0XHQkdGhpcy5zdWJfY2xpZW50X2NvbnRhY3Rfdmlld19jb250cm9sbGVyLmluaXREYXRhKCk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0R2xvYmFsLmxvYWRTY3JpcHQoICd2aWV3cy9pbnZvaWNlL2NsaWVudF9jb250YWN0L0NsaWVudENvbnRhY3RWaWV3Q29udHJvbGxlci5qcycsIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHRhYl9jbGllbnRfY29udGFjdHMgPSAkdGhpcy5lZGl0X3ZpZXdfdGFiLmZpbmQoICcjdGFiX2NsaWVudF9jb250YWN0cycgKTtcblx0XHRcdHZhciBmaXJzdENvbHVtbiA9IHRhYl9jbGllbnRfY29udGFjdHMuZmluZCggJy5maXJzdC1jb2x1bW4tc3ViLXZpZXcnICk7XG5cblx0XHRcdEdsb2JhbC50cmFja1ZpZXcoICdTdWInICsgJ0NsaWVudENvbnRhY3QnICsgJ1ZpZXcnICk7XG5cdFx0XHRDbGllbnRDb250YWN0Vmlld0NvbnRyb2xsZXIubG9hZFN1YlZpZXcoIGZpcnN0Q29sdW1uLCBiZWZvcmVMb2FkVmlldywgYWZ0ZXJMb2FkVmlldyApO1xuXG5cdFx0fSApO1xuXG5cdFx0ZnVuY3Rpb24gYmVmb3JlTG9hZFZpZXcoKSB7XG5cblx0XHR9XG5cblx0XHRmdW5jdGlvbiBhZnRlckxvYWRWaWV3KCBzdWJWaWV3Q29udHJvbGxlciApIHtcblx0XHRcdCR0aGlzLnN1Yl9jbGllbnRfY29udGFjdF92aWV3X2NvbnRyb2xsZXIgPSBzdWJWaWV3Q29udHJvbGxlcjtcblx0XHRcdCR0aGlzLnN1Yl9jbGllbnRfY29udGFjdF92aWV3X2NvbnRyb2xsZXIucGFyZW50X2tleSA9ICdjbGllbnRfaWQnO1xuXHRcdFx0JHRoaXMuc3ViX2NsaWVudF9jb250YWN0X3ZpZXdfY29udHJvbGxlci5wYXJlbnRfdmFsdWUgPSAkdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmNsaWVudF9pZDtcblx0XHRcdCR0aGlzLnN1Yl9jbGllbnRfY29udGFjdF92aWV3X2NvbnRyb2xsZXIucGFyZW50X2VkaXRfcmVjb3JkID0gJHRoaXMuY3VycmVudF9lZGl0X3JlY29yZDtcblx0XHRcdCR0aGlzLnN1Yl9jbGllbnRfY29udGFjdF92aWV3X2NvbnRyb2xsZXIucGFyZW50X3ZpZXdfY29udHJvbGxlciA9ICR0aGlzO1xuXHRcdFx0JHRoaXMuc3ViX2NsaWVudF9jb250YWN0X3ZpZXdfY29udHJvbGxlci5wb3N0SW5pdCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR0aGlzLmluaXREYXRhKCk7XG5cdFx0XHR9O1xuXHRcdH1cblx0fVxuXG5cdGluaXRTdWJDbGllbnRQYXltZW50VmlldygpIHtcblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXG5cdFx0aWYgKCAhdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmlkICkge1xuXHRcdFx0VFRQcm9taXNlLnJlc29sdmUoICdCYXNlVmlld0NvbnRyb2xsZXInLCAnb25UYWJTaG93JyApOyAvL1NpbmNlIHNlYXJjaCgpIGlzbid0IGNhbGxlZCBpbiB0aGlzIGNhc2UsIGFuZCB3ZSBqdXN0IGRpc3BsYXkgdGhlIFwiUGxlYXNlIFNhdmUgVGhpcyBSZWNvcmQgLi4uXCIgbWVzc2FnZSwgcmVzb2x2ZSB0aGUgcHJvbWlzZS5cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoIHRoaXMuc3ViX2NsaWVudF9wYXltZW50X3ZpZXdfY29udHJvbGxlciApIHtcblx0XHRcdHRoaXMuc3ViX2NsaWVudF9wYXltZW50X3ZpZXdfY29udHJvbGxlci5idWlsZENvbnRleHRNZW51KCB0cnVlICk7XG5cdFx0XHR0aGlzLnN1Yl9jbGllbnRfcGF5bWVudF92aWV3X2NvbnRyb2xsZXIuc2V0RGVmYXVsdE1lbnUoKTtcblx0XHRcdCR0aGlzLnN1Yl9jbGllbnRfcGF5bWVudF92aWV3X2NvbnRyb2xsZXIucGFyZW50X2tleSA9ICdjbGllbnRfaWQnO1xuXHRcdFx0JHRoaXMuc3ViX2NsaWVudF9wYXltZW50X3ZpZXdfY29udHJvbGxlci5wYXJlbnRfdmFsdWUgPSAkdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmNsaWVudF9pZDtcblx0XHRcdCR0aGlzLnN1Yl9jbGllbnRfcGF5bWVudF92aWV3X2NvbnRyb2xsZXIucGFyZW50X2VkaXRfcmVjb3JkID0gJHRoaXMuY3VycmVudF9lZGl0X3JlY29yZDtcblx0XHRcdCR0aGlzLnN1Yl9jbGllbnRfcGF5bWVudF92aWV3X2NvbnRyb2xsZXIuaW5pdERhdGEoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRHbG9iYWwubG9hZFNjcmlwdCggJ3ZpZXdzL2ludm9pY2UvY2xpZW50X3BheW1lbnQvQ2xpZW50UGF5bWVudFZpZXdDb250cm9sbGVyLmpzJywgZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgdGFiX3BheW1lbnRfbWV0aG9kcyA9ICR0aGlzLmVkaXRfdmlld190YWIuZmluZCggJyN0YWJfcGF5bWVudF9tZXRob2RzJyApO1xuXHRcdFx0dmFyIGZpcnN0Q29sdW1uID0gdGFiX3BheW1lbnRfbWV0aG9kcy5maW5kKCAnLmZpcnN0LWNvbHVtbi1zdWItdmlldycgKTtcblxuXHRcdFx0R2xvYmFsLnRyYWNrVmlldyggJ1N1YicgKyAnQ2xpZW50UGF5bWVudCcgKyAnVmlldycgKTtcblx0XHRcdENsaWVudFBheW1lbnRWaWV3Q29udHJvbGxlci5sb2FkU3ViVmlldyggZmlyc3RDb2x1bW4sIGJlZm9yZUxvYWRWaWV3LCBhZnRlckxvYWRWaWV3ICk7XG5cblx0XHR9ICk7XG5cblx0XHRmdW5jdGlvbiBiZWZvcmVMb2FkVmlldygpIHtcblxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIGFmdGVyTG9hZFZpZXcoIHN1YlZpZXdDb250cm9sbGVyICkge1xuXHRcdFx0JHRoaXMuc3ViX2NsaWVudF9wYXltZW50X3ZpZXdfY29udHJvbGxlciA9IHN1YlZpZXdDb250cm9sbGVyO1xuXHRcdFx0JHRoaXMuc3ViX2NsaWVudF9wYXltZW50X3ZpZXdfY29udHJvbGxlci5wYXJlbnRfa2V5ID0gJ2NsaWVudF9pZCc7XG5cdFx0XHQkdGhpcy5zdWJfY2xpZW50X3BheW1lbnRfdmlld19jb250cm9sbGVyLnBhcmVudF92YWx1ZSA9ICR0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQuY2xpZW50X2lkO1xuXHRcdFx0JHRoaXMuc3ViX2NsaWVudF9wYXltZW50X3ZpZXdfY29udHJvbGxlci5wYXJlbnRfZWRpdF9yZWNvcmQgPSAkdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkO1xuXHRcdFx0JHRoaXMuc3ViX2NsaWVudF9wYXltZW50X3ZpZXdfY29udHJvbGxlci5wYXJlbnRfdmlld19jb250cm9sbGVyID0gJHRoaXM7XG5cdFx0XHQkdGhpcy5zdWJfY2xpZW50X3BheW1lbnRfdmlld19jb250cm9sbGVyLnBvc3RJbml0ID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHRoaXMuaW5pdERhdGEoKTtcblx0XHRcdH07XG5cdFx0fVxuXHR9XG5cblx0aW5pdFN1YlRyYW5zYWN0aW9uVmlldygpIHtcblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXG5cdFx0aWYgKCAhdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkLmlkICkge1xuXHRcdFx0VFRQcm9taXNlLnJlc29sdmUoICdCYXNlVmlld0NvbnRyb2xsZXInLCAnb25UYWJTaG93JyApOyAvL1NpbmNlIHNlYXJjaCgpIGlzbid0IGNhbGxlZCBpbiB0aGlzIGNhc2UsIGFuZCB3ZSBqdXN0IGRpc3BsYXkgdGhlIFwiUGxlYXNlIFNhdmUgVGhpcyBSZWNvcmQgLi4uXCIgbWVzc2FnZSwgcmVzb2x2ZSB0aGUgcHJvbWlzZS5cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoIHRoaXMuc3ViX3RyYW5zYWN0aW9uX3ZpZXdfY29udHJvbGxlciApIHtcblx0XHRcdHRoaXMuc3ViX3RyYW5zYWN0aW9uX3ZpZXdfY29udHJvbGxlci5idWlsZENvbnRleHRNZW51KCB0cnVlICk7XG5cdFx0XHR0aGlzLnN1Yl90cmFuc2FjdGlvbl92aWV3X2NvbnRyb2xsZXIuc2V0RGVmYXVsdE1lbnUoKTtcblx0XHRcdCR0aGlzLnN1Yl90cmFuc2FjdGlvbl92aWV3X2NvbnRyb2xsZXIucGFyZW50X2tleSA9ICdpbnZvaWNlX2lkJztcblx0XHRcdCR0aGlzLnN1Yl90cmFuc2FjdGlvbl92aWV3X2NvbnRyb2xsZXIucGFyZW50X3ZhbHVlID0gJHRoaXMuY3VycmVudF9lZGl0X3JlY29yZC5pZDtcblx0XHRcdCR0aGlzLnN1Yl90cmFuc2FjdGlvbl92aWV3X2NvbnRyb2xsZXIucGFyZW50X2VkaXRfcmVjb3JkID0gJHRoaXMuY3VycmVudF9lZGl0X3JlY29yZDtcblx0XHRcdCR0aGlzLnN1Yl90cmFuc2FjdGlvbl92aWV3X2NvbnRyb2xsZXIuaW5pdERhdGEoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRHbG9iYWwubG9hZFNjcmlwdCggJ3ZpZXdzL2ludm9pY2UvaW52b2ljZV90cmFuc2FjdGlvbi9JbnZvaWNlVHJhbnNhY3Rpb25WaWV3Q29udHJvbGxlci5qcycsIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHRhYl90cmFuc2FjdGlvbnMgPSAkdGhpcy5lZGl0X3ZpZXdfdGFiLmZpbmQoICcjdGFiX3RyYW5zYWN0aW9ucycgKTtcblx0XHRcdHZhciBmaXJzdENvbHVtbiA9IHRhYl90cmFuc2FjdGlvbnMuZmluZCggJy5maXJzdC1jb2x1bW4tc3ViLXZpZXcnICk7XG5cblx0XHRcdEdsb2JhbC50cmFja1ZpZXcoICdTdWInICsgJ0ludm9pY2VUcmFuc2FjdGlvbicgKyAnVmlldycgKTtcblx0XHRcdEludm9pY2VUcmFuc2FjdGlvblZpZXdDb250cm9sbGVyLmxvYWRTdWJWaWV3KCBmaXJzdENvbHVtbiwgYmVmb3JlTG9hZFZpZXcsIGFmdGVyTG9hZFZpZXcgKTtcblxuXHRcdH0gKTtcblxuXHRcdGZ1bmN0aW9uIGJlZm9yZUxvYWRWaWV3KCkge1xuXG5cdFx0fVxuXG5cdFx0ZnVuY3Rpb24gYWZ0ZXJMb2FkVmlldyggc3ViVmlld0NvbnRyb2xsZXIgKSB7XG5cdFx0XHQkdGhpcy5zdWJfdHJhbnNhY3Rpb25fdmlld19jb250cm9sbGVyID0gc3ViVmlld0NvbnRyb2xsZXI7XG5cdFx0XHQkdGhpcy5zdWJfdHJhbnNhY3Rpb25fdmlld19jb250cm9sbGVyLnBhcmVudF9rZXkgPSAnaW52b2ljZV9pZCc7XG5cdFx0XHQkdGhpcy5zdWJfdHJhbnNhY3Rpb25fdmlld19jb250cm9sbGVyLnBhcmVudF92YWx1ZSA9ICR0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQuaWQ7XG5cdFx0XHQkdGhpcy5zdWJfdHJhbnNhY3Rpb25fdmlld19jb250cm9sbGVyLnBhcmVudF9lZGl0X3JlY29yZCA9ICR0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQ7XG5cdFx0XHQkdGhpcy5zdWJfdHJhbnNhY3Rpb25fdmlld19jb250cm9sbGVyLnBhcmVudF92aWV3X2NvbnRyb2xsZXIgPSAkdGhpcztcblx0XHRcdCR0aGlzLnN1Yl90cmFuc2FjdGlvbl92aWV3X2NvbnRyb2xsZXIucG9zdEluaXQgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0dGhpcy5pbml0RGF0YSgpO1xuXHRcdFx0fTtcblx0XHR9XG5cdH1cblxuXHRyZW1vdmVFZGl0VmlldygpIHtcblx0XHRzdXBlci5yZW1vdmVFZGl0VmlldygpO1xuXHRcdHRoaXMuaGlzdG9yeSA9IG51bGw7XG5cdFx0dGhpcy5lZGl0b3IgPSBudWxsO1xuXHRcdHRoaXMudG90YWxfZGF0YV9yZW5kZXIgPSBudWxsO1xuXHRcdHRoaXMudG90YWxfZGF0YV9yb3dfcmVuZGVyID0gbnVsbDtcblx0XHR0aGlzLnRyYW5zYWN0aW9uX3BhaWRfZGF0YSA9IG51bGw7XG5cdFx0dGhpcy5zdWJfY2xpZW50X2NvbnRhY3Rfdmlld19jb250cm9sbGVyID0gbnVsbDtcblx0XHR0aGlzLnN1Yl9jbGllbnRfcGF5bWVudF92aWV3X2NvbnRyb2xsZXIgPSBudWxsO1xuXHRcdHRoaXMuc3ViX3RyYW5zYWN0aW9uX3ZpZXdfY29udHJvbGxlciA9IG51bGw7XG5cdH1cblxuXHRpbnNpZGVFZGl0b3JBZGRSb3coIGRhdGEsIGluZGV4ICkge1xuXHRcdHZhciBmb3JtX2l0ZW1faW5wdXQ7XG5cdFx0dmFyIHdpZGdldENvbnRhaW5lcjtcblxuXHRcdHZhciByb3cgPSB0aGlzLmdldFJvd1JlbmRlcigpOyAvL0dldCBSb3cgcmVuZGVyXG5cdFx0dmFyIHJlbmRlciA9IHRoaXMuZ2V0UmVuZGVyKCk7IC8vZ2V0IHJlbmRlciwgc2hvdWxkIGJlIGEgdGFibGVcblx0XHR2YXIgd2lkZ2V0cyA9IHt9OyAvL1NhdmUgZWFjaCByb3cncyB3aWRnZXRzXG5cblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXHRcdGlmICggIWRhdGEgKSB7XG5cdFx0XHR0aGlzLmdldERlZmF1bHREYXRhKCBpbmRleCApO1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vU2F2ZSBjdXJyZW50IHNldCBpdGVtXG5cdFx0XHR3aWRnZXRzLmN1cnJlbnRfZWRpdF9pdGVtID0gZGF0YTtcblxuXHRcdFx0Ly9CdWlsZCByb3cgd2lkZ2V0c1xuXG5cdFx0XHQvLyBQcm9kdWN0XG5cdFx0XHR2YXIgYXJncyA9IHt9O1xuXHRcdFx0YXJncy5maWx0ZXJfZGF0YSA9IHt9O1xuXHRcdFx0YXJncy5maWx0ZXJfZGF0YS50eXBlX2lkID0gWzEwLCAyMF07XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLkFXRVNPTUVfQk9YICk7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuQUNvbWJvQm94KCB7XG5cdFx0XHRcdHdpZHRoOiAyMDMsXG5cdFx0XHRcdGlzX3N0YXRpY193aWR0aDogdHJ1ZSxcblx0XHRcdFx0YXBpX2NsYXNzOiBUVEFQSS5BUElQcm9kdWN0LFxuXHRcdFx0XHRhbGxvd19tdWx0aXBsZV9zZWxlY3Rpb246IGZhbHNlLFxuXHRcdFx0XHRsYXlvdXRfbmFtZTogJ2dsb2JhbF9wcm9kdWN0Jyxcblx0XHRcdFx0c2hvd19zZWFyY2hfaW5wdXRzOiB0cnVlLFxuXHRcdFx0XHRzZXRfZW1wdHk6IHRydWUsXG5cdFx0XHRcdGZpZWxkOiAncHJvZHVjdF9pZCdcblx0XHRcdH0gKTtcblx0XHRcdGZvcm1faXRlbV9pbnB1dC5zZXREZWZhdWx0QXJncyggYXJncyApO1xuXHRcdFx0Zm9ybV9pdGVtX2lucHV0LnNldFZhbHVlKCBkYXRhLnByb2R1Y3RfaWQgPyBkYXRhLnByb2R1Y3RfaWQgOiAnJyApO1xuXHRcdFx0d2lkZ2V0c1tmb3JtX2l0ZW1faW5wdXQuZ2V0RmllbGQoKV0gPSBmb3JtX2l0ZW1faW5wdXQ7XG5cdFx0XHRyb3cuY2hpbGRyZW4oKS5lcSggMCApLmFwcGVuZCggZm9ybV9pdGVtX2lucHV0ICk7XG5cblx0XHRcdHRoaXMuc2V0V2lkZ2V0RW5hYmxlQmFzZU9uUGFyZW50Q29udHJvbGxlciggZm9ybV9pdGVtX2lucHV0ICk7XG5cblx0XHRcdGZvcm1faXRlbV9pbnB1dC5iaW5kKCAnZm9ybUl0ZW1DaGFuZ2UnLCBmdW5jdGlvbiggZSwgdGFyZ2V0ICkge1xuXHRcdFx0XHQkdGhpcy5wYXJlbnRfY29udHJvbGxlci5vblJvd0NoYW5nZXMoICQoIHRoaXMgKS5wYXJlbnQoKS5wYXJlbnQoKS5pbmRleCgpIC0gMSwgdGFyZ2V0ICk7XG5cdFx0XHR9ICk7XG5cblx0XHRcdC8vIERlc2NyaXB0aW9uXG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLlRFWFRfSU5QVVQgKTtcblx0XHRcdGZvcm1faXRlbV9pbnB1dC5UVGV4dElucHV0KCB7IGZpZWxkOiAnZGVzY3JpcHRpb24nLCB3aWR0aDogNTAwIH0gKTtcblx0XHRcdGZvcm1faXRlbV9pbnB1dC5zZXRWYWx1ZSggZGF0YS5kZXNjcmlwdGlvbiA/IGRhdGEuZGVzY3JpcHRpb24gOiAnJyApO1xuXHRcdFx0d2lkZ2V0c1tmb3JtX2l0ZW1faW5wdXQuZ2V0RmllbGQoKV0gPSBmb3JtX2l0ZW1faW5wdXQ7XG5cdFx0XHRyb3cuY2hpbGRyZW4oKS5lcSggMSApLmFwcGVuZCggZm9ybV9pdGVtX2lucHV0ICk7XG5cblx0XHRcdHRoaXMuc2V0V2lkZ2V0RW5hYmxlQmFzZU9uUGFyZW50Q29udHJvbGxlciggZm9ybV9pdGVtX2lucHV0ICk7XG5cblx0XHRcdC8vIFFUWVxuXHRcdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5URVhUX0lOUFVUICk7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuVFRleHRJbnB1dCggeyBmaWVsZDogJ3F1YW50aXR5Jywgd2lkdGg6IDUwLCBub192YWxpZGF0ZV90aW1lcl9zZWM6IDEwMCB9ICk7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuc2V0VmFsdWUoIGRhdGEucXVhbnRpdHkgPyBkYXRhLnF1YW50aXR5IDogJycgKTtcblxuXHRcdFx0Zm9ybV9pdGVtX2lucHV0LmJpbmQoICdmb3JtSXRlbUNoYW5nZScsIGZ1bmN0aW9uKCBlLCB0YXJnZXQsIGRvTm90VmFsaWRhdGUgKSB7XG5cdFx0XHRcdGlmICggZG9Ob3RWYWxpZGF0ZSApIHtcblx0XHRcdFx0XHQkdGhpcy5wYXJlbnRfY29udHJvbGxlci5vblJvd0NoYW5nZXMoICQoIHRoaXMgKS5wYXJlbnQoKS5wYXJlbnQoKS5pbmRleCgpIC0gMSwgdGFyZ2V0ICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblxuXHRcdFx0d2lkZ2V0c1tmb3JtX2l0ZW1faW5wdXQuZ2V0RmllbGQoKV0gPSBmb3JtX2l0ZW1faW5wdXQ7XG5cdFx0XHRyb3cuY2hpbGRyZW4oKS5lcSggMiApLmFwcGVuZCggZm9ybV9pdGVtX2lucHV0ICk7XG5cblx0XHRcdHRoaXMuc2V0V2lkZ2V0RW5hYmxlQmFzZU9uUGFyZW50Q29udHJvbGxlciggZm9ybV9pdGVtX2lucHV0ICk7XG5cblx0XHRcdC8vIFByaWNlXG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQgPSBHbG9iYWwubG9hZFdpZGdldEJ5TmFtZSggRm9ybUl0ZW1UeXBlLlRFWFRfSU5QVVQgKTtcblx0XHRcdGZvcm1faXRlbV9pbnB1dC5UVGV4dElucHV0KCB7IGZpZWxkOiAndW5pdF9wcmljZScsIHdpZHRoOiA1MCwgbm9fdmFsaWRhdGVfdGltZXJfc2VjOiAxMDAgfSApO1xuXHRcdFx0Zm9ybV9pdGVtX2lucHV0LnNldFZhbHVlKCBkYXRhLnVuaXRfcHJpY2UgPyBkYXRhLnVuaXRfcHJpY2UgOiAnJyApO1xuXG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuYmluZCggJ2Zvcm1JdGVtQ2hhbmdlJywgZnVuY3Rpb24oIGUsIHRhcmdldCwgZG9Ob3RWYWxpZGF0ZSApIHtcblx0XHRcdFx0aWYgKCBkb05vdFZhbGlkYXRlICkge1xuXHRcdFx0XHRcdCR0aGlzLnBhcmVudF9jb250cm9sbGVyLm9uUm93Q2hhbmdlcyggJCggdGhpcyApLnBhcmVudCgpLnBhcmVudCgpLmluZGV4KCkgLSAxLCB0YXJnZXQgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXG5cdFx0XHR3aWRnZXRzW2Zvcm1faXRlbV9pbnB1dC5nZXRGaWVsZCgpXSA9IGZvcm1faXRlbV9pbnB1dDtcblx0XHRcdHJvdy5jaGlsZHJlbigpLmVxKCAzICkuYXBwZW5kKCBmb3JtX2l0ZW1faW5wdXQgKTtcblxuXHRcdFx0dGhpcy5zZXRXaWRnZXRFbmFibGVCYXNlT25QYXJlbnRDb250cm9sbGVyKCBmb3JtX2l0ZW1faW5wdXQgKTtcblxuXHRcdFx0Ly8gUHJvUmF0ZVxuXHRcdFx0d2lkZ2V0Q29udGFpbmVyID0gJCggJzxkaXYgY2xhc3M9XFwnd2lkZ2V0LWgtYm94XFwnPjwvZGl2PicgKTtcblx0XHRcdGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuVEVYVF9JTlBVVCApO1xuXHRcdFx0Zm9ybV9pdGVtX2lucHV0LlRUZXh0SW5wdXQoIHsgZmllbGQ6ICdwcm9fcmF0ZV9udW1lcmF0b3InLCB3aWR0aDogNTAsIG5vX3ZhbGlkYXRlX3RpbWVyX3NlYzogMTAwIH0gKTtcblx0XHRcdGZvcm1faXRlbV9pbnB1dC5zZXRWYWx1ZSggZGF0YS5wcm9fcmF0ZV9udW1lcmF0b3IgPyBkYXRhLnByb19yYXRlX251bWVyYXRvciA6IDEgKTtcblx0XHRcdGZvcm1faXRlbV9pbnB1dC5hdHRyKCAnbWF4bGVuZ3RoJywgMyApO1xuXG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuYmluZCggJ2Zvcm1JdGVtQ2hhbmdlJywgZnVuY3Rpb24oIGUsIHRhcmdldCwgZG9Ob3RWYWxpZGF0ZSApIHtcblx0XHRcdFx0aWYgKCBkb05vdFZhbGlkYXRlICkge1xuXHRcdFx0XHRcdCR0aGlzLnBhcmVudF9jb250cm9sbGVyLm9uUm93Q2hhbmdlcyggJCggdGhpcyApLnBhcmVudCgpLnBhcmVudCgpLnBhcmVudCgpLmluZGV4KCkgLSAxLCB0YXJnZXQgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXG5cdFx0XHR3aWRnZXRzW2Zvcm1faXRlbV9pbnB1dC5nZXRGaWVsZCgpXSA9IGZvcm1faXRlbV9pbnB1dDtcblx0XHRcdHdpZGdldENvbnRhaW5lci5hcHBlbmQoIGZvcm1faXRlbV9pbnB1dCApO1xuXG5cdFx0XHR2YXIgbGFiZWwgPSAkKCAnPHNwYW4gY2xhc3M9XFwnd2lkZ2V0LXJpZ2h0LWxhYmVsXFwnPi88L3NwYW4+JyApO1xuXHRcdFx0d2lkZ2V0Q29udGFpbmVyLmFwcGVuZCggbGFiZWwgKTtcblxuXHRcdFx0dGhpcy5zZXRXaWRnZXRFbmFibGVCYXNlT25QYXJlbnRDb250cm9sbGVyKCBmb3JtX2l0ZW1faW5wdXQgKTtcblxuXHRcdFx0Zm9ybV9pdGVtX2lucHV0ID0gR2xvYmFsLmxvYWRXaWRnZXRCeU5hbWUoIEZvcm1JdGVtVHlwZS5URVhUX0lOUFVUICk7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuVFRleHRJbnB1dCggeyBmaWVsZDogJ3Byb19yYXRlX2Rlbm9taW5hdG9yJywgd2lkdGg6IDUwLCBub192YWxpZGF0ZV90aW1lcl9zZWM6IDEwMCB9ICk7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuc2V0VmFsdWUoIGRhdGEucHJvX3JhdGVfZGVub21pbmF0b3IgPyBkYXRhLnByb19yYXRlX2Rlbm9taW5hdG9yIDogMSApO1xuXHRcdFx0Zm9ybV9pdGVtX2lucHV0LmF0dHIoICdtYXhsZW5ndGgnLCAzICk7XG5cblx0XHRcdGZvcm1faXRlbV9pbnB1dC5iaW5kKCAnZm9ybUl0ZW1DaGFuZ2UnLCBmdW5jdGlvbiggZSwgdGFyZ2V0LCBkb05vdFZhbGlkYXRlICkge1xuXHRcdFx0XHRpZiAoIGRvTm90VmFsaWRhdGUgKSB7XG5cdFx0XHRcdFx0JHRoaXMucGFyZW50X2NvbnRyb2xsZXIub25Sb3dDaGFuZ2VzKCAkKCB0aGlzICkucGFyZW50KCkucGFyZW50KCkucGFyZW50KCkuaW5kZXgoKSAtIDEsIHRhcmdldCApO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cblx0XHRcdHdpZGdldHNbZm9ybV9pdGVtX2lucHV0LmdldEZpZWxkKCldID0gZm9ybV9pdGVtX2lucHV0O1xuXHRcdFx0d2lkZ2V0Q29udGFpbmVyLmFwcGVuZCggZm9ybV9pdGVtX2lucHV0ICk7XG5cblx0XHRcdHJvdy5jaGlsZHJlbigpLmVxKCA0ICkuYXBwZW5kKCB3aWRnZXRDb250YWluZXIgKTtcblxuXHRcdFx0dGhpcy5zZXRXaWRnZXRFbmFibGVCYXNlT25QYXJlbnRDb250cm9sbGVyKCBmb3JtX2l0ZW1faW5wdXQgKTtcblxuXHRcdFx0Ly8gVG90YWxcblx0XHRcdGZvcm1faXRlbV9pbnB1dCA9IEdsb2JhbC5sb2FkV2lkZ2V0QnlOYW1lKCBGb3JtSXRlbVR5cGUuVEVYVF9JTlBVVCApO1xuXHRcdFx0Zm9ybV9pdGVtX2lucHV0LlRUZXh0SW5wdXQoIHsgZmllbGQ6ICdhbW91bnQnLCB3aWR0aDogMTAwIH0gKTtcblx0XHRcdGZvcm1faXRlbV9pbnB1dC5zZXRWYWx1ZSggZGF0YS5hbW91bnQgPyBkYXRhLmFtb3VudCA6ICcnICk7XG5cdFx0XHRmb3JtX2l0ZW1faW5wdXQuc2V0UmVhZE9ubHkoIHRydWUgKTtcbi8vXHRcdFx0Zm9ybV9pdGVtX2lucHV0LmF0dHIoICdyZWFkb25seScsICdyZWFkb25seScgKTtcblxuXHRcdFx0d2lkZ2V0c1tmb3JtX2l0ZW1faW5wdXQuZ2V0RmllbGQoKV0gPSBmb3JtX2l0ZW1faW5wdXQ7XG5cdFx0XHRyb3cuY2hpbGRyZW4oKS5lcSggNSApLmFwcGVuZCggZm9ybV9pdGVtX2lucHV0ICk7XG5cblx0XHRcdGlmICggdHlwZW9mIGluZGV4ICE9ICd1bmRlZmluZWQnICkge1xuXG5cdFx0XHRcdHJvdy5pbnNlcnRBZnRlciggJCggcmVuZGVyICkuZmluZCggJ3RyJyApLmVxKCBpbmRleCApICk7XG5cdFx0XHRcdHRoaXMucm93c193aWRnZXRzX2FycmF5LnNwbGljZSggKCBpbmRleCApLCAwLCB3aWRnZXRzICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdCQoIHJlbmRlciApLmFwcGVuZCggcm93ICk7XG5cdFx0XHRcdHRoaXMucm93c193aWRnZXRzX2FycmF5LnB1c2goIHdpZGdldHMgKTtcblx0XHRcdH1cblx0XHRcdGlmICggdGhpcy5wYXJlbnRfY29udHJvbGxlci5pc192aWV3aW5nICkge1xuXHRcdFx0XHRyb3cuZmluZCggJy5jb250cm9sLWljb24nICkuaGlkZSgpO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnNldFdpZGdldEVuYWJsZUJhc2VPblBhcmVudENvbnRyb2xsZXIoIGZvcm1faXRlbV9pbnB1dCApO1xuXG5cdFx0XHR2YXIgcGx1c19pY29uID0gcm93LmZpbmQoICcucGx1cy1pY29uJyApO1xuXHRcdFx0dmFyIG1pbnVzX2ljb24gPSByb3cuZmluZCggJy5taW51cy1pY29uJyApO1xuXG5cdFx0XHRwbHVzX2ljb24uY2xpY2soIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHQkdGhpcy5wYXJlbnRfY29udHJvbGxlci5zZXRQYXltZW50SWNvbkRpc2FibGVkKCk7XG5cdFx0XHRcdCR0aGlzLmFkZFJvdyggbnVsbCwgJCggdGhpcyApLnBhcmVudCgpLnBhcmVudCgpLmluZGV4KCkgKTtcblx0XHRcdH0gKTtcblxuXHRcdFx0bWludXNfaWNvbi5jbGljayggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdCR0aGlzLnBhcmVudF9jb250cm9sbGVyLnNldFBheW1lbnRJY29uRGlzYWJsZWQoKTtcblx0XHRcdFx0JHRoaXMucmVtb3ZlUm93KCByb3cgKTtcblxuXHRcdFx0XHRpZiAoIHJlbmRlci5maW5kKCAndHInICkubGVuZ3RoID09PSAxICkge1xuXHRcdFx0XHRcdCR0aGlzLmFkZFJvdygpO1xuXHRcdFx0XHR9XG5cblx0XHRcdH0gKTtcblxuLy9cdFx0XHR0aGlzLmFkZEljb25zRXZlbnQoIHJvdyApOyAvL0JpbmQgZXZlbnQgdG8gYWRkIGFuZCBtaW51cyBpY29uXG5cdFx0XHR0aGlzLnJlbW92ZUxhc3RSb3dMaW5lKCk7XG5cdFx0fVxuXG5cdFx0aWYgKCBkYXRhICYmIFRUVVVJRC5pc1VVSUQoIGRhdGEucHJvZHVjdF9pZCApICYmIGRhdGEucHJvZHVjdF9pZCAhPSBUVFVVSUQuemVyb19pZCApIHtcblx0XHRcdHZhciBmaWx0ZXIgPSB7fTtcblx0XHRcdGZpbHRlci5maWx0ZXJfZGF0YSA9IHt9O1xuXHRcdFx0ZmlsdGVyLmZpbHRlcl9kYXRhLmlkID0gZGF0YS5wcm9kdWN0X2lkO1xuXHRcdFx0ZmlsdGVyLmZpbHRlcl9jb2x1bW5zID0geyBpZDogdHJ1ZSwgcHJpY2VfbG9ja2VkOiB0cnVlLCBkZXNjcmlwdGlvbl9sb2NrZWQ6IHRydWUgfTtcblx0XHRcdHRoaXMucGFyZW50X2NvbnRyb2xsZXIucHJvZHVjdF9hcGlbJ2dldCcgKyB0aGlzLnBhcmVudF9jb250cm9sbGVyLnByb2R1Y3RfYXBpLmtleV9uYW1lXSggZmlsdGVyLCB7XG5cdFx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcmVzICkge1xuXHRcdFx0XHRcdHZhciByZXN1bHQgPSByZXMuZ2V0UmVzdWx0KClbMF07XG5cdFx0XHRcdFx0d2lkZ2V0c1snZGVzY3JpcHRpb24nXS5zZXRSZWFkT25seSggcmVzdWx0LmRlc2NyaXB0aW9uX2xvY2tlZCApO1xuXHRcdFx0XHRcdHdpZGdldHNbJ3VuaXRfcHJpY2UnXS5zZXRSZWFkT25seSggcmVzdWx0LnByaWNlX2xvY2tlZCApO1xuXHRcdFx0XHR9XG5cdFx0XHR9ICk7XG5cdFx0fVxuXHR9XG5cblx0aW5zaWRlRWRpdG9yUmVtb3ZlUm93KCByb3cgKSB7XG5cdFx0dmFyIGluZGV4ID0gcm93WzBdLnJvd0luZGV4IC0gMTtcblx0XHR2YXIgcmVtb3ZlX2lkID0gdGhpcy5yb3dzX3dpZGdldHNfYXJyYXlbaW5kZXhdLmN1cnJlbnRfZWRpdF9pdGVtLmlkO1xuXHRcdGlmICggVFRVVUlELmlzVVVJRCggcmVtb3ZlX2lkICkgJiYgcmVtb3ZlX2lkICE9IFRUVVVJRC56ZXJvX2lkICYmIHJlbW92ZV9pZCAhPSBUVFVVSUQubm90X2V4aXN0X2lkICkge1xuXHRcdFx0dGhpcy5kZWxldGVfaWRzLnB1c2goIHJlbW92ZV9pZCApO1xuXHRcdH1cblx0XHRyb3cucmVtb3ZlKCk7XG5cdFx0dGhpcy5yb3dzX3dpZGdldHNfYXJyYXkuc3BsaWNlKCBpbmRleCwgMSApO1xuXHRcdHRoaXMucGFyZW50X2NvbnRyb2xsZXIuZ2V0SW52b2ljZVRvdGFsRGF0YSgpO1xuXHRcdHRoaXMucmVtb3ZlTGFzdFJvd0xpbmUoKTtcblx0fVxuXG5cdG9uUm93Q2hhbmdlcyggaW5kZXgsIHRhcmdldCApIHtcblx0XHR0aGlzLnNldFBheW1lbnRJY29uRGlzYWJsZWQoKTtcblx0XHR2YXIgJHRoaXMgPSB0aGlzO1xuXHRcdHZhciBjdXJyZW50X3JvdyA9IHRoaXMuZWRpdG9yLnJvd3Nfd2lkZ2V0c19hcnJheVtpbmRleF07XG5cdFx0dmFyIGtleSA9IHRhcmdldC5nZXRGaWVsZCgpO1xuXHRcdHZhciB2YWx1ZSA9IHRhcmdldC5nZXRWYWx1ZSgpO1xuXHRcdHZhciBmaWx0ZXIgPSB7fTtcblx0XHRmaWx0ZXIuZmlsdGVyX2RhdGEgPSB7fTtcblx0XHRmaWx0ZXIuZmlsdGVyX2NvbHVtbnMgPSB7fTtcblx0XHRmaWx0ZXIuZmlsdGVyX2NvbHVtbnMuZGVzY3JpcHRpb24gPSB0cnVlO1xuXHRcdGZpbHRlci5maWx0ZXJfY29sdW1ucy5uYW1lID0gdHJ1ZTtcblx0XHRmaWx0ZXIuZmlsdGVyX2NvbHVtbnMucGFydF9udW1iZXIgPSB0cnVlO1xuXHRcdGZpbHRlci5maWx0ZXJfY29sdW1ucy50eXBlX2lkID0gdHJ1ZTtcblx0XHRmaWx0ZXIuZmlsdGVyX2NvbHVtbnMuY3VycmVuY3lfaWQgPSB0cnVlO1xuXHRcdGZpbHRlci5maWx0ZXJfY29sdW1ucy5pZCA9IHRydWU7XG5cdFx0ZmlsdGVyLmZpbHRlcl9jb2x1bW5zLnByaWNlX2xvY2tlZCA9IHRydWU7XG5cdFx0ZmlsdGVyLmZpbHRlcl9jb2x1bW5zLmRlc2NyaXB0aW9uX2xvY2tlZCA9IHRydWU7XG5cblx0XHRzd2l0Y2ggKCBrZXkgKSB7XG5cdFx0XHRjYXNlICdxdWFudGl0eSc6XG5cdFx0XHRjYXNlICdwcm9kdWN0X2lkJzpcblx0XHRcdFx0dmFyIHByb2R1Y3RfaWQ7XG5cdFx0XHRcdHZhciBxdWFudGl0eTtcblx0XHRcdFx0aWYgKCBrZXkgPT09ICdwcm9kdWN0X2lkJyApIHtcblx0XHRcdFx0XHRxdWFudGl0eSA9IDE7XG5cdFx0XHRcdFx0cHJvZHVjdF9pZCA9IHZhbHVlO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHF1YW50aXR5ID0gdmFsdWU7XG5cdFx0XHRcdFx0cHJvZHVjdF9pZCA9IGN1cnJlbnRfcm93Wydwcm9kdWN0X2lkJ10uZ2V0VmFsdWUoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIFRUVVVJRC5pc1VVSUQoIHByb2R1Y3RfaWQgKSAmJiBwcm9kdWN0X2lkICE9IFRUVVVJRC56ZXJvX2lkICkge1xuXHRcdFx0XHRcdGZpbHRlci5maWx0ZXJfZGF0YS5pZCA9IHByb2R1Y3RfaWQ7XG5cdFx0XHRcdFx0dGhpcy5wcm9kdWN0X2FwaVsnZ2V0JyArIHRoaXMucHJvZHVjdF9hcGkua2V5X25hbWVdKCBmaWx0ZXIsIHtcblx0XHRcdFx0XHRcdG9uUmVzdWx0OiBmdW5jdGlvbiggcF9yZXMgKSB7XG5cdFx0XHRcdFx0XHRcdHZhciByZXN1bHRfZGF0YSA9IHBfcmVzLmdldFJlc3VsdCgpWzBdO1xuXHRcdFx0XHRcdFx0XHRpZiAoIGtleSA9PT0gJ3Byb2R1Y3RfaWQnICkge1xuXHRcdFx0XHRcdFx0XHRcdGN1cnJlbnRfcm93WydkZXNjcmlwdGlvbiddLnNldFZhbHVlKCByZXN1bHRfZGF0YVsnZGVzY3JpcHRpb24nXSApO1xuXHRcdFx0XHRcdFx0XHRcdGN1cnJlbnRfcm93WydkZXNjcmlwdGlvbiddLnNldFJlYWRPbmx5KCByZXN1bHRfZGF0YVsnZGVzY3JpcHRpb25fbG9ja2VkJ10gKTtcblx0XHRcdFx0XHRcdFx0XHRjdXJyZW50X3Jvd1sndW5pdF9wcmljZSddLnNldFJlYWRPbmx5KCByZXN1bHRfZGF0YVsncHJpY2VfbG9ja2VkJ10gKTtcblxuXHRcdFx0XHRcdFx0XHRcdGN1cnJlbnRfcm93WydjdXJyZW50X2VkaXRfaXRlbSddWydwcm9kdWN0X3R5cGVfaWQnXSA9IHJlc3VsdF9kYXRhWyd0eXBlX2lkJ107XG5cdFx0XHRcdFx0XHRcdFx0Y3VycmVudF9yb3dbJ2N1cnJlbnRfZWRpdF9pdGVtJ11bJ3Byb2R1Y3RfbmFtZSddID0gcmVzdWx0X2RhdGFbJ25hbWUnXTtcblx0XHRcdFx0XHRcdFx0XHRjdXJyZW50X3Jvd1snY3VycmVudF9lZGl0X2l0ZW0nXVsncHJvZHVjdF9wYXJ0X251bWJlciddID0gcmVzdWx0X2RhdGFbJ3BhcnRfbnVtYmVyJ107XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRpZiAoIHJlc3VsdF9kYXRhLmlkICYmICR0aGlzLmN1cnJlbnRfZWRpdF9yZWNvcmQgJiYgJHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFsnY3VycmVuY3lfaWQnXSApIHtcblx0XHRcdFx0XHRcdFx0XHQkdGhpcy5wcm9kdWN0X2FwaVsnZ2V0UHJvZHVjdFF1YW50aXR5VW5pdFByaWNlJ10oIHJlc3VsdF9kYXRhLmlkLCBxdWFudGl0eSwgJHRoaXMuY3VycmVudF9lZGl0X3JlY29yZFsnY3VycmVuY3lfaWQnXSwge1xuXHRcdFx0XHRcdFx0XHRcdFx0b25SZXN1bHQ6IGZ1bmN0aW9uKCB1X3JlcyApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0dmFyIHVuaXRfcHJpY2UgPSB1X3Jlcy5nZXRSZXN1bHQoKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBrZXkgPT09ICdwcm9kdWN0X2lkJyApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRjdXJyZW50X3Jvd1sncXVhbnRpdHknXS5zZXRWYWx1ZSggcXVhbnRpdHkgKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRjdXJyZW50X3Jvd1sndW5pdF9wcmljZSddLnNldFZhbHVlKCB1bml0X3ByaWNlICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdCR0aGlzLmNhbGNUcmFuc2FjdGlvblJvd1RvdGFsKCBjdXJyZW50X3JvdyApO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoICR0aGlzLmVkaXRvciAmJiAkdGhpcy5lZGl0b3Iucm93c193aWRnZXRzX2FycmF5ICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdCR0aGlzLmVkaXRvci5yb3dzX3dpZGdldHNfYXJyYXlbaW5kZXhdID0gY3VycmVudF9yb3c7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dmFyIHRyYW5zYWN0aW9uX2RhdGEgPSAkdGhpcy5lZGl0b3IuZ2V0VmFsdWUoKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQkdGhpcy5nZXRJbnZvaWNlVG90YWxEYXRhKCB0cmFuc2FjdGlvbl9kYXRhICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0JHRoaXMuZ2V0U2hpcHBpbmdPcHRpb25zKCB0cmFuc2FjdGlvbl9kYXRhICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRjYXNlICdwcm9fcmF0ZV9udW1lcmF0b3InOlxuXHRcdFx0Y2FzZSAncHJvX3JhdGVfZGVub21pbmF0b3InOlxuXHRcdFx0Y2FzZSAndW5pdF9wcmljZSc6XG5cdFx0XHRcdHRoaXMuY2FsY1RyYW5zYWN0aW9uUm93VG90YWwoIGN1cnJlbnRfcm93ICk7XG5cdFx0XHRcdHZhciB0cmFuc2FjdGlvbl9kYXRhID0gJHRoaXMuZWRpdG9yLmdldFZhbHVlKCk7XG5cdFx0XHRcdHRoaXMuZ2V0SW52b2ljZVRvdGFsRGF0YSggdHJhbnNhY3Rpb25fZGF0YSApO1xuXHRcdFx0XHR0aGlzLmdldFNoaXBwaW5nT3B0aW9ucyggdHJhbnNhY3Rpb25fZGF0YSApO1xuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblxuXHRjYWxjVHJhbnNhY3Rpb25Sb3dUb3RhbCggY3VycmVudF9yb3cgKSB7XG5cdFx0dmFyIHRvdGFsID0gMC4wMDtcblx0XHR2YXIgcHJvX3JhdGVfbnVtZXJhdG9yID0gcGFyc2VGbG9hdCggY3VycmVudF9yb3dbJ3Byb19yYXRlX251bWVyYXRvciddLmdldFZhbHVlKCkgKTtcblx0XHR2YXIgcHJvX3JhdGVfZGVub21pbmF0b3IgPSBwYXJzZUZsb2F0KCBjdXJyZW50X3Jvd1sncHJvX3JhdGVfZGVub21pbmF0b3InXS5nZXRWYWx1ZSgpICk7XG5cdFx0dmFyIHF1YW50aXR5ID0gcGFyc2VGbG9hdCggY3VycmVudF9yb3dbJ3F1YW50aXR5J10uZ2V0VmFsdWUoKSApO1xuXHRcdHZhciB1bml0X3ByaWNlID0gcGFyc2VGbG9hdCggY3VycmVudF9yb3dbJ3VuaXRfcHJpY2UnXS5nZXRWYWx1ZSgpICk7XG5cblx0XHRpZiAoICggIWlzTmFOKCBxdWFudGl0eSApICYmIGlzRmluaXRlKCBxdWFudGl0eSApICkgJiYgKCAhaXNOYU4oIHVuaXRfcHJpY2UgKSAmJiBpc0Zpbml0ZSggdW5pdF9wcmljZSApICkgKSB7XG5cdFx0XHR0b3RhbCA9ICggcXVhbnRpdHkgKiB1bml0X3ByaWNlICk7XG5cdFx0fVxuXG5cdFx0aWYgKCAoICFpc05hTiggcHJvX3JhdGVfbnVtZXJhdG9yICkgJiYgaXNGaW5pdGUoIHByb19yYXRlX251bWVyYXRvciApICYmIHByb19yYXRlX251bWVyYXRvciAhPSAwICkgJiYgKCAhaXNOYU4oIHByb19yYXRlX2Rlbm9taW5hdG9yICkgJiYgaXNGaW5pdGUoIHByb19yYXRlX2Rlbm9taW5hdG9yICkgJiYgcHJvX3JhdGVfZGVub21pbmF0b3IgIT0gMCApICkge1xuXHRcdFx0dG90YWwgPSAoIHRvdGFsICogKCBwcm9fcmF0ZV9udW1lcmF0b3IgLyBwcm9fcmF0ZV9kZW5vbWluYXRvciApICk7XG5cdFx0fVxuXG5cdFx0Y3VycmVudF9yb3dbJ2Ftb3VudCddLnNldFZhbHVlKCBwYXJzZUZsb2F0KCB0b3RhbCApLnRvRml4ZWQoIDIgKSApO1xuXHR9XG5cblx0aW5zaWRlRWRpdG9yR2V0VmFsdWUoIGN1cnJlbnRfZWRpdF9pdGVtX2lkICkge1xuXHRcdHZhciBsZW4gPSB0aGlzLnJvd3Nfd2lkZ2V0c19hcnJheS5sZW5ndGg7XG5cblx0XHR2YXIgcmVzdWx0ID0gW107XG5cblx0XHRmb3IgKCB2YXIgaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblxuXHRcdFx0dmFyIHJvdyA9IHRoaXMucm93c193aWRnZXRzX2FycmF5W2ldO1xuXHRcdFx0dmFyIGRhdGEgPSB7fTtcblx0XHRcdGRhdGFbJ3N0YXR1c19pZCddID0gcm93LmN1cnJlbnRfZWRpdF9pdGVtWydzdGF0dXNfaWQnXTtcblx0XHRcdGRhdGFbJ3Byb2R1Y3RfcGFydF9udW1iZXInXSA9IHJvdy5jdXJyZW50X2VkaXRfaXRlbVsncHJvZHVjdF9wYXJ0X251bWJlciddO1xuXHRcdFx0ZGF0YVsnaWQnXSA9IHJvdy5jdXJyZW50X2VkaXRfaXRlbVsnaWQnXTtcblx0XHRcdGRhdGFbJ2Rlc2NyaXB0aW9uJ10gPSByb3cuY3VycmVudF9lZGl0X2l0ZW1bJ2Rlc2NyaXB0aW9uJ107XG5cdFx0XHRkYXRhWydwcm9kdWN0X25hbWUnXSA9IHJvdy5jdXJyZW50X2VkaXRfaXRlbVsncHJvZHVjdF9uYW1lJ107XG5cdFx0XHRkYXRhWydhbW91bnQnXSA9IHJvdy5jdXJyZW50X2VkaXRfaXRlbVsnYW1vdW50J107XG5cdFx0XHRkYXRhWyd1bml0X3ByaWNlJ10gPSByb3cuY3VycmVudF9lZGl0X2l0ZW1bJ3VuaXRfcHJpY2UnXTtcblx0XHRcdGRhdGFbJ3Byb2R1Y3RfdHlwZV9pZCddID0gcm93LmN1cnJlbnRfZWRpdF9pdGVtWydwcm9kdWN0X3R5cGVfaWQnXTtcblx0XHRcdGRhdGFbJ3R5cGVfaWQnXSA9IHJvdy5jdXJyZW50X2VkaXRfaXRlbVsndHlwZV9pZCddO1xuXHRcdFx0ZGF0YVsncHJvX3JhdGVfZGVub21pbmF0b3InXSA9IHJvdy5jdXJyZW50X2VkaXRfaXRlbVsncHJvX3JhdGVfZGVub21pbmF0b3InXTtcblx0XHRcdGRhdGFbJ2NsaWVudF9pZCddID0gcm93LmN1cnJlbnRfZWRpdF9pdGVtWydjbGllbnRfaWQnXTtcblx0XHRcdGRhdGFbJ3F1YW50aXR5J10gPSByb3cuY3VycmVudF9lZGl0X2l0ZW1bJ3F1YW50aXR5J107XG5cdFx0XHRkYXRhWydwcm9kdWN0X2lkJ10gPSByb3cuY3VycmVudF9lZGl0X2l0ZW1bJ3Byb2R1Y3RfaWQnXTtcblx0XHRcdGRhdGFbJ2ludm9pY2VfaWQnXSA9IHJvdy5jdXJyZW50X2VkaXRfaXRlbVsnaW52b2ljZV9pZCddO1xuXHRcdFx0ZGF0YVsncHJvX3JhdGVfbnVtZXJhdG9yJ10gPSByb3cuY3VycmVudF9lZGl0X2l0ZW1bJ3Byb19yYXRlX251bWVyYXRvciddO1xuXHRcdFx0ZGF0YVsnZWZmZWN0aXZlX2RhdGUnXSA9IHJvdy5jdXJyZW50X2VkaXRfaXRlbVsnZWZmZWN0aXZlX2RhdGUnXTtcblxuXHRcdFx0dmFyIHByb2R1Y3RfaWQgPSByb3dbJ3Byb2R1Y3RfaWQnXS5nZXRWYWx1ZSgpO1xuXG5cdFx0XHRpZiAoIHR5cGVvZiBjdXJyZW50X2VkaXRfaXRlbV9pZCAhPT0gJ3VuZGVmaW5lZCcgJiYgKCBjdXJyZW50X2VkaXRfaXRlbV9pZCA9PT0gJycgfHwgY3VycmVudF9lZGl0X2l0ZW1faWQgPT09IGZhbHNlICkgKSB7XG5cdFx0XHRcdGRhdGFbJ2lkJ10gPSAnJztcblx0XHRcdFx0ZGF0YVsnaW52b2ljZV9pZCddID0gJyc7XG5cdFx0XHRcdGRhdGFbJ3R5cGVfaWQnXSA9IDEwO1xuXHRcdFx0XHRkYXRhWydlZmZlY3RpdmVfZGF0ZSddID0gbmV3IERhdGUoKS5mb3JtYXQoKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCB0eXBlb2YgZGF0YS5lZmZlY3RpdmVfZGF0ZSA9PT0gJ3VuZGVmaW5lZCcgKSB7XG5cdFx0XHRcdGRhdGFbJ2VmZmVjdGl2ZV9kYXRlJ10gPSBuZXcgRGF0ZSgpLmZvcm1hdCgpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHR5cGVvZiBkYXRhLnR5cGVfaWQgPT09ICd1bmRlZmluZWQnICkge1xuXHRcdFx0XHRkYXRhWyd0eXBlX2lkJ10gPSAxMDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBUVFVVSUQuaXNVVUlEKCBwcm9kdWN0X2lkICkgJiYgcHJvZHVjdF9pZCAhPSBUVFVVSUQuemVyb19pZCApIHtcblx0XHRcdFx0ZGF0YVsncHJvZHVjdF9pZCddID0gcHJvZHVjdF9pZDtcblx0XHRcdFx0ZGF0YVsncXVhbnRpdHknXSA9IHJvd1sncXVhbnRpdHknXS5nZXRWYWx1ZSgpO1xuXHRcdFx0XHRkYXRhWydwcm9fcmF0ZV9udW1lcmF0b3InXSA9IHJvd1sncHJvX3JhdGVfbnVtZXJhdG9yJ10uZ2V0VmFsdWUoKTtcblx0XHRcdFx0ZGF0YVsnZGVzY3JpcHRpb24nXSA9IHJvd1snZGVzY3JpcHRpb24nXS5nZXRWYWx1ZSgpO1xuXHRcdFx0XHRkYXRhWydwcm9fcmF0ZV9kZW5vbWluYXRvciddID0gcm93Wydwcm9fcmF0ZV9kZW5vbWluYXRvciddLmdldFZhbHVlKCk7XG5cdFx0XHRcdGRhdGFbJ2Ftb3VudCddID0gcm93WydhbW91bnQnXS5nZXRWYWx1ZSgpO1xuXHRcdFx0XHRkYXRhWyd1bml0X3ByaWNlJ10gPSByb3dbJ3VuaXRfcHJpY2UnXS5nZXRWYWx1ZSgpO1xuXHRcdFx0XHRkYXRhWydjbGllbnRfaWQnXSA9IHRoaXMucGFyZW50X2NvbnRyb2xsZXIuY3VycmVudF9lZGl0X3JlY29yZFsnY2xpZW50X2lkJ107XG5cblx0XHRcdFx0cmVzdWx0LnB1c2goIGRhdGEgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0dW5pZm9ybVZhcmlhYmxlKCByZWNvcmQgKSB7XG5cblx0XHRpZiAoICFHbG9iYWwuaXNTZXQoIHJlY29yZCApICkge1xuXHRcdFx0cmVjb3JkID0ge307XG5cdFx0fVxuXHRcdHZhciB0cmFuc2FjdGlvbl9kYXRhID0gdGhpcy5lZGl0b3IuZ2V0VmFsdWUoIHRoaXMuY3VycmVudF9lZGl0X3JlY29yZC5pZCApO1xuXHRcdGlmICggdHJhbnNhY3Rpb25fZGF0YS5sZW5ndGggPiAwICkge1xuXHRcdFx0cmVjb3JkLnRyYW5zYWN0aW9ucyA9IHRyYW5zYWN0aW9uX2RhdGE7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJlY29yZDtcblx0fVxuXG5cdG9uQ29weUFzTmV3UmVzdWx0KCByZXN1bHQgKSB7XG5cdFx0dmFyICR0aGlzID0gdGhpcztcblx0XHR2YXIgcmVzdWx0X2RhdGEgPSByZXN1bHQuZ2V0UmVzdWx0KCk7XG5cdFx0aWYgKCAhcmVzdWx0X2RhdGEgKSB7XG5cdFx0XHRUQWxlcnRNYW5hZ2VyLnNob3dBbGVydCggJC5pMThuLl8oICdSZWNvcmQgZG9lcyBub3QgZXhpc3QnICkgKTtcblx0XHRcdCR0aGlzLm9uQ2FuY2VsQ2xpY2soKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQkdGhpcy5vcGVuRWRpdFZpZXcoKTsgLy8gUHV0IGl0IGhlcmUgaXMgdG8gYXZvaWQgaWYgdGhlIHNlbGVjdGVkIG9uZSBpcyBub3QgZXhpc3RlZCBpbiBkYXRhIG9yIGhhdmUgZGVsZXRlZCBieSBvdGhlciBwcmFncmFtLiBpbiB0aGlzIGNhc2UsIHRoZSBlZGl0IHZpZXcgc2hvdWxkIG5vdCBiZSBvcGVuZC5cblxuXHRcdHJlc3VsdF9kYXRhID0gcmVzdWx0X2RhdGFbMF07XG5cdFx0dGhpcy5jb3BpZWRfcmVjb3JkX2lkID0gcmVzdWx0X2RhdGEuaWQ7XG5cblx0XHRyZXN1bHRfZGF0YS5pZCA9ICcnO1xuXG5cdFx0aWYgKCAkdGhpcy5zdWJfdmlld19tb2RlICYmICR0aGlzLnBhcmVudF9rZXkgKSB7XG5cdFx0XHRyZXN1bHRfZGF0YVskdGhpcy5wYXJlbnRfa2V5XSA9ICR0aGlzLnBhcmVudF92YWx1ZTtcblx0XHR9XG5cblx0XHQkdGhpcy5jdXJyZW50X2VkaXRfcmVjb3JkID0gcmVzdWx0X2RhdGE7XG5cdFx0JHRoaXMuaW5pdEVkaXRWaWV3KCk7XG5cdH1cblxuXHRnZXRJbnZvaWNlVGFiSHRtbCgpIHtcblx0XHRyZXR1cm4gYDxkaXYgaWQ9XCJ0YWJfaW52b2ljZVwiIGNsYXNzPVwiZWRpdC12aWV3LXRhYi1vdXRzaWRlXCI+XG5cdFx0XHRcdFx0PGRpdiBjbGFzcz1cImVkaXQtdmlldy10YWJcIiBpZD1cInRhYl9pbnZvaWNlX2NvbnRlbnRfZGl2XCI+XG5cdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwiZmlyc3QtY29sdW1uXCI+PC9kaXY+XG5cdFx0XHRcdFx0XHQ8ZGl2IGNsYXNzPVwic2Vjb25kLWNvbHVtblwiPjwvZGl2PlxuXHRcdFx0XHRcdFx0PGRpdiBjbGFzcz1cImluc2lkZS1lZGl0b3ItZGl2IGZ1bGwtd2lkdGgtY29sdW1uXCIgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAxMHB4O1wiPjwvZGl2PlxuXHRcdFx0XHRcdFx0PGRpdiBjbGFzcz1cImluc2lkZS10b3RhbC1kYXRhLWVkaXRvci1kaXZcIj48L2Rpdj5cblx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJpbnNpZGUtdHJhbnNhY3Rpb24taGlzdG9yeS1kaXZcIj48L2Rpdj5cblx0XHRcdFx0XHRcdDxkaXYgY2xhc3M9XCJ0aGlyZC1jb2x1bW4gZnVsbC13aWR0aC1jb2x1bW5cIj48L2Rpdj5cblx0XHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PC9kaXY+YDtcblx0fVxuXG59XG5cbkludm9pY2VWaWV3Q29udHJvbGxlci5sb2FkU3ViVmlldyA9IGZ1bmN0aW9uKCBjb250YWluZXIsIGJlZm9yZVZpZXdMb2FkZWRGdW4sIGFmdGVyVmlld0xvYWRlZEZ1biApIHtcblxuXHRHbG9iYWwubG9hZFZpZXdTb3VyY2UoICdJbnZvaWNlJywgJ1N1Ykludm9pY2VWaWV3Lmh0bWwnLCBmdW5jdGlvbiggcmVzdWx0ICkge1xuXHRcdHZhciBhcmdzID0ge307XG5cdFx0dmFyIHRlbXBsYXRlID0gXy50ZW1wbGF0ZSggcmVzdWx0ICk7XG5cblx0XHRpZiAoIEdsb2JhbC5pc1NldCggYmVmb3JlVmlld0xvYWRlZEZ1biApICkge1xuXHRcdFx0YmVmb3JlVmlld0xvYWRlZEZ1bigpO1xuXHRcdH1cblxuXHRcdGlmICggR2xvYmFsLmlzU2V0KCBjb250YWluZXIgKSApIHtcblx0XHRcdGNvbnRhaW5lci5odG1sKCB0ZW1wbGF0ZSggYXJncyApICk7XG5cdFx0XHRpZiAoIEdsb2JhbC5pc1NldCggYWZ0ZXJWaWV3TG9hZGVkRnVuICkgKSB7XG5cdFx0XHRcdGFmdGVyVmlld0xvYWRlZEZ1biggc3ViX2ludm9pY2Vfdmlld19jb250cm9sbGVyICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///4585\n")}}]); |