Coverage.RangeUseCount;Coverage.CoverageSegment;Coverage.CoverageType={CSS:(1<<0),JavaScript:(1<<1),JavaScriptCoarse:(1<<2),};Coverage.CoverageModel=class extends SDK.SDKModel{constructor(target){super(target);this._cpuProfilerModel=target.model(SDK.CPUProfilerModel);this._cssModel=target.model(SDK.CSSModel);this._debuggerModel=target.model(SDK.DebuggerModel);this._coverageByURL=new Map();this._coverageByContentProvider=new Map();this._bestEffortCoveragePromise=null;}
start(){if(this._cssModel){this._clearCSS();this._cssModel.startCoverage();}
if(this._cpuProfilerModel){this._bestEffortCoveragePromise=this._cpuProfilerModel.bestEffortCoverage();this._cpuProfilerModel.startPreciseCoverage();}
return!!(this._cssModel||this._cpuProfilerModel);}
stop(){var pollPromise=this.poll();if(this._cpuProfilerModel)
this._cpuProfilerModel.stopPreciseCoverage();if(this._cssModel)
this._cssModel.stopCoverage();return pollPromise;}
reset(){this._coverageByURL=new Map();this._coverageByContentProvider=new Map();}
async poll(){var updates=await Promise.all([this._takeCSSCoverage(),this._takeJSCoverage()]);return updates[0].concat(updates[1]);}
entries(){return Array.from(this._coverageByURL.values());}
usageForRange(contentProvider,startOffset,endOffset){var coverageInfo=this._coverageByContentProvider.get(contentProvider);return coverageInfo&&coverageInfo.usageForRange(startOffset,endOffset);}
_clearCSS(){for(var entry of this._coverageByContentProvider.values()){if(entry.type()!==Coverage.CoverageType.CSS)
continue;var contentProvider=(entry.contentProvider());this._coverageByContentProvider.delete(contentProvider);var key=`${contentProvider.startLine}:${contentProvider.startColumn}`;var urlEntry=this._coverageByURL.get(entry.url());if(!urlEntry||!urlEntry._coverageInfoByLocation.delete(key))
continue;urlEntry._size-=entry._size;urlEntry._usedSize-=entry._usedSize;if(!urlEntry._coverageInfoByLocation.size)
this._coverageByURL.delete(entry.url());}}
async _takeJSCoverage(){if(!this._cpuProfilerModel)
return[];var rawCoverageData=await this._cpuProfilerModel.takePreciseCoverage();if(this._bestEffortCoveragePromise){var bestEffortCoverage=await this._bestEffortCoveragePromise;this._bestEffortCoveragePromise=null;rawCoverageData=bestEffortCoverage.concat(rawCoverageData);}
return this._processJSCoverage(rawCoverageData);}
_processJSCoverage(scriptsCoverage){var updatedEntries=[];for(var entry of scriptsCoverage){var script=this._debuggerModel.scriptForId(entry.scriptId);if(!script)
continue;var ranges=[];var type=Coverage.CoverageType.JavaScript;for(var func of entry.functions){if(func.isBlockCoverage===false&&!(func.ranges.length===1&&!func.ranges[0].count))
type|=Coverage.CoverageType.JavaScriptCoarse;for(var range of func.ranges)
ranges.push(range);}
var entry=this._addCoverage(script,script.contentLength,script.lineOffset,script.columnOffset,ranges,type);if(entry)
updatedEntries.push(entry);}
return updatedEntries;}
async _takeCSSCoverage(){if(!this._cssModel)
return[];var rawCoverageData=await this._cssModel.takeCoverageDelta();return this._processCSSCoverage(rawCoverageData);}
_processCSSCoverage(ruleUsageList){var updatedEntries=[];var rulesByStyleSheet=new Map();for(var rule of ruleUsageList){var styleSheetHeader=this._cssModel.styleSheetHeaderForId(rule.styleSheetId);if(!styleSheetHeader)
continue;var ranges=rulesByStyleSheet.get(styleSheetHeader);if(!ranges){ranges=[];rulesByStyleSheet.set(styleSheetHeader,ranges);}
ranges.push({startOffset:rule.startOffset,endOffset:rule.endOffset,count:Number(rule.used)});}
for(var entry of rulesByStyleSheet){var styleSheetHeader=(entry[0]);var ranges=(entry[1]);var entry=this._addCoverage(styleSheetHeader,styleSheetHeader.contentLength,styleSheetHeader.startLine,styleSheetHeader.startColumn,ranges,Coverage.CoverageType.CSS);if(entry)
updatedEntries.push(entry);}
return updatedEntries;}
static _convertToDisjointSegments(ranges){ranges.sort((a,b)=>a.startOffset-b.startOffset);var result=[];var stack=[];for(var entry of ranges){var top=stack.peekLast();while(top&&top.endOffset<=entry.startOffset){append(top.endOffset,top.count);stack.pop();top=stack.peekLast();}
append(entry.startOffset,top?top.count:undefined);stack.push(entry);}
while(stack.length){var top=stack.pop();append(top.endOffset,top.count);}
function append(end,count){var last=result.peekLast();if(last){if(last.end===end)
return;if(last.count===count){last.end=end;return;}}
result.push({end:end,count:count});}
return result;}
_addCoverage(contentProvider,contentLength,startLine,startColumn,ranges,type){var url=contentProvider.contentURL();if(!url)
return null;var urlCoverage=this._coverageByURL.get(url);if(!urlCoverage){urlCoverage=new Coverage.URLCoverageInfo(url);this._coverageByURL.set(url,urlCoverage);}
var coverageInfo=urlCoverage._ensureEntry(contentProvider,contentLength,startLine,startColumn,type);this._coverageByContentProvider.set(contentProvider,coverageInfo);var segments=Coverage.CoverageModel._convertToDisjointSegments(ranges);if(segments.length&&segments.peekLast().end<contentLength)
segments.push({end:contentLength});var oldUsedSize=coverageInfo._usedSize;coverageInfo.mergeCoverage(segments);if(coverageInfo._usedSize===oldUsedSize)
return null;urlCoverage._usedSize+=coverageInfo._usedSize-oldUsedSize;return coverageInfo;}};Coverage.URLCoverageInfo=class{constructor(url){this._url=url;this._coverageInfoByLocation=new Map();this._size=0;this._usedSize=0;this._type;this._isContentScript=false;}
url(){return this._url;}
type(){return this._type;}
size(){return this._size;}
usedSize(){return this._usedSize;}
unusedSize(){return this._size-this._usedSize;}
isContentScript(){return this._isContentScript;}
_ensureEntry(contentProvider,contentLength,lineOffset,columnOffset,type){var key=`${lineOffset}:${columnOffset}`;var entry=this._coverageInfoByLocation.get(key);if((type&Coverage.CoverageType.JavaScript)&&!this._coverageInfoByLocation.size)
this._isContentScript=(contentProvider).isContentScript();this._type|=type;if(entry){entry._coverageType|=type;return entry;}
if((type&Coverage.CoverageType.JavaScript)&&!this._coverageInfoByLocation.size)
this._isContentScript=(contentProvider).isContentScript();entry=new Coverage.CoverageInfo(contentProvider,contentLength,type);this._coverageInfoByLocation.set(key,entry);this._size+=contentLength;return entry;}};Coverage.CoverageInfo=class{constructor(contentProvider,size,type){this._contentProvider=contentProvider;this._size=size;this._usedSize=0;this._coverageType=type;this._segments=[];}
contentProvider(){return this._contentProvider;}
url(){return this._contentProvider.contentURL();}
type(){return this._coverageType;}
mergeCoverage(segments){this._segments=Coverage.CoverageInfo._mergeCoverage(this._segments,segments);this._updateStats();}
usageForRange(start,end){var index=this._segments.upperBound(start,(position,segment)=>position-segment.end);for(;index<this._segments.length&&this._segments[index].end<end;++index){if(this._segments[index].count)
return true;}
return index<this._segments.length&&!!this._segments[index].count;}
static _mergeCoverage(segmentsA,segmentsB){var result=[];var indexA=0;var indexB=0;while(indexA<segmentsA.length&&indexB<segmentsB.length){var a=segmentsA[indexA];var b=segmentsB[indexB];var count=typeof a.count==='number'||typeof b.count==='number'?(a.count||0)+(b.count||0):undefined;var end=Math.min(a.end,b.end);var last=result.peekLast();if(!last||last.count!==count)
result.push({end:end,count:count});else
last.end=end;if(a.end<=b.end)
indexA++;if(a.end>=b.end)
indexB++;}
for(;indexA<segmentsA.length;indexA++)
result.push(segmentsA[indexA]);for(;indexB<segmentsB.length;indexB++)
result.push(segmentsB[indexB]);return result;}
_updateStats(){this._usedSize=0;var last=0;for(var segment of this._segments){if(segment.count)
this._usedSize+=segment.end-last;last=segment.end;}}};;Coverage.CoverageListView=class extends UI.VBox{constructor(filterCallback){super(true);this._nodeForCoverageInfo=new Map();this._filterCallback=filterCallback;this._highlightRegExp=null;this.registerRequiredCSS('coverage/coverageListView.css');var columns=[{id:'url',title:Common.UIString('URL'),width:'250px',fixedWidth:false,sortable:true},{id:'type',title:Common.UIString('Type'),width:'45px',fixedWidth:true,sortable:true},{id:'size',title:Common.UIString('Total Bytes'),width:'60px',fixedWidth:true,sortable:true,align:DataGrid.DataGrid.Align.Right},{id:'unusedSize',title:Common.UIString('Unused Bytes'),width:'100px',fixedWidth:true,sortable:true,align:DataGrid.DataGrid.Align.Right,sort:DataGrid.DataGrid.Order.Descending},{id:'bars',title:'',width:'250px',fixedWidth:false,sortable:true}];this._dataGrid=new DataGrid.SortableDataGrid(columns);this._dataGrid.setResizeMethod(DataGrid.DataGrid.ResizeMethod.Last);this._dataGrid.element.classList.add('flex-auto');this._dataGrid.element.addEventListener('keydown',this._onKeyDown.bind(this),false);this._dataGrid.addEventListener(DataGrid.DataGrid.Events.OpenedNode,this._onOpenedNode,this);this._dataGrid.addEventListener(DataGrid.DataGrid.Events.SortingChanged,this._sortingChanged,this);var dataGridWidget=this._dataGrid.asWidget();dataGridWidget.show(this.contentElement);}
update(coverageInfo){var hadUpdates=false;var maxSize=coverageInfo.reduce((acc,entry)=>Math.max(acc,entry.size()),0);var rootNode=this._dataGrid.rootNode();for(var entry of coverageInfo){var node=this._nodeForCoverageInfo.get(entry);if(node){if(this._filterCallback(node._coverageInfo))
hadUpdates=node._refreshIfNeeded(maxSize)||hadUpdates;continue;}
node=new Coverage.CoverageListView.GridNode(entry,maxSize);this._nodeForCoverageInfo.set(entry,node);if(this._filterCallback(node._coverageInfo)){rootNode.appendChild(node);hadUpdates=true;}}
if(hadUpdates)
this._sortingChanged();}
reset(){this._nodeForCoverageInfo.clear();this._dataGrid.rootNode().removeChildren();}
updateFilterAndHighlight(highlightRegExp){this._highlightRegExp=highlightRegExp;var hadTreeUpdates=false;for(var node of this._nodeForCoverageInfo.values()){var shouldBeVisible=this._filterCallback(node._coverageInfo);var isVisible=!!node.parent;if(shouldBeVisible)
node._setHighlight(this._highlightRegExp);if(shouldBeVisible===isVisible)
continue;hadTreeUpdates=true;if(!shouldBeVisible)
node.remove();else
this._dataGrid.rootNode().appendChild(node);}
if(hadTreeUpdates)
this._sortingChanged();}
_onOpenedNode(){this._revealSourceForSelectedNode();}
_onKeyDown(event){if(!isEnterKey(event))
return;event.consume(true);this._revealSourceForSelectedNode();}
async _revealSourceForSelectedNode(){var node=this._dataGrid.selectedNode;if(!node)
return;var coverageInfo=(node)._coverageInfo;var sourceCode=Workspace.workspace.uiSourceCodeForURL(coverageInfo.url());if(!sourceCode)
return;var content=await sourceCode.requestContent();if(TextUtils.isMinified(content)){var formatData=await Sources.sourceFormatter.format(sourceCode);sourceCode=formatData.formattedSourceCode;}
if(this._dataGrid.selectedNode!==node)
return;Common.Revealer.reveal(sourceCode);}
_sortingChanged(){var columnId=this._dataGrid.sortColumnId();if(!columnId)
return;var sortFunction;switch(columnId){case'url':sortFunction=compareURL;break;case'type':sortFunction=compareType;break;case'size':sortFunction=compareNumericField.bind(null,'size');break;case'bars':case'unusedSize':sortFunction=compareNumericField.bind(null,'unusedSize');break;default:console.assert(false,'Unknown sort field: '+columnId);return;}
this._dataGrid.sortNodes(sortFunction,!this._dataGrid.isSortOrderAscending());function compareURL(a,b){var nodeA=(a);var nodeB=(b);return nodeA._url.localeCompare(nodeB._url);}
function compareNumericField(fieldName,a,b){var nodeA=(a);var nodeB=(b);return nodeA._coverageInfo[fieldName]()-nodeB._coverageInfo[fieldName]()||compareURL(a,b);}
function compareType(a,b){var nodeA=(a);var nodeB=(b);var typeA=Coverage.CoverageListView._typeToString(nodeA._coverageInfo.type());var typeB=Coverage.CoverageListView._typeToString(nodeB._coverageInfo.type());return typeA.localeCompare(typeB)||compareURL(a,b);}}
static _typeToString(type){var types=[];if(type&Coverage.CoverageType.CSS)
types.push(Common.UIString('CSS'));if(type&Coverage.CoverageType.JavaScriptCoarse)
types.push(Common.UIString('JS (coarse)'));else if(type&Coverage.CoverageType.JavaScript)
types.push(Common.UIString('JS'));return types.join('+');}};Coverage.CoverageListView.GridNode=class extends DataGrid.SortableDataGridNode{constructor(coverageInfo,maxSize){super();this._coverageInfo=coverageInfo;this._lastUsedSize;this._url=coverageInfo.url();this._maxSize=maxSize;this._highlightDOMChanges=[];this._highlightRegExp=null;}
_setHighlight(highlightRegExp){if(this._highlightRegExp===highlightRegExp)
return;this._highlightRegExp=highlightRegExp;this.refresh();}
_refreshIfNeeded(maxSize){if(this._lastUsedSize===this._coverageInfo.usedSize()&&maxSize===this._maxSize)
return false;this._lastUsedSize=this._coverageInfo.usedSize();this._maxSize=maxSize;this.refresh();return true;}
createCell(columnId){var cell=this.createTD(columnId);switch(columnId){case'url':cell.title=this._url;var outer=cell.createChild('div','url-outer');var prefix=outer.createChild('div','url-prefix');var suffix=outer.createChild('div','url-suffix');var splitURL=/^(.*)(\/[^/]*)$/.exec(this._url);prefix.textContent=splitURL?splitURL[1]:this._url;suffix.textContent=splitURL?splitURL[2]:'';if(this._highlightRegExp)
this._highlight(outer,this._url);break;case'type':cell.textContent=Coverage.CoverageListView._typeToString(this._coverageInfo.type());if(this._coverageInfo.type()&Coverage.CoverageType.JavaScriptCoarse)
cell.title=Common.UIString('JS coverage is function-level only. Reload the page for block-level coverage.');break;case'size':cell.textContent=Number.withThousandsSeparator(this._coverageInfo.size()||0);break;case'unusedSize':var unusedSize=this._coverageInfo.unusedSize()||0;var unusedSizeSpan=cell.createChild('span');var unusedPercentsSpan=cell.createChild('span','percent-value');unusedSizeSpan.textContent=Number.withThousandsSeparator(unusedSize);unusedPercentsSpan.textContent=Common.UIString('%.1f\xa0%%',unusedSize/this._coverageInfo.size()*100);break;case'bars':var barContainer=cell.createChild('div','bar-container');var unusedSizeBar=barContainer.createChild('div','bar bar-unused-size');unusedSizeBar.style.width=(100*this._coverageInfo.unusedSize()/this._maxSize).toFixed(4)+'%';var usedSizeBar=barContainer.createChild('div','bar bar-used-size');usedSizeBar.style.width=(100*this._coverageInfo.usedSize()/this._maxSize).toFixed(4)+'%';}
return cell;}
_highlight(element,textContent){var matches=this._highlightRegExp.exec(textContent);if(!matches||!matches.length)
return;var range=new TextUtils.SourceRange(matches.index,matches[0].length);UI.highlightRangesWithStyleClass(element,[range],'filter-highlight');}};;Coverage.CoverageView=class extends UI.VBox{constructor(){super(true);this._model=null;this._pollTimer;this._decorationManager=null;this._resourceTreeModel=null;this.registerRequiredCSS('coverage/coverageView.css');var toolbarContainer=this.contentElement.createChild('div','coverage-toolbar-container');var toolbar=new UI.Toolbar('coverage-toolbar',toolbarContainer);this._toggleRecordAction=(UI.actionRegistry.action('coverage.toggle-recording'));this._toggleRecordButton=UI.Toolbar.createActionButton(this._toggleRecordAction);toolbar.appendToolbarItem(this._toggleRecordButton);var startWithReloadAction=(UI.actionRegistry.action('coverage.start-with-reload'));this._startWithReloadButton=UI.Toolbar.createActionButton(startWithReloadAction);toolbar.appendToolbarItem(this._startWithReloadButton);this._clearButton=new UI.ToolbarButton(Common.UIString('Clear all'),'largeicon-clear');this._clearButton.addEventListener(UI.ToolbarButton.Events.Click,this._clear.bind(this));toolbar.appendToolbarItem(this._clearButton);this._textFilterRegExp=null;toolbar.appendSeparator();this._filterInput=new UI.ToolbarInput(Common.UIString('URL filter'),0.4,1);this._filterInput.setEnabled(false);this._filterInput.addEventListener(UI.ToolbarInput.Event.TextChanged,this._onFilterChanged,this);toolbar.appendToolbarItem(this._filterInput);toolbar.appendSeparator();this._showContentScriptsSetting=Common.settings.createSetting('showContentScripts',false);this._showContentScriptsSetting.addChangeListener(this._onFilterChanged,this);var contentScriptsCheckbox=new UI.ToolbarSettingCheckbox(this._showContentScriptsSetting,Common.UIString('Include extension content scripts'),Common.UIString('Content scripts'));toolbar.appendToolbarItem(contentScriptsCheckbox);this._coverageResultsElement=this.contentElement.createChild('div','coverage-results');this._landingPage=this._buildLandingPage();this._listView=new Coverage.CoverageListView(this._isVisible.bind(this,false));this._statusToolbarElement=this.contentElement.createChild('div','coverage-toolbar-summary');this._statusMessageElement=this._statusToolbarElement.createChild('div','coverage-message');this._landingPage.show(this._coverageResultsElement);}
_buildLandingPage(){var recordButton=UI.createInlineButton(UI.Toolbar.createActionButton(this._toggleRecordAction));var reloadButton=UI.createInlineButton(UI.Toolbar.createActionButtonForId('coverage.start-with-reload'));var widget=new UI.VBox();var message=UI.formatLocalized('Click the record button %s to start capturing coverage.\n'+'Click the reload button %s to reload and start capturing coverage.',[recordButton,reloadButton]);message.classList.add('message');widget.contentElement.appendChild(message);widget.element.classList.add('landing-page');return widget;}
_clear(){this._model=null;this._reset();}
_reset(){if(this._decorationManager){this._decorationManager.dispose();this._decorationManager=null;}
this._listView.reset();this._listView.detach();this._landingPage.show(this._coverageResultsElement);this._statusMessageElement.textContent='';this._filterInput.setEnabled(false);}
_toggleRecording(){var enable=!this._toggleRecordAction.toggled();if(enable)
this._startRecording(false);else
this._stopRecording();}
_startRecording(reload){this._reset();var mainTarget=SDK.targetManager.mainTarget();if(!mainTarget)
return;this._resourceTreeModel=(mainTarget.model(SDK.ResourceTreeModel));if(!this._resourceTreeModel)
return;if(!this._model||reload)
this._model=new Coverage.CoverageModel(mainTarget);Host.userMetrics.actionTaken(Host.UserMetrics.Action.CoverageStarted);if(!this._model.start())
return;this._resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.MainFrameNavigated,this._onMainFrameNavigated,this);this._decorationManager=new Coverage.CoverageDecorationManager(this._model);this._toggleRecordAction.setToggled(true);this._clearButton.setEnabled(false);this._startWithReloadButton.setEnabled(false);this._filterInput.setEnabled(true);if(this._landingPage.isShowing())
this._landingPage.detach();this._listView.show(this._coverageResultsElement);if(reload)
this._resourceTreeModel.reloadPage();else
this._poll();}
async _poll(){delete this._pollTimer;var updates=await this._model.poll();this._updateViews(updates);this._pollTimer=setTimeout(()=>this._poll(),700);}
async _stopRecording(){if(this._pollTimer){clearTimeout(this._pollTimer);delete this._pollTimer;}
this._resourceTreeModel.removeEventListener(SDK.ResourceTreeModel.Events.MainFrameNavigated,this._onMainFrameNavigated,this);this._resourceTreeModel=null;var updatedEntries=await this._model.stop();this._updateViews(updatedEntries);this._toggleRecordAction.setToggled(false);this._startWithReloadButton.setEnabled(true);this._clearButton.setEnabled(true);}
_onMainFrameNavigated(){this._model.reset();this._decorationManager.reset();this._listView.reset();this._poll();}
async _updateViews(updatedEntries){this._updateStats();this._listView.update(this._model.entries());this._decorationManager.update(updatedEntries);}
_updateStats(){var total=0;var unused=0;for(var info of this._model.entries()){if(!this._isVisible(true,info))
continue;total+=info.size();unused+=info.unusedSize();}
var percentUnused=total?Math.round(100*unused/total):0;this._statusMessageElement.textContent=Common.UIString('%s of %s bytes are not used. (%d%%)',Number.bytesToString(unused),Number.bytesToString(total),percentUnused);}
_onFilterChanged(){if(!this._listView)
return;var text=this._filterInput.value();this._textFilterRegExp=text?createPlainTextSearchRegex(text,'i'):null;this._listView.updateFilterAndHighlight(this._textFilterRegExp);this._updateStats();}
_isVisible(ignoreTextFilter,coverageInfo){var url=coverageInfo.url();if(url.startsWith(Coverage.CoverageView._extensionBindingsURLPrefix))
return false;if(coverageInfo.isContentScript()&&!this._showContentScriptsSetting.get())
return false;return ignoreTextFilter||!this._textFilterRegExp||this._textFilterRegExp.test(url);}};Coverage.CoverageView._extensionBindingsURLPrefix='extensions::';Coverage.CoverageView.ActionDelegate=class{handleAction(context,actionId){var coverageViewId='coverage';UI.viewManager.showView(coverageViewId).then(()=>UI.viewManager.view(coverageViewId).widget()).then(widget=>this._innerHandleAction((widget),actionId));return true;}
_innerHandleAction(coverageView,actionId){switch(actionId){case'coverage.toggle-recording':coverageView._toggleRecording();break;case'coverage.start-with-reload':coverageView._startRecording(true);break;default:console.assert(false,`Unknown action: ${actionId}`);}}};;Coverage.RawLocation;Coverage.CoverageDecorationManager=class{constructor(coverageModel){this._coverageModel=coverageModel;this._textByProvider=new Map();this._uiSourceCodeByContentProvider=new Multimap();this._documentUISouceCodeToStylesheets=new WeakMap();for(var uiSourceCode of Workspace.workspace.uiSourceCodes())
uiSourceCode.addLineDecoration(0,Coverage.CoverageDecorationManager._decoratorType,this);Workspace.workspace.addEventListener(Workspace.Workspace.Events.UISourceCodeAdded,this._onUISourceCodeAdded,this);}
reset(){for(var uiSourceCode of Workspace.workspace.uiSourceCodes())
uiSourceCode.removeDecorationsForType(Coverage.CoverageDecorationManager._decoratorType);}
dispose(){this.reset();Workspace.workspace.removeEventListener(Workspace.Workspace.Events.UISourceCodeAdded,this._onUISourceCodeAdded,this);}
update(updatedEntries){for(var entry of updatedEntries){for(var uiSourceCode of this._uiSourceCodeByContentProvider.get(entry.contentProvider())){uiSourceCode.removeDecorationsForType(Coverage.CoverageDecorationManager._decoratorType);uiSourceCode.addLineDecoration(0,Coverage.CoverageDecorationManager._decoratorType,this);}}}
async usageByLine(uiSourceCode){var result=[];var sourceText=new TextUtils.Text(uiSourceCode.content()||'');await this._updateTexts(uiSourceCode,sourceText);var lineEndings=sourceText.lineEndings();for(var line=0;line<sourceText.lineCount();++line){var lineLength=lineEndings[line]-(line?lineEndings[line-1]:0)-1;if(!lineLength){result.push(undefined);continue;}
var startLocations=this._rawLocationsForSourceLocation(uiSourceCode,line,0);var endLocations=this._rawLocationsForSourceLocation(uiSourceCode,line,lineLength);var used=undefined;for(var startIndex=0,endIndex=0;startIndex<startLocations.length;++startIndex){var start=startLocations[startIndex];while(endIndex<endLocations.length&&Coverage.CoverageDecorationManager._compareLocations(start,endLocations[endIndex])>=0)
++endIndex;if(endIndex>=endLocations.length||endLocations[endIndex].id!==start.id)
continue;var end=endLocations[endIndex++];var text=this._textByProvider.get(end.contentProvider);if(!text)
continue;var textValue=text.value();var startOffset=Math.min(text.offsetFromPosition(start.line,start.column),textValue.length-1);var endOffset=Math.min(text.offsetFromPosition(end.line,end.column),textValue.length-1);while(startOffset<=endOffset&&/\s/.test(textValue[startOffset]))
++startOffset;while(startOffset<=endOffset&&/\s/.test(textValue[endOffset]))
--endOffset;if(startOffset<=endOffset)
used=this._coverageModel.usageForRange(end.contentProvider,startOffset,endOffset);if(used)
break;}
result.push(used);}
return result;}
_updateTexts(uiSourceCode,text){var promises=[];for(var line=0;line<text.lineCount();++line){for(var entry of this._rawLocationsForSourceLocation(uiSourceCode,line,0)){if(this._textByProvider.has(entry.contentProvider))
continue;this._textByProvider.set(entry.contentProvider,null);this._uiSourceCodeByContentProvider.set(entry.contentProvider,uiSourceCode);promises.push(this._updateTextForProvider(entry.contentProvider));}}
return Promise.all(promises);}
async _updateTextForProvider(contentProvider){var content=await contentProvider.requestContent();this._textByProvider.set(contentProvider,new TextUtils.Text(content));}
_rawLocationsForSourceLocation(uiSourceCode,line,column){var result=[];var contentType=uiSourceCode.contentType();if(contentType.hasScripts()){var location=Bindings.debuggerWorkspaceBinding.uiLocationToRawLocation(uiSourceCode,line,column);if(location&&location.script()){var script=location.script();if(script.isInlineScript()&&contentType.isDocument()){if(comparePositions(script.lineOffset,script.columnOffset,location.lineNumber,location.columnNumber)>0||comparePositions(script.endLine,script.endColumn,location.lineNumber,location.columnNumber)<=0){location=null;}else{location.lineNumber-=script.lineOffset;if(!location.lineNumber)
location.columnNumber-=script.columnOffset;}}
if(location){result.push({id:`js:${location.scriptId}`,contentProvider:location.script(),line:location.lineNumber,column:location.columnNumber});}}}
if(contentType.isStyleSheet()||contentType.isDocument()){var rawStyleLocations=contentType.isDocument()?this._documentUILocationToCSSRawLocations(uiSourceCode,line,column):Bindings.cssWorkspaceBinding.uiLocationToRawLocations(new Workspace.UILocation(uiSourceCode,line,column));for(var location of rawStyleLocations){var header=location.header();if(!header)
continue;if(header.isInline&&contentType.isDocument()){location.lineNumber-=header.startLine;if(!location.lineNumber)
location.columnNumber-=header.startColumn;}
result.push({id:`css:${location.styleSheetId}`,contentProvider:location.header(),line:location.lineNumber,column:location.columnNumber});}}
result.sort(Coverage.CoverageDecorationManager._compareLocations);function comparePositions(aLine,aColumn,bLine,bColumn){return aLine-bLine||aColumn-bColumn;}
return result;}
_documentUILocationToCSSRawLocations(uiSourceCode,line,column){var stylesheets=this._documentUISouceCodeToStylesheets.get(uiSourceCode);if(!stylesheets){stylesheets=[];var cssModel=this._coverageModel.target().model(SDK.CSSModel);if(!cssModel)
return[];for(var headerId of cssModel.styleSheetIdsForURL(uiSourceCode.url())){var header=cssModel.styleSheetHeaderForId(headerId);if(header)
stylesheets.push(header);}
stylesheets.sort(stylesheetComparator);this._documentUISouceCodeToStylesheets.set(uiSourceCode,stylesheets);}
var endIndex=stylesheets.upperBound(undefined,(unused,header)=>line-header.startLine||column-header.startColumn);if(!endIndex)
return[];var locations=[];var last=stylesheets[endIndex-1];for(var index=endIndex-1;index>=0&&stylesheets[index].startLine===last.startLine&&stylesheets[index].startColumn===last.startColumn;--index)
locations.push(new SDK.CSSLocation(stylesheets[index],line,column));return locations;function stylesheetComparator(a,b){return a.startLine-b.startLine||a.startColumn-b.startColumn||a.id.localeCompare(b.id);}}
static _compareLocations(a,b){return a.id.localeCompare(b.id)||a.line-b.line||a.column-b.column;}
_onUISourceCodeAdded(event){var uiSourceCode=(event.data);uiSourceCode.addLineDecoration(0,Coverage.CoverageDecorationManager._decoratorType,this);}};Coverage.CoverageDecorationManager._decoratorType='coverage';Coverage.CoverageView.LineDecorator=class{decorate(uiSourceCode,textEditor){var decorations=uiSourceCode.decorationsForType(Coverage.CoverageDecorationManager._decoratorType);if(!decorations||!decorations.size){textEditor.uninstallGutter(Coverage.CoverageView.LineDecorator._gutterType);return;}
var decorationManager=(decorations.values().next().value.data());decorationManager.usageByLine(uiSourceCode).then(lineUsage=>{textEditor.operation(()=>this._innerDecorate(textEditor,lineUsage));});}
_innerDecorate(textEditor,lineUsage){var gutterType=Coverage.CoverageView.LineDecorator._gutterType;textEditor.uninstallGutter(gutterType);textEditor.installGutter(gutterType,false);for(var line=0;line<lineUsage.length;++line){if(typeof lineUsage[line]!=='boolean')
continue;var className=lineUsage[line]?'text-editor-coverage-used-marker':'text-editor-coverage-unused-marker';textEditor.setGutterDecoration(line,gutterType,createElementWithClass('div',className));}}};Coverage.CoverageView.LineDecorator._gutterType='CodeMirror-gutter-coverage';;Runtime.cachedResources["coverage/coverageListView.css"]=".data-grid {\n  border: none;\n}\n\n.data-grid td .url-outer {\n  width: 100%;\n  display: inline-flex;\n  justify-content: flex-start;\n}\n\n.data-grid td .url-outer .filter-highlight {\n  font-weight: bold;\n}\n\n.data-grid td .url-prefix {\n  overflow-x: hidden;\n  text-overflow: ellipsis;\n}\n\n.data-grid td .url-suffix {\n  flex: none;\n}\n\n.data-grid td .bar {\n  display: inline-block;\n  height: 8px;\n}\n\n.data-grid .selected td .bar {\n  border-top: 1px white solid;\n  border-bottom: 1px white solid;\n}\n\n.data-grid .selected td .bar:last-child {\n  border-right: 1px white solid;\n}\n\n.data-grid .selected td .bar:first-child {\n  border-left: 1px white solid;\n}\n\n.data-grid td .bar-container {\n}\n\n.data-grid td .bar-unused-size {\n  background-color: #E57373;\n}\n\n.data-grid td .bar-used-size {\n  background-color: #81C784;\n}\n\n.data-grid td .percent-value {\n  color: #888;\n  width: 45px;\n  display: inline-block;\n}\n\n.data-grid:focus tr.selected span.percent-value {\n  color: #eee;\n}\n\n/*# sourceURL=coverage/coverageListView.css */";Runtime.cachedResources["coverage/coverageView.css"]="/*\n * Copyright (c) 2016 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n    overflow: hidden;\n}\n\n.coverage-toolbar-container {\n    display: flex;\n    border-bottom: 1px solid #ccc;\n    flex: 0 0;\n}\n\n.coverage-toolbar {\n    display: inline-block;\n}\n\n.coverage-toolbar-summary {\n    background-color: #eee;\n    border-top: 1px solid #ccc;\n    padding-left: 5px;\n    flex: 0 0 19px;\n    display: flex;\n    padding-right: 5px;\n}\n\n.coverage-toolbar-summary .coverage-message {\n    padding-top: 2px;\n    padding-left: 1ex;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n    overflow: hidden;\n}\n\n.coverage-results {\n    overflow-y: auto;\n    display: flex;\n    flex: auto;\n}\n\n.landing-page {\n    justify-content: center;\n    align-items:  center;\n    padding: 20px;\n}\n\n.landing-page .message {\n    white-space: pre-line;\n}\n\n/*# sourceURL=coverage/coverageView.css */";