import{UIString,Revealer,ObjectWrapper,Settings}from'../common/common.js';import{NetworkManager,SDKModel,EmulationModel}from'../sdk/sdk.js';import{userMetrics,UserMetrics}from'../host/host.js';import{ARIAUtils,Toolbar,Icon,Widget,UIUtils,ListWidget}from'../ui/ui.js';const CPUThrottlingRates={NoThrottling:1,MidTierMobile:4,LowEndMobile:6,};const NoThrottlingConditions={title:NetworkManager.NoThrottlingConditions.title,description:UIString.UIString('No throttling'),network:NetworkManager.NoThrottlingConditions,cpuThrottlingRate:CPUThrottlingRates.NoThrottling,};const OfflineConditions={title:NetworkManager.OfflineConditions.title,description:UIString.UIString('No internet connectivity'),network:NetworkManager.OfflineConditions,cpuThrottlingRate:CPUThrottlingRates.NoThrottling,};const LowEndMobileConditions={title:UIString.UIString('Low-end mobile'),description:UIString.UIString('Slow 3G & 6x CPU slowdown'),network:NetworkManager.Slow3GConditions,cpuThrottlingRate:CPUThrottlingRates.LowEndMobile,};const MidTierMobileConditions={title:UIString.UIString('Mid-tier mobile'),description:UIString.UIString('Fast 3G & 4x CPU slowdown'),network:NetworkManager.Fast3GConditions,cpuThrottlingRate:CPUThrottlingRates.MidTierMobile,};const CustomConditions={title:UIString.UIString('Custom'),description:UIString.UIString('Check Network and Performance panels'),};const mobilePresets=[MidTierMobileConditions,LowEndMobileConditions,CustomConditions];const advancedMobilePresets=[OfflineConditions,];const networkPresets=[NetworkManager.Fast3GConditions,NetworkManager.Slow3GConditions,NetworkManager.OfflineConditions,];const cpuThrottlingPresets=[CPUThrottlingRates.NoThrottling,CPUThrottlingRates.MidTierMobile,CPUThrottlingRates.LowEndMobile,];let Conditions;let NetworkThrottlingConditionsGroup;let MobileThrottlingConditionsGroup;let ConditionsList;let PlaceholderConditions;var ThrottlingPresets=Object.freeze({__proto__:null,CPUThrottlingRates:CPUThrottlingRates,NoThrottlingConditions:NoThrottlingConditions,OfflineConditions:OfflineConditions,LowEndMobileConditions:LowEndMobileConditions,MidTierMobileConditions:MidTierMobileConditions,CustomConditions:CustomConditions,mobilePresets:mobilePresets,advancedMobilePresets:advancedMobilePresets,networkPresets:networkPresets,cpuThrottlingPresets:cpuThrottlingPresets,Conditions:Conditions,NetworkThrottlingConditionsGroup:NetworkThrottlingConditionsGroup,MobileThrottlingConditionsGroup:MobileThrottlingConditionsGroup,ConditionsList:ConditionsList,PlaceholderConditions:PlaceholderConditions});class NetworkThrottlingSelector{constructor(populateCallback,selectCallback,customNetworkConditionsSetting){this._populateCallback=populateCallback;this._selectCallback=selectCallback;this._customNetworkConditionsSetting=customNetworkConditionsSetting;this._customNetworkConditionsSetting.addChangeListener(this._populateOptions,this);NetworkManager.MultitargetNetworkManager.instance().addEventListener(NetworkManager.MultitargetNetworkManager.Events.ConditionsChanged,()=>{this._networkConditionsChanged();},this);this._options;this._populateOptions();}
revealAndUpdate(){Revealer.reveal(this._customNetworkConditionsSetting);this._networkConditionsChanged();}
optionSelected(conditions){NetworkManager.MultitargetNetworkManager.instance().setNetworkConditions(conditions);}
_populateOptions(){const disabledGroup={title:UIString.UIString('Disabled'),items:[NetworkManager.NoThrottlingConditions]};const presetsGroup={title:UIString.UIString('Presets'),items:networkPresets};const customGroup={title:UIString.UIString('Custom'),items:this._customNetworkConditionsSetting.get()};this._options=this._populateCallback([disabledGroup,presetsGroup,customGroup]);if(!this._networkConditionsChanged()){for(let i=this._options.length-1;i>=0;i--){if(this._options[i]){this.optionSelected((this._options[i]));break;}}}}
_networkConditionsChanged(){const value=NetworkManager.MultitargetNetworkManager.instance().networkConditions();for(let index=0;index<this._options.length;++index){const option=this._options[index];if(option&&option.download===value.download&&option.upload===value.upload&&option.latency===value.latency&&option.title===value.title){this._selectCallback(index);return true;}}
return false;}}
var NetworkThrottlingSelector$1=Object.freeze({__proto__:null,NetworkThrottlingSelector:NetworkThrottlingSelector});class ThrottlingManager extends ObjectWrapper.ObjectWrapper{constructor(){super();this._cpuThrottlingRate=CPUThrottlingRates.NoThrottling;this._cpuThrottlingControls=new Set();this._cpuThrottlingRates=cpuThrottlingPresets;this._customNetworkConditionsSetting=Settings.Settings.instance().moduleSetting('customNetworkConditions');this._currentNetworkThrottlingConditions=NetworkManager.NoThrottlingConditions;this._lastNetworkThrottlingConditions;NetworkManager.MultitargetNetworkManager.instance().addEventListener(NetworkManager.MultitargetNetworkManager.Events.ConditionsChanged,()=>{this._lastNetworkThrottlingConditions=this._currentNetworkThrottlingConditions;this._currentNetworkThrottlingConditions=NetworkManager.MultitargetNetworkManager.instance().networkConditions();});SDKModel.TargetManager.instance().observeModels(EmulationModel.EmulationModel,this);}
decorateSelectWithNetworkThrottling(selectElement){let options=[];const selector=new NetworkThrottlingSelector(populate,select,this._customNetworkConditionsSetting);selectElement.addEventListener('change',optionSelected,false);return selector;function populate(groups){selectElement.removeChildren();options=[];for(let i=0;i<groups.length;++i){const group=groups[i];const groupElement=selectElement.createChild('optgroup');groupElement.label=group.title;for(const conditions of group.items){const title=conditions.title;const option=new Option(title,title);ARIAUtils.setAccessibleName(option,ls`${group.title}: ${title}`);groupElement.appendChild(option);options.push(conditions);}
if(i===groups.length-1){const option=new Option(ls`Add…`,ls`Add…`);ARIAUtils.setAccessibleName(option,ls`Add ${group.title}`);groupElement.appendChild(option);options.push(null);}}
return options;}
function optionSelected(){if(selectElement.selectedIndex===selectElement.options.length-1){selector.revealAndUpdate();}else{selector.optionSelected(options[selectElement.selectedIndex]);}}
function select(index){if(selectElement.selectedIndex!==index){selectElement.selectedIndex=index;}}}
createOfflineToolbarCheckbox(){const checkbox=new Toolbar.ToolbarCheckbox(UIString.UIString('Offline'),UIString.UIString('Force disconnected from network'),forceOffline.bind(this));NetworkManager.MultitargetNetworkManager.instance().addEventListener(NetworkManager.MultitargetNetworkManager.Events.ConditionsChanged,networkConditionsChanged);checkbox.setChecked(NetworkManager.MultitargetNetworkManager.instance().networkConditions()===NetworkManager.OfflineConditions);function forceOffline(){if(checkbox.checked()){NetworkManager.MultitargetNetworkManager.instance().setNetworkConditions(NetworkManager.OfflineConditions);}else{NetworkManager.MultitargetNetworkManager.instance().setNetworkConditions(this._lastNetworkThrottlingConditions);}}
function networkConditionsChanged(){checkbox.setChecked(NetworkManager.MultitargetNetworkManager.instance().networkConditions()===NetworkManager.OfflineConditions);}
return checkbox;}
createMobileThrottlingButton(){const button=new Toolbar.ToolbarMenuButton(appendItems);button.setTitle(UIString.UIString('Throttling'));button.setGlyph('');button.turnIntoSelect();button.setDarkText();let options=[];let selectedIndex=-1;const selector=new MobileThrottlingSelector(populate,select);return button;function appendItems(contextMenu){for(let index=0;index<options.length;++index){const conditions=options[index];if(!conditions){continue;}
if(conditions.title===CustomConditions.title&&conditions.description===CustomConditions.description){continue;}
contextMenu.defaultSection().appendCheckboxItem(UIString.UIString(conditions.title),selector.optionSelected.bind(selector,(conditions)),selectedIndex===index);}}
function populate(groups){options=[];for(const group of groups){for(const conditions of group.items){options.push(conditions);}
options.push(null);}
return options;}
function select(index){selectedIndex=index;button.setText(options[index].title);button.setTitle(options[index].description);}}
cpuThrottlingRate(){return this._cpuThrottlingRate;}
setCPUThrottlingRate(rate){this._cpuThrottlingRate=rate;for(const emulationModel of SDKModel.TargetManager.instance().models(EmulationModel.EmulationModel)){emulationModel.setCPUThrottlingRate(this._cpuThrottlingRate);}
let icon=null;if(this._cpuThrottlingRate!==CPUThrottlingRates.NoThrottling){userMetrics.actionTaken(UserMetrics.Action.CpuThrottlingEnabled);icon=Icon.Icon.create('smallicon-warning');icon.title=UIString.UIString('CPU throttling is enabled');}
const index=this._cpuThrottlingRates.indexOf(this._cpuThrottlingRate);for(const control of this._cpuThrottlingControls){control.setSelectedIndex(index);}
self.UI.inspectorView.setPanelIcon('timeline',icon);this.dispatchEventToListeners(Events.RateChanged,this._cpuThrottlingRate);}
modelAdded(emulationModel){if(this._cpuThrottlingRate!==CPUThrottlingRates.NoThrottling){emulationModel.setCPUThrottlingRate(this._cpuThrottlingRate);}}
modelRemoved(emulationModel){}
createCPUThrottlingSelector(){const control=new Toolbar.ToolbarComboBox(event=>this.setCPUThrottlingRate(this._cpuThrottlingRates[event.target.selectedIndex]),ls`CPU throttling`);this._cpuThrottlingControls.add(control);const currentRate=this._cpuThrottlingRate;for(let i=0;i<this._cpuThrottlingRates.length;++i){const rate=this._cpuThrottlingRates[i];const title=rate===1?UIString.UIString('No throttling'):UIString.UIString('%d× slowdown',rate);const option=control.createOption(title);control.addOption(option);if(currentRate===rate){control.setSelectedIndex(i);}}
return control;}}
const Events={RateChanged:Symbol('RateChanged')};class ActionDelegate{handleAction(context,actionId){if(actionId==='network-conditions.network-online'){NetworkManager.MultitargetNetworkManager.instance().setNetworkConditions(NetworkManager.NoThrottlingConditions);return true;}
if(actionId==='network-conditions.network-low-end-mobile'){NetworkManager.MultitargetNetworkManager.instance().setNetworkConditions(NetworkManager.Slow3GConditions);return true;}
if(actionId==='network-conditions.network-mid-tier-mobile'){NetworkManager.MultitargetNetworkManager.instance().setNetworkConditions(NetworkManager.Fast3GConditions);return true;}
if(actionId==='network-conditions.network-offline'){NetworkManager.MultitargetNetworkManager.instance().setNetworkConditions(NetworkManager.OfflineConditions);return true;}
return false;}}
function throttlingManager(){return self.singleton(ThrottlingManager);}
var ThrottlingManager$1=Object.freeze({__proto__:null,ThrottlingManager:ThrottlingManager,Events:Events,ActionDelegate:ActionDelegate,throttlingManager:throttlingManager});class MobileThrottlingSelector{constructor(populateCallback,selectCallback){this._populateCallback=populateCallback;this._selectCallback=selectCallback;throttlingManager().addEventListener(Events.RateChanged,this._conditionsChanged,this);NetworkManager.MultitargetNetworkManager.instance().addEventListener(NetworkManager.MultitargetNetworkManager.Events.ConditionsChanged,this._conditionsChanged,this);this._options=this._populateOptions();this._conditionsChanged();}
optionSelected(conditions){NetworkManager.MultitargetNetworkManager.instance().setNetworkConditions(conditions.network);throttlingManager().setCPUThrottlingRate(conditions.cpuThrottlingRate);}
_populateOptions(){const disabledGroup={title:UIString.UIString('Disabled'),items:[NoThrottlingConditions]};const presetsGroup={title:UIString.UIString('Presets'),items:mobilePresets};const advancedGroup={title:UIString.UIString('Advanced'),items:advancedMobilePresets};return this._populateCallback([disabledGroup,presetsGroup,advancedGroup]);}
_conditionsChanged(){const networkConditions=NetworkManager.MultitargetNetworkManager.instance().networkConditions();const cpuThrottlingRate=throttlingManager().cpuThrottlingRate();for(let index=0;index<this._options.length;++index){const option=this._options[index];if(option&&option.network===networkConditions&&option.cpuThrottlingRate===cpuThrottlingRate){this._selectCallback(index);return;}}
this._selectCallback(this._options.indexOf(CustomConditions));}}
var MobileThrottlingSelector$1=Object.freeze({__proto__:null,MobileThrottlingSelector:MobileThrottlingSelector});class NetworkPanelIndicator{constructor(){if(!self.UI.inspectorView.hasPanel('network')){return;}
const manager=NetworkManager.MultitargetNetworkManager.instance();manager.addEventListener(NetworkManager.MultitargetNetworkManager.Events.ConditionsChanged,updateVisibility);manager.addEventListener(NetworkManager.MultitargetNetworkManager.Events.BlockedPatternsChanged,updateVisibility);manager.addEventListener(NetworkManager.MultitargetNetworkManager.Events.InterceptorsChanged,updateVisibility);updateVisibility();function updateVisibility(){let icon=null;if(manager.isThrottling()){icon=Icon.Icon.create('smallicon-warning');icon.title=UIString.UIString('Network throttling is enabled');}else if(NetworkManager.MultitargetNetworkManager.instance().isIntercepting()){icon=Icon.Icon.create('smallicon-warning');icon.title=UIString.UIString('Requests may be rewritten by local overrides');}else if(manager.isBlocking()){icon=Icon.Icon.create('smallicon-warning');icon.title=UIString.UIString('Requests may be blocked');}
self.UI.inspectorView.setPanelIcon('network',icon);}}}
var NetworkPanelIndicator$1=Object.freeze({__proto__:null,NetworkPanelIndicator:NetworkPanelIndicator});class ThrottlingSettingsTab extends Widget.VBox{constructor(){super(true);this.registerRequiredCSS('mobile_throttling/throttlingSettingsTab.css');const header=this.contentElement.createChild('div','header');header.textContent=ls`Network Throttling Profiles`;ARIAUtils.markAsHeading(header,1);const addButton=UIUtils.createTextButton(UIString.UIString('Add custom profile...'),this._addButtonClicked.bind(this),'add-conditions-button');this.contentElement.appendChild(addButton);this._list=new ListWidget.ListWidget(this);this._list.element.classList.add('conditions-list');this._list.registerRequiredCSS('mobile_throttling/throttlingSettingsTab.css');this._list.show(this.contentElement);this._customSetting=Settings.Settings.instance().moduleSetting('customNetworkConditions');this._customSetting.addChangeListener(this._conditionsUpdated,this);this.setDefaultFocusedElement(addButton);}
wasShown(){super.wasShown();this._conditionsUpdated();}
_conditionsUpdated(){this._list.clear();const conditions=this._customSetting.get();for(let i=0;i<conditions.length;++i){this._list.appendItem(conditions[i],true);}
this._list.appendSeparator();}
_addButtonClicked(){this._list.addNewItem(this._customSetting.get().length,{title:'',download:-1,upload:-1,latency:0});}
renderItem(item,editable){const conditions=(item);const element=document.createElement('div');element.classList.add('conditions-list-item');const title=element.createChild('div','conditions-list-text conditions-list-title');const titleText=title.createChild('div','conditions-list-title-text');titleText.textContent=conditions.title;titleText.title=conditions.title;element.createChild('div','conditions-list-separator');element.createChild('div','conditions-list-text').textContent=throughputText(conditions.download);element.createChild('div','conditions-list-separator');element.createChild('div','conditions-list-text').textContent=throughputText(conditions.upload);element.createChild('div','conditions-list-separator');element.createChild('div','conditions-list-text').textContent=UIString.UIString('%dms',conditions.latency);return element;}
removeItemRequested(item,index){const list=this._customSetting.get();list.splice(index,1);this._customSetting.set(list);}
commitEdit(item,editor,isNew){const conditions=(item);conditions.title=editor.control('title').value.trim();const download=editor.control('download').value.trim();conditions.download=download?parseInt(download,10)*(1024/8):-1;const upload=editor.control('upload').value.trim();conditions.upload=upload?parseInt(upload,10)*(1024/8):-1;const latency=editor.control('latency').value.trim();conditions.latency=latency?parseInt(latency,10):0;const list=this._customSetting.get();if(isNew){list.push(conditions);}
this._customSetting.set(list);}
beginEdit(item){const conditions=(item);const editor=this._createEditor();editor.control('title').value=conditions.title;editor.control('download').value=conditions.download<=0?'':String(conditions.download/(1024/8));editor.control('upload').value=conditions.upload<=0?'':String(conditions.upload/(1024/8));editor.control('latency').value=conditions.latency?String(conditions.latency):'';return editor;}
_createEditor(){if(this._editor){return this._editor;}
const editor=new ListWidget.Editor();this._editor=editor;const content=editor.contentElement();const titles=content.createChild('div','conditions-edit-row');const nameLabel=titles.createChild('div','conditions-list-text conditions-list-title');const nameStr=ls`Profile Name`;nameLabel.textContent=nameStr;titles.createChild('div','conditions-list-separator conditions-list-separator-invisible');const downloadLabel=titles.createChild('div','conditions-list-text');const downloadStr=ls`Download`;downloadLabel.textContent=downloadStr;titles.createChild('div','conditions-list-separator conditions-list-separator-invisible');const uploadLabel=titles.createChild('div','conditions-list-text');const uploadStr=ls`Upload`;uploadLabel.textContent=uploadStr;titles.createChild('div','conditions-list-separator conditions-list-separator-invisible');const latencyLabel=titles.createChild('div','conditions-list-text');const latencyStr=ls`Latency`;latencyLabel.textContent=latencyStr;const fields=content.createChild('div','conditions-edit-row');const nameInput=editor.createInput('title','text','',titleValidator);ARIAUtils.setAccessibleName(nameInput,nameStr);fields.createChild('div','conditions-list-text conditions-list-title').appendChild(nameInput);fields.createChild('div','conditions-list-separator conditions-list-separator-invisible');let cell=fields.createChild('div','conditions-list-text');const downloadInput=editor.createInput('download','text',ls`kb/s`,throughputValidator);cell.appendChild(downloadInput);ARIAUtils.setAccessibleName(downloadInput,downloadStr);const downloadOptional=cell.createChild('div','conditions-edit-optional');const optionalStr=ls`optional`;downloadOptional.textContent=optionalStr;ARIAUtils.setDescription(downloadInput,optionalStr);fields.createChild('div','conditions-list-separator conditions-list-separator-invisible');cell=fields.createChild('div','conditions-list-text');const uploadInput=editor.createInput('upload','text',ls`kb/s`,throughputValidator);ARIAUtils.setAccessibleName(uploadInput,uploadStr);cell.appendChild(uploadInput);const uploadOptional=cell.createChild('div','conditions-edit-optional');uploadOptional.textContent=optionalStr;ARIAUtils.setDescription(uploadInput,optionalStr);fields.createChild('div','conditions-list-separator conditions-list-separator-invisible');cell=fields.createChild('div','conditions-list-text');const latencyInput=editor.createInput('latency','text',ls`ms`,latencyValidator);ARIAUtils.setAccessibleName(latencyInput,latencyStr);cell.appendChild(latencyInput);const latencyOptional=cell.createChild('div','conditions-edit-optional');latencyOptional.textContent=optionalStr;ARIAUtils.setDescription(latencyInput,optionalStr);return editor;function titleValidator(item,index,input){const maxLength=49;const value=input.value.trim();const valid=value.length>0&&value.length<=maxLength;if(!valid){const errorMessage=ls`Profile Name characters length must be between 1 to ${maxLength} inclusive`;return{valid,errorMessage};}
return{valid};}
function throughputValidator(item,index,input){const minThroughput=0;const maxThroughput=10000000;const value=input.value.trim();const parsedValue=Number(value);const throughput=input.getAttribute('aria-label');const valid=!Number.isNaN(parsedValue)&&parsedValue>=minThroughput&&parsedValue<=maxThroughput;if(!valid){const errorMessage=ls`${throughput} must be a number between ${minThroughput}kb/s to ${maxThroughput}kb/s inclusive`;return{valid,errorMessage};}
return{valid};}
function latencyValidator(item,index,input){const minLatency=0;const maxLatency=1000000;const value=input.value.trim();const parsedValue=Number(value);const valid=Number.isInteger(parsedValue)&&parsedValue>=minLatency&&parsedValue<=maxLatency;if(!valid){const errorMessage=ls`Latency must be an integer between ${minLatency}ms to ${maxLatency}ms inclusive`;return{valid,errorMessage};}
return{valid};}}}
function throughputText(throughput,plainText){if(throughput<0){return'';}
const throughputInKbps=throughput/(1024/8);const delimiter=plainText?'':' ';if(throughputInKbps<1024){return UIString.UIString('%d%skb/s',throughputInKbps,delimiter);}
if(throughputInKbps<1024*10){return UIString.UIString('%.1f%sMb/s',throughputInKbps/1024,delimiter);}
return UIString.UIString('%d%sMb/s',(throughputInKbps/1024)|0,delimiter);}
var ThrottlingSettingsTab$1=Object.freeze({__proto__:null,ThrottlingSettingsTab:ThrottlingSettingsTab,throughputText:throughputText});export{MobileThrottlingSelector$1 as MobileThrottlingSelector,NetworkPanelIndicator$1 as NetworkPanelIndicator,NetworkThrottlingSelector$1 as NetworkThrottlingSelector,ThrottlingManager$1 as ThrottlingManager,ThrottlingPresets,ThrottlingSettingsTab$1 as ThrottlingSettingsTab};