ornamentum
Version:
Angular Toolkit
333 lines • 37.6 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, Input, TemplateRef } from '@angular/core';
import { DataTableConfigService } from '../../services/data-table-config.service';
import { DataTableDataStateService } from '../../services/data-table-data-state.service';
import { DataTableEventStateService } from '../../services/data-table-event.service';
import { get } from '../../../utility/services/object-utility.class';
/**
* Data table body component. Data table body table definition rendering is handled by this component.
*/
export class DataTableBodyComponent {
/**
* @param {?} config
* @param {?} dataStateService
* @param {?} eventStateService
*/
constructor(config, dataStateService, eventStateService) {
this.config = config;
this.dataStateService = dataStateService;
this.eventStateService = eventStateService;
}
/**
* Unique data row tracking callback.
* @param {?} index Current index.
* @param {?} dataRow Data row object reference.
* @return {?}
*/
dataRowTrackBy(index, dataRow) {
return dataRow.index;
}
/**
* Odd row status; True if row index is a odd number.
* @param {?} row Data row object.
* @return {?} True if odd row.
*/
isOddRow(row) {
return row.index % 2 === 0;
}
/**
* Even row status; True if row index is a even number.
* @param {?} row Data row object.
* @return {?} True if even row.
*/
isEvenRow(row) {
return row.index % 2 === 1;
}
/**
* Odd substitute row status by row index; True if row index is an odd substitute row.
* @param {?} index Row index.
* @return {?} True if odd substitute row.
*/
isOddSubstituteRow(index) {
return (index + this.dataStateService.substituteRows.length) % 2 === 0;
}
/**
* Even substitute row status by row index; True if row index is an even substitute row.
* @param {?} index Row index.
* @return {?} True if even substitute row.
*/
isEvenSubstituteRow(index) {
return (index + this.dataStateService.substituteRows.length) % 2 === 1;
}
/**
* On row expand event handler.
* @param {?} $event Click event argument reference.
* @param {?} dataRow Data row object.
* @return {?}
*/
onRowExpand($event, dataRow) {
dataRow.expanded = !dataRow.expanded;
if (!this.config.showRowExpandLoadingSpinner) {
dataRow.dataLoaded = true;
}
}
/**
* On row initialize event handler.
* @param {?} dataRow Data table row.
* @return {?}
*/
onRowInit(dataRow) {
this.eventStateService.rowBindStream.emit(dataRow);
}
/**
* On cell initialize event handler.
* @param {?} column Data table column component reference.
* @param {?} row Data table row object.
* @return {?}
*/
onCellInit(column, row) {
this.eventStateService.cellBindStream.emit({
column,
row
});
}
/**
* Cell clicked event handler.
* @param {?} column Column data table component reference.
* @param {?} row Data table row reference.
* @param {?} event Mouse click event argument reference.
* @return {?}
*/
cellClicked(column, row, event) {
this.eventStateService.cellClickStream.emit({ row, column, event });
}
/**
* Get row span collection by data row.
* @param {?} row Data row reference.
* @return {?} Dummy row span collection.
*/
getRowSpanCollection(row) {
return Array.from({
length: this.dataStateService.onDynamicRowSpanExtract(row)
});
}
/**
* Get total column count used for substitute row generation.
* @return {?} Number of columns.
*/
get totalColumnCount() {
/** @type {?} */
let count = 0;
count += this.config.showIndexColumn ? 1 : 0;
count += this.config.showRowSelectCheckboxColumn ? 1 : 0;
count += this.config.expandableRows ? 1 : 0;
this.columns.forEach((/**
* @param {?} column
* @return {?}
*/
column => {
count += column.visible ? 1 : 0;
}));
return count;
}
/**
* On row select click event handler.
* @param {?} row Data row reference.
* @param {?} event Row click event.
* @return {?}
*/
onRowSelectClick(row, event) {
// Prevent single mode checkbox getting unchecked on tapping already selected.
if (this.config.selectMode === 'single') {
/** @type {?} */
const id = get(row.item, this.config.selectTrackBy);
/** @type {?} */
const previousSelection = this.dataStateService.selectedRow;
if (previousSelection === id) {
event.preventDefault();
row.selected = true;
}
}
}
/**
* On row selection change event handler.
* @param {?} row Data row reference.
* @return {?}
*/
onRowSelectChange(row) {
/** @type {?} */
const id = get(row.item, this.config.selectTrackBy);
switch (this.config.selectMode) {
case 'multi': {
/** @type {?} */
const index = this.dataStateService.selectedRows.indexOf(id);
if (row.selected && index < 0) {
this.dataStateService.selectedRows.push(id);
}
else if (!row.selected && index > -1) {
this.dataStateService.selectedRows.splice(index, 1);
}
/** @type {?} */
const previousAllRowSelectedState = this.dataStateService.allRowSelected;
this.dataStateService.allRowSelected = this.dataStateService.dataRows.every((/**
* @param {?} dataRow
* @return {?}
*/
(dataRow) => {
return dataRow.selected;
}));
this.eventStateService.rowSelectChangeStream.emit(this.dataStateService.selectedRows);
if (previousAllRowSelectedState !== this.dataStateService.allRowSelected) {
this.eventStateService.allRowSelectChangeStream.emit(this.dataStateService.allRowSelected);
}
break;
}
case 'single_toggle': {
if (row.selected) {
this.dataStateService.selectedRow = id;
// deselect all other row other rows
this.dataStateService.dataRows.forEach((/**
* @param {?} dataRow
* @return {?}
*/
(dataRow) => {
if (dataRow !== row) {
dataRow.selected = false;
}
}));
}
else {
this.dataStateService.selectedRow = undefined;
}
this.eventStateService.rowSelectChangeStream.emit(this.dataStateService.selectedRow);
break;
}
case 'single': {
/** @type {?} */
const previousSelection = this.dataStateService.selectedRow;
this.dataStateService.selectedRow = id;
row.selected = true;
// deselect all other row other rows
this.dataStateService.dataRows.forEach((/**
* @param {?} dataRow
* @return {?}
*/
(dataRow) => {
if (dataRow !== row) {
dataRow.selected = false;
}
}));
if (previousSelection !== id) {
this.eventStateService.rowSelectChangeStream.emit(this.dataStateService.selectedRow);
}
break;
}
}
}
/**
* Row clicked event handler.
* @param {?} row Data row object.
* @param {?} event Mouse click event argument object.
* @return {?}
*/
rowClicked(row, event) {
if (this.config.selectOnRowClick || (this.config.expandableRows && this.config.expandOnRowClick)) {
/** @type {?} */
const target = (/** @type {?} */ (event.target));
if (target && target.classList && target.classList.contains('ng-ignore-propagation')) {
return;
}
if (this.config.rowSelectable && this.config.selectOnRowClick) {
row.selected = !row.selected;
this.onRowSelectChange(row);
}
if (this.config.expandOnRowClick) {
row.expanded = !row.expanded;
}
}
this.eventStateService.rowClickStream.emit({ row, event });
}
/**
* Row double clicked event handler.
* @param {?} row Data row object.
* @param {?} event Event Mouse click event argument object.
* @return {?}
*/
rowDoubleClicked(row, event) {
this.eventStateService.rowDoubleClickStream.emit({ row, event });
}
/**
* Get substitute row availability status.
* @return {?} True if substitute rows are available.
*/
get hasSubstituteRows() {
return !this.config.loadOnScroll
&& this.config.showSubstituteRows
&& this.dataStateService.dataRows.length
&& !this.dataStateService.showNoDataOverlay;
}
/**
* Get cell value by data field.
* @param {?} row Data row reference.
* @param {?} column Data table column component reference.
* @return {?}
*/
getFieldValue(row, column) {
return get(row.item, column.field);
}
/**
* Get row select checkbox display status.
* @return {?} True if row selector checkbox should be displayed.
*/
get showRowSelectCheckbox() {
return this.config.rowSelectable && this.config.showRowSelectCheckbox;
}
/**
* Get row expend view loading status. Used to display loading spinner on expand column while data fetching.
* @param {?} row Data row object reference.
* @return {?}
*/
isRowExpanderLoading(row) {
return row.expanded && !row.dataLoaded;
}
}
DataTableBodyComponent.decorators = [
{ type: Component, args: [{
exportAs: 'ngDataTableBody',
// tslint:disable-next-line
selector: '[ngDataTableBody]',
template: "<ng-container *ngFor=\"let row of dataStateService.dataRows; trackBy: dataRowTrackBy; let i = index;\">\n <ng-container *ngFor=\"let ignored of getRowSpanCollection(row); let rowSpanIndex = index; let rowSpanCount = count\">\n <tr\n class=\"ng-data-table-row\"\n (ngInit)=\"onRowInit(row)\"\n [attr.title]=\"row.tooltip\"\n [class.row-odd]=\"isOddRow(row)\"\n [class.row-even]=\"isEvenRow(row)\"\n [class.selected]=\"row.selected\"\n [class.clickable]=\"config.selectOnRowClick\"\n [class.disabled]=\"row.disabled\"\n [ngClass]=\"row.cssClass\"\n (dblclick)=\"rowDoubleClicked(row, $event)\"\n (click)=\"rowClicked(row, $event)\"\n >\n <td\n class=\"ng-data-table-row-expand-button ng-ignore-propagation\"\n [style.background-color]=\"row.color\"\n *ngIf=\"config.expandableRows && !rowSpanIndex\"\n (click)=\"onRowExpand($event, row)\"\n [attr.rowspan]=\"rowSpanCount\"\n >\n <div [hidden]=\"config.showRowExpandLoadingSpinner && isRowExpanderLoading(row)\">\n <span class=\"ng-data-table-expander-collapsed-icon ng-ignore-propagation\" *ngIf=\"!row.expanded\"></span>\n <span class=\"ng-data-table-expander-expanded-icon ng-ignore-propagation\" *ngIf=\"row.expanded\"></span>\n </div>\n <ng-data-table-loading-spinner\n *ngIf=\"config.showRowExpandLoadingSpinner\"\n [loadingSpinnerTemplate]=\"rowExpandLoadingSpinnerTemplate\"\n [isLoading]=\"isRowExpanderLoading(row)\"\n [showOverlay]=\"false\"\n >\n </ng-data-table-loading-spinner>\n </td>\n <td\n class=\"index-column\"\n [style.background-color]=\"row.color\"\n *ngIf=\"config.showIndexColumn && !rowSpanIndex\"\n [textContent]=\"row.index\"\n [attr.rowspan]=\"rowSpanCount\"\n >\n </td>\n <td\n class=\"ng-data-table-select-column\"\n [style.background-color]=\"row.color\"\n *ngIf=\"showRowSelectCheckbox && !rowSpanIndex\"\n [attr.rowspan]=\"rowSpanCount\"\n >\n <div class=\"ng-data-table-checkbox-container ng-ignore-propagation\">\n <input class=\"ng-data-table-checkbox-input ng-ignore-propagation\" type=\"checkbox\"\n [id]=\"dataStateService.getUniqueId('dr', i)\"\n [(ngModel)]=\"row.selected\"\n (click)=\"onRowSelectClick(row, $event)\"\n (change)=\"onRowSelectChange(row)\"\n />\n <label class=\"ng-ignore-propagation\" [for]=\"dataStateService.getUniqueId('dr', i)\"></label>\n </div>\n </td>\n <ng-container *ngFor=\"let column of columns\">\n <ng-container *ngIf=\"column.visible\">\n <td\n class=\"ng-data-table-data-column\"\n *ngIf=\"!column.cellTemplate && !rowSpanIndex\"\n (ngInit)=\"onCellInit(column, row)\"\n [ngClass]=\"column.cssClass\"\n [attr.rowspan]=\"rowSpanCount\"\n [style.background-color]=\"column.getCellColor(row) || row.color\"\n (click)=\"cellClicked(column, row, $event)\"\n >\n <span>{{ getFieldValue(row, column) }}</span>\n </td>\n <ng-container\n *ngIf=\"column.cellTemplate\"\n [ngTemplateOutlet]=\"column.cellTemplate\"\n [ngTemplateOutletContext]=\"{ column: column, row: row, spanIndex: rowSpanIndex, rowSpan: rowSpanCount }\"\n >\n </ng-container>\n </ng-container>\n </ng-container>\n </tr>\n </ng-container>\n <tr *ngIf=\"config.expandableRows\" [hidden]=\"!row.expanded\" class=\"ng-data-table-row-expansion\">\n <td [attr.colspan]=\"totalColumnCount\">\n <ng-container [ngTemplateOutlet]=\"rowExpandTemplate\" [ngTemplateOutletContext]=\"{ row: row }\"> </ng-container>\n </td>\n </tr>\n</ng-container>\n<ng-container *ngIf=\"hasSubstituteRows\">\n <tr\n *ngFor=\"let ignored of dataStateService.substituteRows; let index = index\"\n [class.row-odd]=\"isOddSubstituteRow(index)\"\n [class.row-even]=\"isEvenSubstituteRow(index)\"\n >\n <td *ngIf=\"config.expandableRows\"> </td>\n <td *ngIf=\"config.showIndexColumn\"> </td>\n <td *ngIf=\"showRowSelectCheckbox\"> </td>\n <ng-container *ngFor=\"let column of columns\">\n <td *ngIf=\"column.visible\"> </td>\n </ng-container>\n </tr>\n</ng-container>\n"
}] }
];
/** @nocollapse */
DataTableBodyComponent.ctorParameters = () => [
{ type: DataTableConfigService },
{ type: DataTableDataStateService },
{ type: DataTableEventStateService }
];
DataTableBodyComponent.propDecorators = {
columns: [{ type: Input }],
rowExpandTemplate: [{ type: Input }],
rowExpandLoadingSpinnerTemplate: [{ type: Input }]
};
if (false) {
/** @type {?} */
DataTableBodyComponent.prototype.columns;
/** @type {?} */
DataTableBodyComponent.prototype.rowExpandTemplate;
/** @type {?} */
DataTableBodyComponent.prototype.rowExpandLoadingSpinnerTemplate;
/** @type {?} */
DataTableBodyComponent.prototype.config;
/** @type {?} */
DataTableBodyComponent.prototype.dataStateService;
/**
* @type {?}
* @private
*/
DataTableBodyComponent.prototype.eventStateService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS10YWJsZS1ib2R5LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL29ybmFtZW50dW0vIiwic291cmNlcyI6WyJkYXRhLXRhYmxlL2NvbXBvbmVudHMvZGF0YS10YWJsZS1ib2R5L2RhdGEtdGFibGUtYm9keS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQU05RCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUNsRixPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUN6RixPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUVyRixPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0RBQWdELENBQUM7Ozs7QUFXckUsTUFBTSxPQUFPLHNCQUFzQjs7Ozs7O0lBVWpDLFlBQ1MsTUFBOEIsRUFDOUIsZ0JBQTJDLEVBQzFDLGlCQUE2QztRQUY5QyxXQUFNLEdBQU4sTUFBTSxDQUF3QjtRQUM5QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQTJCO1FBQzFDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBNEI7SUFDcEQsQ0FBQzs7Ozs7OztJQU9HLGNBQWMsQ0FBQyxLQUFhLEVBQUUsT0FBMEI7UUFDN0QsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDO0lBQ3ZCLENBQUM7Ozs7OztJQU9NLFFBQVEsQ0FBQyxHQUFzQjtRQUNwQyxPQUFPLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM3QixDQUFDOzs7Ozs7SUFPTSxTQUFTLENBQUMsR0FBc0I7UUFDckMsT0FBTyxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDN0IsQ0FBQzs7Ozs7O0lBT00sa0JBQWtCLENBQUMsS0FBYTtRQUNyQyxPQUFPLENB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QztJQUNuRSxDQUFDOzs7OztJQU1ELElBQVcsaUJBQWlCO1FBQzFCLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVk7ZUFDM0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0I7ZUFDOUIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxNQUFNO2VBQ3JDLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGlCQUFpQixDQUFDO0lBQ2hELENBQUM7Ozs7Ozs7SUFPTSxhQUFhLENBQUMsR0FBc0IsRUFBRSxNQUFnQztRQUMzRSxPQUFPLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNyQyxDQUFDOzs7OztJQU1ELElBQVcscUJBQXFCO1FBQzlCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQztJQUN4RSxDQUFDOzs7Ozs7SUFNTSxvQkFBb0IsQ0FBQyxHQUFzQjtRQUNoRCxPQUFPLEdBQUcsQ0FBQyxRQUFRLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDO0lBQ3pDLENBQUM7OztZQWhTRixTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLGlCQUFpQjs7Z0JBRTNCLFFBQVEsRUFBRSxtQkFBbUI7Z0JBQzdCLDAzSUFBK0M7YUFDaEQ7Ozs7WUFkUSxzQkFBc0I7WUFDdEIseUJBQXlCO1lBQ3pCLDBCQUEwQjs7O3NCQWNoQyxLQUFLO2dDQUdMLEtBQUs7OENBR0wsS0FBSzs7OztJQU5OLHlDQUMyQzs7SUFFM0MsbURBQzJDOztJQUUzQyxpRUFDeUQ7O0lBR3ZELHdDQUFxQzs7SUFDckMsa0RBQWtEOzs7OztJQUNsRCxtREFBcUQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBUZW1wbGF0ZVJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBEYXRhVGFibGVSb3cgfSBmcm9tICcuLi8uLi9tb2RlbHMvZGF0YS10YWJsZS1yb3cubW9kZWwnO1xuXG5pbXBvcnQgeyBEYXRhVGFibGVDb2x1bW5Db21wb25lbnQgfSBmcm9tICcuLi9kYXRhLXRhYmxlLWNvbHVtbi9kYXRhLXRhYmxlLWNvbHVtbi5jb21wb25lbnQnO1xuXG5pbXBvcnQgeyBEYXRhVGFibGVDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZGF0YS10YWJsZS1jb25maWcuc2VydmljZSc7XG5pbXBvcnQgeyBEYXRhVGFibGVEYXRhU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZGF0YS10YWJsZS1kYXRhLXN0YXRlLnNlcnZpY2UnO1xuaW1wb3J0IHsgRGF0YVRhYmxlRXZlbnRTdGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9kYXRhLXRhYmxlLWV2ZW50LnNlcnZpY2UnO1xuXG5pbXBvcnQgeyBnZXQgfSBmcm9tICcuLi8uLi8uLi91dGlsaXR5L3NlcnZpY2VzL29iamVjdC11dGlsaXR5LmNsYXNzJztcblxuLyoqXG4gKiBEYXRhIHRhYmxlIGJvZHkgY29tcG9uZW50LiBEYXRhIHRhYmxlIGJvZHkgdGFibGUgZGVmaW5pdGlvbiByZW5kZXJpbmcgaXMgaGFuZGxlZCBieSB0aGlzIGNvbXBvbmVudC5cbiAqL1xuQENvbXBvbmVudCh7XG4gIGV4cG9ydEFzOiAnbmdEYXRhVGFibGVCb2R5JyxcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lXG4gIHNlbGVjdG9yOiAnW25nRGF0YVRhYmxlQm9keV0nLFxuICB0ZW1wbGF0ZVVybDogJy4vZGF0YS10YWJsZS1ib2R5LmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBEYXRhVGFibGVCb2R5Q29tcG9uZW50IHtcbiAgQElucHV0KClcbiAgcHVibGljIGNvbHVtbnM6IERhdGFUYWJsZUNvbHVtbkNvbXBvbmVudFtdO1xuXG4gIEBJbnB1dCgpXG4gIHB1YmxpYyByb3dFeHBhbmRUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICBASW5wdXQoKVxuICBwdWJsaWMgcm93RXhwYW5kTG9hZGluZ1NwaW5uZXJUZW1wbGF0ZTogVGVtcGxhdGVSZWY8YW55PjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgY29uZmlnOiBEYXRhVGFibGVDb25maWdTZXJ2aWNlLFxuICAgIHB1YmxpYyBkYXRhU3RhdGVTZXJ2aWNlOiBEYXRhVGFibGVEYXRhU3RhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgZXZlbnRTdGF0ZVNlcnZpY2U6IERhdGFUYWJsZUV2ZW50U3RhdGVTZXJ2aWNlXG4gICkge31cblxuICAvKipcbiAgICogVW5pcXVlIGRhdGEgcm93IHRyYWNraW5nIGNhbGxiYWNrLlxuICAgKiBAcGFyYW0gaW5kZXggQ3VycmVudCBpbmRleC5cbiAgICogQHBhcmFtIGRhdGFSb3cgRGF0YSByb3cgb2JqZWN0IHJlZmVyZW5jZS5cbiAgICovXG4gIHB1YmxpYyBkYXRhUm93VHJhY2tCeShpbmRleDogbnVtYmVyLCBkYXRhUm93OiBEYXRhVGFibGVSb3c8YW55Pik6IG51bWJlciB7XG4gICAgcmV0dXJuIGRhdGFSb3cuaW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogT2RkIHJvdyBzdGF0dXM7IFRydWUgaWYgcm93IGluZGV4IGlzIGEgb2RkIG51bWJlci5cbiAgICogQHBhcmFtIHJvdyBEYXRhIHJvdyBvYmplY3QuXG4gICAqIEByZXR1cm4gVHJ1ZSBpZiBvZGQgcm93LlxuICAgKi9cbiAgcHVibGljIGlzT2RkUm93KHJvdzogRGF0YVRhYmxlUm93PGFueT4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gcm93LmluZGV4ICUgMiA9PT0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBFdmVuIHJvdyBzdGF0dXM7IFRydWUgaWYgcm93IGluZGV4IGlzIGEgZXZlbiBudW1iZXIuXG4gICAqIEBwYXJhbSByb3cgRGF0YSByb3cgb2JqZWN0LlxuICAgKiBAcmV0dXJuIFRydWUgaWYgZXZlbiByb3cuXG4gICAqL1xuICBwdWJsaWMgaXNFdmVuUm93KHJvdzogRGF0YVRhYmxlUm93PGFueT4pOiBib29sZWFuIHtcbiAgICByZXR1cm4gcm93LmluZGV4ICUgMiA9PT0gMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPZGQgc3Vic3RpdHV0ZSByb3cgc3RhdHVzIGJ5IHJvdyBpbmRleDsgVHJ1ZSBpZiByb3cgaW5kZXggaXMgYW4gb2RkIHN1YnN0aXR1dGUgcm93LlxuICAgKiBAcGFyYW0gaW5kZXggUm93IGluZGV4LlxuICAgKiBAcmV0dXJuIFRydWUgaWYgb2RkIHN1YnN0aXR1dGUgcm93LlxuICAgKi9cbiAgcHVibGljIGlzT2RkU3Vic3RpdHV0ZVJvdyhpbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChpbmRleCArIHRoaXMuZGF0YVN0YXRlU2VydmljZS5zdWJzdGl0dXRlUm93cy5sZW5ndGgpICUgMiA9PT0gMDtcbiAgfVxuXG4gIC8qKlxuICAgKiBFdmVuIHN1YnN0aXR1dGUgcm93IHN0YXR1cyBieSByb3cgaW5kZXg7IFRydWUgaWYgcm93IGluZGV4IGlzIGFuIGV2ZW4gc3Vic3RpdHV0ZSByb3cuXG4gICAqIEBwYXJhbSBpbmRleCBSb3cgaW5kZXguXG4gICAqIEByZXR1cm4gVHJ1ZSBpZiBldmVuIHN1YnN0aXR1dGUgcm93LlxuICAgKi9cbiAgcHVibGljIGlzRXZlblN1YnN0aXR1dGVSb3coaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoaW5kZXggKyB0aGlzLmRhdGFTdGF0ZVNlcnZpY2Uuc3Vic3RpdHV0ZVJvd3MubGVuZ3RoKSAlIDIgPT09IDE7XG4gIH1cblxuICAvKipcbiAgICogT24gcm93IGV4cGFuZCBldmVudCBoYW5kbGVyLlxuICAgKiBAcGFyYW0gJGV2ZW50IENsaWNrIGV2ZW50IGFyZ3VtZW50IHJlZmVyZW5jZS5cbiAgICogQHBhcmFtIGRhdGFSb3cgRGF0YSByb3cgb2JqZWN0LlxuICAgKi9cbiAgcHVibGljIG9uUm93RXhwYW5kKCRldmVudDogRXZlbnQsIGRhdGFSb3c6IERhdGFUYWJsZVJvdzxhbnk+KTogdm9pZCB7XG4gICAgZGF0YVJvdy5leHBhbmRlZCA9ICFkYXRhUm93LmV4cGFuZGVkO1xuXG4gICAgaWYgKCF0aGlzLmNvbmZpZy5zaG93Um93RXhwYW5kTG9hZGluZ1NwaW5uZXIpIHtcbiAgICAgIGRhdGFSb3cuZGF0YUxvYWRlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE9uIHJvdyBpbml0aWFsaXplIGV2ZW50IGhhbmRsZXIuXG4gICAqIEBwYXJhbSBkYXRhUm93IERhdGEgdGFibGUgcm93LlxuICAgKi9cbiAgcHVibGljIG9uUm93SW5pdChkYXRhUm93KTogdm9pZCB7XG4gICAgdGhpcy5ldmVudFN0YXRlU2VydmljZS5yb3dCaW5kU3RyZWFtLmVtaXQoZGF0YVJvdyk7XG4gIH1cblxuICAvKipcbiAgICogT24gY2VsbCBpbml0aWFsaXplIGV2ZW50IGhhbmRsZXIuXG4gICAqIEBwYXJhbSBjb2x1bW4gRGF0YSB0YWJsZSBjb2x1bW4gY29tcG9uZW50IHJlZmVyZW5jZS5cbiAgICogQHBhcmFtIHJvdyBEYXRhIHRhYmxlIHJvdyBvYmplY3QuXG4gICAqL1xuICBwdWJsaWMgb25DZWxsSW5pdChjb2x1bW46IERhdGFUYWJsZUNvbHVtbkNvbXBvbmVudCwgcm93OiBEYXRhVGFibGVSb3c8YW55Pik6IHZvaWQge1xuICAgIHRoaXMuZXZlbnRTdGF0ZVNlcnZpY2UuY2VsbEJpbmRTdHJlYW0uZW1pdCh7XG4gICAgICBjb2x1bW4sXG4gICAgICByb3dcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDZWxsIGNsaWNrZWQgZXZlbnQgaGFuZGxlci5cbiAgICogQHBhcmFtIGNvbHVtbiBDb2x1bW4gZGF0YSB0YWJsZSBjb21wb25lbnQgcmVmZXJlbmNlLlxuICAgKiBAcGFyYW0gcm93IERhdGEgdGFibGUgcm93IHJlZmVyZW5jZS5cbiAgICogQHBhcmFtIGV2ZW50IE1vdXNlIGNsaWNrIGV2ZW50IGFyZ3VtZW50IHJlZmVyZW5jZS5cbiAgICovXG4gIHB1YmxpYyBjZWxsQ2xpY2tlZChjb2x1bW46IERhdGFUYWJsZUNvbHVtbkNvbXBvbmVudCwgcm93OiBEYXRhVGFibGVSb3c8YW55PiwgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmV2ZW50U3RhdGVTZXJ2aWNlLmNlbGxDbGlja1N0cmVhbS5lbWl0KHsgcm93LCBjb2x1bW4sIGV2ZW50IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCByb3cgc3BhbiBjb2xsZWN0aW9uIGJ5IGRhdGEgcm93LlxuICAgKiBAcGFyYW0gcm93IERhdGEgcm93IHJlZmVyZW5jZS5cbiAgICogQHJldHVybiBEdW1teSByb3cgc3BhbiBjb2xsZWN0aW9uLlxuICAgKi9cbiAgcHVibGljIGdldFJvd1NwYW5Db2xsZWN0aW9uKHJvdzogRGF0YVRhYmxlUm93PGFueT4pOiBhbnlbXSB7XG4gICAgcmV0dXJuIEFycmF5LmZyb20oe1xuICAgICAgbGVuZ3RoOiB0aGlzLmRhdGFTdGF0ZVNlcnZpY2Uub25EeW5hbWljUm93U3BhbkV4dHJhY3Qocm93KVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0b3RhbCBjb2x1bW4gY291bnQgdXNlZCBmb3Igc3Vic3RpdHV0ZSByb3cgZ2VuZXJhdGlvbi5cbiAgICogQHJldHVybiBOdW1iZXIgb2YgY29sdW1ucy5cbiAgICovXG4gIHB1YmxpYyBnZXQgdG90YWxDb2x1bW5Db3VudCgpOiBudW1iZXIge1xuICAgIGxldCBjb3VudCA9IDA7XG4gICAgY291bnQgKz0gdGhpcy5jb25maWcuc2hvd0luZGV4Q29sdW1uID8gMSA6IDA7XG4gICAgY291bnQgKz0gdGhpcy5jb25maWcuc2hvd1Jvd1NlbGVjdENoZWNrYm94Q29sdW1uID8gMSA6IDA7XG4gICAgY291bnQgKz0gdGhpcy5jb25maWcuZXhwYW5kYWJsZVJvd3MgPyAxIDogMDtcbiAgICB0aGlzLmNvbHVtbnMuZm9yRWFjaChjb2x1bW4gPT4ge1xuICAgICAgY291bnQgKz0gY29sdW1uLnZpc2libGUgPyAxIDogMDtcbiAgICB9KTtcblxuICAgIHJldHVybiBjb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBPbiByb3cgc2VsZWN0IGNsaWNrIGV2ZW50IGhhbmRsZXIuXG4gICAqIEBwYXJhbSByb3cgRGF0YSByb3cgcmVmZXJlbmNlLlxuICAgKiBAcGFyYW0gZXZlbnQgUm93IGNsaWNrIGV2ZW50LlxuICAgKi9cbiAgcHVibGljIG9uUm93U2VsZWN0Q2xpY2socm93OiBEYXRhVGFibGVSb3c8YW55PiwgZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgLy8gUHJldmVudCBzaW5nbGUgbW9kZSBjaGVja2JveCBnZXR0aW5nIHVuY2hlY2tlZCBvbiB0YXBwaW5nIGFscmVhZHkgc2VsZWN0ZWQuXG4gICAgaWYgKHRoaXMuY29uZmlnLnNlbGVjdE1vZGUgPT09ICdzaW5nbGUnKSB7XG4gICAgICBjb25zdCBpZCA9IGdldChyb3cuaXRlbSwgdGhpcy5jb25maWcuc2VsZWN0VHJhY2tCeSk7XG4gICAgICBjb25zdCBwcmV2aW91c1NlbGVjdGlvbiA9IHRoaXMuZGF0YVN0YXRlU2VydmljZS5zZWxlY3RlZFJvdztcblxuICAgICAgaWYgKHByZXZpb3VzU2VsZWN0aW9uID09PSBpZCkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICByb3cuc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBPbiByb3cgc2VsZWN0aW9uIGNoYW5nZSBldmVudCBoYW5kbGVyLlxuICAgKiBAcGFyYW0gcm93IERhdGEgcm93IHJlZmVyZW5jZS5cbiAgICovXG4gIHB1YmxpYyBvblJvd1NlbGVjdENoYW5nZShyb3c6IERhdGFUYWJsZVJvdzxhbnk+KTogdm9pZCB7XG4gICAgY29uc3QgaWQgPSBnZXQocm93Lml0ZW0sIHRoaXMuY29uZmlnLnNlbGVjdFRyYWNrQnkpO1xuXG4gICAgc3dpdGNoICh0aGlzLmNvbmZpZy5zZWxlY3RNb2RlKSB7XG4gICAgICBjYXNlICdtdWx0aSc6IHtcbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLmRhdGFTdGF0ZVNlcnZpY2Uuc2VsZWN0ZWRSb3dzLmluZGV4T2YoaWQpO1xuICAgICAgICBpZiAocm93LnNlbGVjdGVkICYmIGluZGV4IDwgMCkge1xuICAgICAgICAgIHRoaXMuZGF0YVN0YXRlU2VydmljZS5zZWxlY3RlZFJvd3MucHVzaChpZCk7XG4gICAgICAgIH0gZWxzZSBpZiAoIXJvdy5zZWxlY3RlZCAmJiBpbmRleCA+IC0xKSB7XG4gICAgICAgICAgdGhpcy5kYXRhU3RhdGVTZXJ2aWNlLnNlbGVjdGVkUm93cy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcHJldmlvdXNBbGxSb3dTZWxlY3RlZFN0YXRlID0gdGhpcy5kYXRhU3RhdGVTZXJ2aWNlLmFsbFJvd1NlbGVjdGVkO1xuICAgICAgICB0aGlzLmRhdGFTdGF0ZVNlcnZpY2UuYWxsUm93U2VsZWN0ZWQgPSB0aGlzLmRhdGFTdGF0ZVNlcnZpY2UuZGF0YVJvd3MuZXZlcnkoKGRhdGFSb3c6IERhdGFUYWJsZVJvdzxhbnk+KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIGRhdGFSb3cuc2VsZWN0ZWQ7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuZXZlbnRTdGF0ZVNlcnZpY2Uucm93U2VsZWN0Q2hhbmdlU3RyZWFtLmVtaXQodGhpcy5kYXRhU3RhdGVTZXJ2aWNlLnNlbGVjdGVkUm93cyk7XG5cbiAgICAgICAgaWYgKHByZXZpb3VzQWxsUm93U2VsZWN0ZWRTdGF0ZSAhPT0gdGhpcy5kYXRhU3RhdGVTZXJ2aWNlLmFsbFJvd1NlbGVjdGVkKSB7XG4gICAgICAgICAgdGhpcy5ldmVudFN0YXRlU2VydmljZS5hbGxSb3dTZWxlY3RDaGFuZ2VTdHJlYW0uZW1pdCh0aGlzLmRhdGFTdGF0ZVNlcnZpY2UuYWxsUm93U2VsZWN0ZWQpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnc2luZ2xlX3RvZ2dsZSc6IHtcbiAgICAgICAgaWYgKHJvdy5zZWxlY3RlZCkge1xuICAgICAgICAgIHRoaXMuZGF0YVN0YXRlU2VydmljZS5zZWxlY3RlZFJvdyA9IGlkO1xuXG4gICAgICAgICAgLy8gZGVzZWxlY3QgYWxsIG90aGVyIHJvdyBvdGhlciByb3dzXG4gICAgICAgICAgdGhpcy5kYXRhU3RhdGVTZXJ2aWNlLmRhdGFSb3dzLmZvckVhY2goKGRhdGFSb3c6IERhdGFUYWJsZVJvdzxhbnk+KSA9PiB7XG4gICAgICAgICAgICBpZiAoZGF0YVJvdyAhPT0gcm93KSB7XG4gICAgICAgICAgICAgIGRhdGFSb3cuc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmRhdGFTdGF0ZVNlcnZpY2Uuc2VsZWN0ZWRSb3cgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmV2ZW50U3RhdGVTZXJ2aWNlLnJvd1NlbGVjdENoYW5nZVN0cmVhbS5lbWl0KHRoaXMuZGF0YVN0YXRlU2VydmljZS5zZWxlY3RlZFJvdyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnc2luZ2xlJzoge1xuICAgICAgICBjb25zdCBwcmV2aW91c1NlbGVjdGlvbiA9IHRoaXMuZGF0YVN0YXRlU2VydmljZS5zZWxlY3RlZFJvdztcbiAgICAgICAgdGhpcy5kYXRhU3RhdGVTZXJ2aWNlLnNlbGVjdGVkUm93ID0gaWQ7XG4gICAgICAgIHJvdy5zZWxlY3RlZCA9IHRydWU7XG5cbiAgICAgICAgLy8gZGVzZWxlY3QgYWxsIG90aGVyIHJvdyBvdGhlciByb3dzXG4gICAgICAgIHRoaXMuZGF0YVN0YXRlU2VydmljZS5kYXRhUm93cy5mb3JFYWNoKChkYXRhUm93OiBEYXRhVGFibGVSb3c8YW55PikgPT4ge1xuICAgICAgICAgIGlmIChkYXRhUm93ICE9PSByb3cpIHtcbiAgICAgICAgICAgIGRhdGFSb3cuc2VsZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChwcmV2aW91c1NlbGVjdGlvbiAhPT0gaWQpIHtcbiAgICAgICAgICB0aGlzLmV2ZW50U3RhdGVTZXJ2aWNlLnJvd1NlbGVjdENoYW5nZVN0cmVhbS5lbWl0KHRoaXMuZGF0YVN0YXRlU2VydmljZS5zZWxlY3RlZFJvdyk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJvdyBjbGlja2VkIGV2ZW50IGhhbmRsZXIuXG4gICAqIEBwYXJhbSByb3cgRGF0YSByb3cgb2JqZWN0LlxuICAgKiBAcGFyYW0gZXZlbnQgTW91c2UgY2xpY2sgZXZlbnQgYXJndW1lbnQgb2JqZWN0LlxuICAgKi9cbiAgcHVibGljIHJvd0NsaWNrZWQocm93OiBEYXRhVGFibGVSb3c8YW55PiwgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jb25maWcuc2VsZWN0T25Sb3dDbGljayB8fCAodGhpcy5jb25maWcuZXhwYW5kYWJsZVJvd3MgJiYgdGhpcy5jb25maWcuZXhwYW5kT25Sb3dDbGljaykpIHtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICAgIGlmICh0YXJnZXQgJiYgdGFyZ2V0LmNsYXNzTGlzdCAmJiB0YXJnZXQuY2xhc3NMaXN0LmNvbnRhaW5zKCduZy1pZ25vcmUtcHJvcGFnYXRpb24nKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmNvbmZpZy5yb3dTZWxlY3RhYmxlICYmIHRoaXMuY29uZmlnLnNlbGVjdE9uUm93Q2xpY2spIHtcbiAgICAgICAgcm93LnNlbGVjdGVkID0gIXJvdy5zZWxlY3RlZDtcbiAgICAgICAgdGhpcy5vblJvd1NlbGVjdENoYW5nZShyb3cpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5jb25maWcuZXhwYW5kT25Sb3dDbGljaykge1xuICAgICAgICByb3cuZXhwYW5kZWQgPSAhcm93LmV4cGFuZGVkO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZXZlbnRTdGF0ZVNlcnZpY2Uucm93Q2xpY2tTdHJlYW0uZW1pdCh7IHJvdywgZXZlbnQgfSk7XG4gIH1cblxuICAvKipcbiAgICogUm93IGRvdWJsZSBjbGlja2VkIGV2ZW50IGhhbmRsZXIuXG4gICAqIEBwYXJhbSByb3cgRGF0YSByb3cgb2JqZWN0LlxuICAgKiBAcGFyYW0gZXZlbnQgRXZlbnQgTW91c2UgY2xpY2sgZXZlbnQgYXJndW1lbnQgb2JqZWN0LlxuICAgKi9cbiAgcHVibGljIHJvd0RvdWJsZUNsaWNrZWQocm93OiBEYXRhVGFibGVSb3c8YW55PiwgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmV2ZW50U3RhdGVTZXJ2aWNlLnJvd0RvdWJsZUNsaWNrU3RyZWFtLmVtaXQoeyByb3csIGV2ZW50IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBzdWJzdGl0dXRlIHJvdyBhdmFpbGFiaWxpdHkgc3RhdHVzLlxuICAgKiBAcmV0dXJuIFRydWUgaWYgc3Vic3RpdHV0ZSByb3dzIGFyZSBhdmFpbGFibGUuXG4gICAqL1xuICBwdWJsaWMgZ2V0IGhhc1N1YnN0aXR1dGVSb3dzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhdGhpcy5jb25maWcubG9hZE9uU2Nyb2xsXG4gICAgICAmJiB0aGlzLmNvbmZpZy5zaG93U3Vic3RpdHV0ZVJvd3NcbiAgICAgICYmIHRoaXMuZGF0YVN0YXRlU2VydmljZS5kYXRhUm93cy5sZW5ndGhcbiAgICAgICYmICF0aGlzLmRhdGFTdGF0ZVNlcnZpY2Uuc2hvd05vRGF0YU92ZXJsYXk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGNlbGwgdmFsdWUgYnkgZGF0YSBmaWVsZC5cbiAgICogQHBhcmFtIHJvdyBEYXRhIHJvdyByZWZlcmVuY2UuXG4gICAqIEBwYXJhbSBjb2x1bW4gRGF0YSB0YWJsZSBjb2x1bW4gY29tcG9uZW50IHJlZmVyZW5jZS5cbiAgICovXG4gIHB1YmxpYyBnZXRGaWVsZFZhbHVlKHJvdzogRGF0YVRhYmxlUm93PGFueT4sIGNvbHVtbjogRGF0YVRhYmxlQ29sdW1uQ29tcG9uZW50KSB7XG4gICAgcmV0dXJuIGdldChyb3cuaXRlbSwgY29sdW1uLmZpZWxkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgcm93IHNlbGVjdCBjaGVja2JveCBkaXNwbGF5IHN0YXR1cy5cbiAgICogQHJldHVybiBUcnVlIGlmIHJvdyBzZWxlY3RvciBjaGVja2JveCBzaG91bGQgYmUgZGlzcGxheWVkLlxuICAgKi9cbiAgcHVibGljIGdldCBzaG93Um93U2VsZWN0Q2hlY2tib3goKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnLnJvd1NlbGVjdGFibGUgJiYgdGhpcy5jb25maWcuc2hvd1Jvd1NlbGVjdENoZWNrYm94O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCByb3cgZXhwZW5kIHZpZXcgbG9hZGluZyBzdGF0dXMuIFVzZWQgdG8gZGlzcGxheSBsb2FkaW5nIHNwaW5uZXIgb24gZXhwYW5kIGNvbHVtbiB3aGlsZSBkYXRhIGZldGNoaW5nLlxuICAgKiBAcGFyYW0gcm93IERhdGEgcm93IG9iamVjdCByZWZlcmVuY2UuXG4gICAqL1xuICBwdWJsaWMgaXNSb3dFeHBhbmRlckxvYWRpbmcocm93OiBEYXRhVGFibGVSb3c8YW55Pik6IGJvb2xlYW4ge1xuICAgIHJldHVybiByb3cuZXhwYW5kZWQgJiYgIXJvdy5kYXRhTG9hZGVkO1xuICB9XG59XG4iXX0=