
<!DOCTYPE html>
<html>
<head><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
	<script>

		function setTaggedSessionInfo(tag, taggedSessionInfo) {
			var oldTaggedSessionInfo = window._taggedSessionInfos[tag];
			window._taggedSessionInfos[tag] = taggedSessionInfo;

			if (!oldTaggedSessionInfo || taggedSessionInfo.SessionID != oldTaggedSessionInfo.SessionID || taggedSessionInfo.Code != oldTaggedSessionInfo.Code)
				SC.livedata.notifyDirty();
		}

		// backwards compatibility with extensions
		function setTaggedSessionID(tag, sessionID) {
			window.setTaggedSessionInfo(tag, { SessionID: sessionID });
		}

		function getTaggedSessionInfo(tag) {
			return window._taggedSessionInfos[tag];
		}
		
		function getSessionInfo() {
			var liveData = SC.livedata.get();
			return liveData && liveData.ResponseInfoMap && liveData.ResponseInfoMap['GuestSessionInfo']
		}

	</script>
<script src="Script.ashx?__Cache=957f04c7-3b12-46bb-8b29-f3aeddbb7b27" id="defaultScript"></script>
<script src="Scripts/SC.polyfill.ts?ScriptImportType=NoModule&amp;__Cache=161b42ee-46f8-4716-aa56-87ec642df487" nomodule="nomodule"></script>
<script src="Scripts/SC.main.ts?ScriptImportType=NoModule&amp;__Cache=9c15416d-ffc1-4f8e-a6dd-461313e9d2b5" nomodule="nomodule"></script>
<script src="Scripts/SC.main.ts?ScriptImportType=Classic&amp;__Cache=9c15416d-ffc1-4f8e-a6dd-461313e9d2b5"></script>
<link href="App_Themes/DarkWithBlue/Default.css?__Cache=335b1531-fd2f-4d7d-b04f-87798024328d" type="text/css" rel="stylesheet" /><link href="FavIcon.axd?__Cache=ab0e342d-03bf-4fb6-8ddf-2436a7d9bf45" rel="shortcut icon" />
<script>SC.util.mergeIntoContext({"focusedControlID":null,"userName":"","userDisplayName":"","isUserAuthenticated":false,"antiForgeryToken":"UxVbPZHGTPmJR4N9F0MkuvGDzyMqmZx19b2lW2G3eOEBAAA/xXeqe8MtQg==","isUserAdministrator":false,"canDisplayPAMDashboard":false,"canManageSharedToolbox":false,"pageBaseFileName":"Guest","notifyActivityFrequencyMilliseconds":600000,"loginAfterInactivityMilliseconds":0,"canChangePassword":false,"controlPanelUrl":null,"pageType":"GuestPage","processType":2,"userAgentOverride":null,"sessionTypeInfos":[],"imports":{"SC.editor":"Scripts/SC.editor.ts?ScriptImportType=EsModule\u0026__Cache=85d087cb-de31-440b-a7b3-b93b1557e69c"}});</script>
<script src="https://cloud.screenconnect.com/scripts/instance.js?Instance=tkndx7" async="async" defer="defer"></script>
<script>SC.extension.addInitializeProc('fa369545-ba27-4670-b053-a9f65f3269b0', function (extensionContext) {
if (SC.context.pageType == 'AdministrationPage' && SC.context.isUserAuthenticated)
	SC.service.GetThemeInfo(function (themeInfo) {
		SC.util.includeStyleSheet(extensionContext.baseUrl + 'css/Style.css');
	});

SC.event.addGlobalHandler(SC.event.ExecuteCommand, function (eventArgs) {
	switch (eventArgs.commandName) {
		case 'WebConfigSave':
			SC.dialog.showModalButtonDialog(
				'Prompt',
				SC.res['AdvancedConfig.ApplyChanges'],
				'OK',
				'Default',
				function (container) {
					SC.ui.setContents(container, [
						eventArgs.commandArgument === 'WebConfigRestore' ? $p(SC.res['AdvancedConfig.RestoreDefaults.WebConfigWarning']) : $p(SC.res['AdvancedConfig.RestartInstanceWarning'])
					]);
				},
				function () {
					var appSettings = JSON.parse(sessionStorage.getItem('WebConfigAppSettings'));
					var pageSettings = JSON.parse(JSON.stringify(appSettings.location));
					delete appSettings.location;

					SC.service.WriteChangesToWebConfig(appSettings, pageSettings, function (result) {
						if (result === 'OK') {
							sessionStorage.removeItem('WebConfigAppSettings');
							SC.dialog.showModalActivityAndReload('Save', true, window.location.href.split('#')[0]);
						} else {
							SC.dialog.showModalMessageBox(SC.res['AdvancedConfig.SaveError.Title'], SC.res['AdvancedConfig.SaveError.WebConfigDescription'] + ' ' + result);
						}
					});
				}
			);
			break;
		case 'AppConfigSave':
			SC.dialog.showModalButtonDialog(
				'Prompt',
				SC.res['AdvancedConfig.ApplyChanges'],
				'OK',
				'Default',
				function (container) {
					SC.ui.setContents(container, [
						eventArgs.commandArgument === 'AppConfigRestore' ? $p(SC.res['AdvancedConfig.RestoreDefaults.AppConfigWarning']) : $p(SC.res['AdvancedConfig.ReinstallWarning'])
					]);
				},
				function () {
					var applicationSettings = JSON.parse(sessionStorage.getItem('AppConfigAppSettings'));
					
					SC.service.WriteChangesToAppConfigNew(applicationSettings, AppConfigDefaults, function (result) {
						if (result === 'OK') {
							sessionStorage.removeItem('AppConfigAppSettings');
							window.location.reload();
						} else {
							SC.dialog.showModalMessageBox(SC.res['AdvancedConfig.SaveError.Title'], SC.res['AdvancedConfig.SaveError.AppConfigDescription'] + ' ' + result);
						}
					});
				}
			);
			break;
	}
});


});</script>
<script>SC.extension.addInitializeProc('fc234f0e-2e8e-4a1f-b977-ba41b14031f7', function (extensionContext) {
// Add: Options | Help
var x=extensionContext.baseUrl.split('/').splice(-2)[0];
SC.event.addGlobalHandler(SC.event.QueryCommandButtonState,function(e){if(e.commandName=='EditExtensionSettings'){if(e.commandContext.extensionInfo.ExtensionID==x&&e.commandElement._commandName=='EditExtensionSettings')SC.ui.addElement(e.target.parentElement,'A',{href:'#',_commandName:'ShowHelpLink_'+x,innerHTML:'Help'});}});
SC.event.addGlobalHandler(SC.event.ExecuteCommand,function(e){if(e.commandName=='ShowHelpLink_'+x){window.open('https://docs.connectwise.com/ConnectWise_Automate/ConnectWise_Automate_Documentation/080/020/020?psa=1', '_blank');}});
});</script>
<script>SC.extension.addInitializeProc('fc234f0e-2e8e-4a1f-b977-ba41b14031f7', function (extensionContext) {
/*
    The following is currently ripped from the Hosted Integration Template per ScreenConnect
    Potential to one day not need this and use some core functionality

    File will hide the UI and display the fourth column only
*/
var sendCommandToParent = function (commandName, commandData) {
    if (commandName) {
        window.parent.postMessage({ _internalCommand: commandName, _internalCommandData: commandData ? commandData : {} }, '*');
    }
};

SC.event.addGlobalHandler(SC.event.PreRender, function () {
    window.addEventListener('message', async function (eventArgs) {
        SC.util.includeStyleSheet(extensionContext.baseUrl + 'LiveData/livedata.css');
        
        switch (eventArgs.data._externalCommand) {
            case 'RenderSessionDetailsFullWidthCommand':
                var applicablePaths = ['/', '/Guest', '/Host', '/Login'];
                
                if (!applicablePaths.includes(window.location.pathname)) {
                    break;
                }

                var elementsToHide = [
                    $('.HeaderPanel'),
                    $('.GlobalBar'),
                    $('.NavigationPanel'),
                    $('.MasterPanel'),
                    $('.MainDetailHeaderPanel'),
                    $('.MainDetailPanel'),
                    $('.ToggleDetailPanelButton'),
                ];

                for (var i = 0; i < elementsToHide.length; i++) {
                    if (elementsToHide[i]) {
                        SC.css.ensureClass(elementsToHide[i], 'HiddenElement', true);
                    }
                }

                var outerPanel = $('.OuterPanel');
                var mainPanel = $('.MainPanel');
                var subDetailHeader = $('.SubDetailHeaderPanel');

                if (outerPanel) {
                    SC.css.ensureClass(outerPanel, 'OuterPanelOverride', true);
                }

                if (mainPanel) {
                    SC.css.ensureClass(mainPanel, 'GridOverride', true);
                }

                if (subDetailHeader) {
                    SC.css.ensureClass(subDetailHeader, 'FullSizeHeaderElement', true);
                }

                var notifyPaths = ['/', '/Guest'];

                if (notifyPaths.includes(window.location.pathname)) {
                    sendCommandToParent('OnPreRenderComplete');
                }

                break;

            case 'LoadSessionCommand':
                var sessionID = eventArgs.data._externalCommandData;

                if (sessionID) {
                    // Call our LiveDataService
                    await SC.service.GetSessionDetailsUrl(
                        sessionID,
                        function (url) {
                            if (url) {
                                window.location.href = url;
                            }
                        }
                    );
                }

                sendCommandToParent('OnLoadSessionComplete');
                break;
        }
    });

    sendCommandToParent('OnPreRender');
});
});</script>
<script>SC.extension.addInitializeProc('93cceb0c-f5cd-4d7b-abee-e6718bc624c3', function (extensionContext) {
SC.event.addGlobalHandler(SC.event.QueryCommandButtons, function (eventArgs) {
	switch (eventArgs.area) {
		case 'ExtrasPopoutPanel':
			if (SC.context.pageType == 'AdministrationPage') {
				eventArgs.buttonDefinitions.push(
					{ commandName: 'OpenManageConfigurationModal', text: SC.res['ConnectWiseManage.EditSettings.OpenModal'] }
				);
			}
			break;
	}
});

SC.event.addGlobalHandler(SC.event.ExecuteCommand, function (eventArgs) {
	switch (eventArgs.commandName) {
		case 'OpenManageConfigurationModal':
			SC.service.GetConnectWiseApiSettings(function (cwApiSettings) {
				openManageConfigurationModal(cwApiSettings);
			});
			break;
	}
});

function populatePSASettingTabContent(cwApiSettings, possibleBoardsAndCompanies, serviceBoardRelevantProperties) {
    var duplicateCompanyNames = Object.entries(Object.groupBy(possibleBoardsAndCompanies["Companies"], ({ Name }) => Name.toLowerCase())).filter(function (group) {
                                        return group[1].length > 1;
                                    }).map(function (group) {
                                        return group[1][0].Name;
                                    });
    
    return $table({className: 'DataTable'}, [
        $thead(
            $tr([
                $th(SC.res['ExtensionsPanel.EditSettings.KeyHeaderText']),
                $th(SC.res['ExtensionsPanel.EditSettings.DescriptionHeaderText']),
                $th(SC.res['ExtensionsPanel.EditSettings.ValueHeaderText']),
            ]),
        ),
        $tbody({className: 'DataTableBody'},
            ['Chat', 'Events', 'Notes'].map(it =>
                $tr([
                    $td(SC.res['ConnectWiseManage.EditExtensionSettings.CwSession' + it + 'PostType.LabelText']),
                    $td(SC.res['ConnectWiseManage.EditExtensionSettings.CwSession' + it + 'PostType.Text']),
                    $td([
                        $input({
                            id: 'cwSession' + it + 'AsNote',
                            type: 'checkbox',
                            checked: Number(cwApiSettings['CwSession' + it + 'PostType']) & 1
                        }), $label('Note', {for: 'cwSession' + it + 'AsNote', className: 'PSAModalCheckboxLabel'}),
                        $input({
                            id: 'cwSession' + it + 'AsAttachment',
                            type: 'checkbox',
                            checked: Number(cwApiSettings['CwSession' + it + 'PostType']) & 2
                        }), $label('Attachment', {
                            for: 'cwSession' + it + 'AsAttachment',
                            className: 'PSAModalCheckboxLabel'
                        }),
                    ]),
                ])
            ),
            $tr([
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.CombineAttachments.LabelText']),
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.CombineAttachments.Text']),
                $td($input({
                    id: 'cwCombineAttachments',
                    type: 'checkbox',
                    checked: cwApiSettings['CwCombineAttachments'].trim().toLowerCase() === 'true'
                })),
            ]),
            $tr([
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.IncludePreviewLink.LabelText']),
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.IncludePreviewLink.Text']),
                $td($input({
                    id: 'cwIncludeSessionDetailsLink',
                    type: 'checkbox',
                    checked: cwApiSettings['CwIncludeSessionDetailsLink'].trim().toLowerCase() === 'true'
                })),
            ]),
            $tr([
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.ShouldSendCamEvents.LabelText']),
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.ShouldSendCamEvents.Text']),
                $td($input({
                    id: 'cwShouldSendCamEventsBox',
                    type: 'checkbox',
                    checked: cwApiSettings['CwShouldCreateTicketForCAMEvents'].trim().toLowerCase() === 'true'
                })),
            ]),
			$tr([
				$td([
                    SC.res['ConnectWiseManage.EditExtensionSettings.MapCompanyNameToCustomProperty.LabelText'],
                ]),
				$td([
					SC.res['ConnectWiseManage.EditExtensionSettings.MapCompanyNameToCustomProperty.Text'],
					$br(),
					$br(),
					duplicateCompanyNames.length > 0 ?
						$p({className: 'Warning'}, SC.util.formatString(SC.res['ConnectWiseManage.EditExtensionSettings.MapCompanyNameToCustomPropertyDuplicateWarning.TextFormat'], duplicateCompanyNames.toString()))
						: SC.res['ConnectWiseManage.EditExtensionSettings.MapCompanyNameToCustomPropertyDuplicateInfo.Text']
				]),
				$td([
						$select({id: 'cwMapCompanyNameToCustomProperty'},
							[
								cwApiSettings["CwMapCompanyNameToCustomProperty"]
									? $option({value: cwApiSettings["CwMapCompanyNameToCustomProperty"], text: getCustomPropertyNameFromNumber(cwApiSettings["CwMapCompanyNameToCustomProperty"])})
									: $option({value: null, text: ""}),
								Array.from({length: 8}, (_, i) => {
									if (i + 1 !== Number(cwApiSettings["CwMapCompanyNameToCustomProperty"]))
										return $option({
											value: i + 1,
											text: getCustomPropertyNameFromNumber(i + 1)
										})
								})
							]
						),
                    ]
				),
			]),
            $tr([
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.ServiceBoard.LabelText']),
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.ServiceBoard.Text']),
                $td([
                    $select({
                        id: 'cwSelectServiceBoard', _eventHandlerMap: {
                            'change': function (eventArgs) {
								SC.css.ensureClass($('cwCamEventTicketDefaultStatusBox'), 'Loading', true);
								SC.css.ensureClass($('cwCamEventTicketDefaultTypeBox'), 'Loading', true);
                                SC.service.GetPossibleServiceBoardRelevantProperties($('cwSelectServiceBoard').value, function (response) {
                                    SC.ui.clear($('cwCamEventTicketDefaultStatusBox'));
                                    SC.ui.clear($('cwCamEventTicketDefaultTypeBox'));

                                    if (response["Statuses"] != null)
                                        response["Statuses"].map(function (_) {
                                            SC.ui.addContent($('cwCamEventTicketDefaultStatusBox'), $option({
                                                value: _.Id,
                                                text: _.Name
                                            }))
                                        });

                                    if (response["Types"] != null)
                                        response["Types"].map(function (_) {
                                            SC.ui.addContent($('cwCamEventTicketDefaultTypeBox'), $option({
                                                value: _.Id,
                                                text: _.Name
                                            }))
                                        });
									SC.css.ensureClass($('cwCamEventTicketDefaultStatusBox'), 'Loading', false);
									SC.css.ensureClass($('cwCamEventTicketDefaultTypeBox'), 'Loading', false);
                                });
                            }
                        }
                    },
						[
							$option({value: cwApiSettings["CwCamEventServiceBoardID"], text: getNameByIdOrReturnDefaultText(possibleBoardsAndCompanies["ServiceBoards"], cwApiSettings["CwCamEventServiceBoardID"], SC.res['ConnectWiseManage.EditExtensionSettings.ServiceBoard.SelectText'])}),
							createOptionsFromListExcludingGivenID(possibleBoardsAndCompanies["ServiceBoards"], cwApiSettings["CwCamEventServiceBoardID"])
						]
					),
                ])
            ]),
            $tr([
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.TicketStatus.LabelText']),
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.TicketStatus.Text']),
                $td([
					serviceBoardRelevantProperties != null && serviceBoardRelevantProperties["Statuses"] != null
						? $select({id: 'cwCamEventTicketDefaultStatusBox'}, 
							[
								cwApiSettings["CwCamEventTicketDefaultStatusID"] ? $option({value: cwApiSettings["CwCamEventTicketDefaultStatusID"], text: getNameByIdOrReturnDefaultText(serviceBoardRelevantProperties["Statuses"], cwApiSettings["CwCamEventTicketDefaultStatusID"], "")}) : null,
								createOptionsFromListExcludingGivenID(serviceBoardRelevantProperties["Statuses"], cwApiSettings["CwCamEventTicketDefaultStatusID"])
							])
						: $select({id: 'cwCamEventTicketDefaultStatusBox'}),
                ]),
            ]),
            $tr([
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.TicketType.LabelText']),
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.TicketType.Text']),
                $td([
					serviceBoardRelevantProperties != null && serviceBoardRelevantProperties["Types"] != null
						? $select({id: 'cwCamEventTicketDefaultTypeBox'},
							[
								cwApiSettings["CwCamEventTicketDefaultType"] ? $option({value: cwApiSettings["CwCamEventTicketDefaultType"], text: getNameByIdOrReturnDefaultText(serviceBoardRelevantProperties["Types"], cwApiSettings["CwCamEventTicketDefaultType"], "")}): null,
								createOptionsFromListExcludingGivenID(serviceBoardRelevantProperties["Types"], cwApiSettings["CwCamEventTicketDefaultType"]),
							])
						: $select({id: 'cwCamEventTicketDefaultTypeBox'}),
                ]),
            ]),
            $tr([
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.TicketCompany.LabelText']),
                $td(SC.res['ConnectWiseManage.EditExtensionSettings.TicketCompany.Text']),
                $td([
					$select({id: 'cwSelectCompany'},
						[
							$option({value: cwApiSettings["CwCamEventTicketDefaultCompanyID"], text: getNameByIdOrReturnDefaultText(possibleBoardsAndCompanies["Companies"], cwApiSettings["CwCamEventTicketDefaultCompanyID"], SC.res['ConnectWiseManage.EditExtensionSettings.TicketCompany.SelectText'])}),
							createOptionsFromListExcludingGivenID(possibleBoardsAndCompanies["Companies"], cwApiSettings["CwCamEventTicketDefaultCompanyID"])
						]
					)
				]),
            ]),
	)
    ]);
}

function getCustomPropertyNameFromNumber(number) {
	var customPropertyLabel = SC.res[`SessionProperty.Custom${number}.LabelText`];
	if (customPropertyLabel) {
		return customPropertyLabel.replace(":", "");
	} else {
		return "Custom Property " + number;
	}
}
function getNameByIdOrReturnDefaultText(list, id, defaultText) {
	const item = list.find(item => item.Id === id);
	return item ? item.Name : defaultText;
}

function createOptionsFromListExcludingGivenID(list, excludedID) {
	return list.filter(item => item.Id !== excludedID).map(function (_) {
		return $option({value: _.Id, text: _.Name});
	})
}


function openManageConfigurationModal(cwApiSettings) {
	var psaSettingTabContainer = $div({className: 'PSASettingsContainer'}, [
		$p("To view settings please enter the credentials first, then press the 'Test Connect' button.")
	]);

	var resultPanel = $div({className: 'ResultPanel'});

	var credentialsPanel = $div({className: "PSACredentialsContainer"}, [
		$dl([
			$dt([
				SC.res['ConnectWiseManage.EditExtensionSettings.ManageUrl.LabelText'],
				SC.ui.createInfoIcon(SC.res['ConnectWiseManage.EditExtensionSettings.ManageUrl.Text']),
			]),
			$dd(SC.ui.createTextBox({
				id: 'cwUrlBox',
				value: cwApiSettings['CwUrl'],
				placeholder: SC.res['ConnectWiseManage.EditExtensionSettings.ManageUrl.PlaceholderText']
			}, false)),
			$dt([
				SC.res['ConnectWiseManage.EditExtensionSettings.ControlUrl.LabelText'],
				SC.ui.createInfoIcon(SC.res['ConnectWiseManage.EditExtensionSettings.ControlUrl.Text']),
			]),
			$dd(SC.ui.createTextBox({id: 'scUrlBox', value: cwApiSettings['ScServerUrl']}, false)),
			$dt([
				SC.res['ConnectWiseManage.EditExtensionSettings.Company.LabelText'],
				SC.ui.createInfoIcon(SC.res['ConnectWiseManage.EditExtensionSettings.CwCompany.Text']),
			]),
			$dd(SC.ui.createTextBox({
				id: 'cwCompanyNameBox',
				value: cwApiSettings['CwCompanyName'],
				placeholder: SC.res['ConnectWiseManage.EditExtensionSettings.Company.PlaceholderText']
			}, false)),
			$dt([
				SC.res['ConnectWiseManage.EditExtensionSettings.ManageApi.PublicKey.LabelText'],
				SC.ui.createInfoIcon(SC.res['ConnectWiseManage.EditExtensionSettings.CwPublicKey.Text']),
			]),
			$dd(SC.ui.createTextBox({id: 'cwPublicApiKeyBox', value: cwApiSettings['CwApiPublicKey']}, false)),
			$dt([
				SC.res['ConnectWiseManage.EditExtensionSettings.ManageApi.PrivateKey.LabelText'],
				SC.ui.createInfoIcon(SC.res['ConnectWiseManage.EditExtensionSettings.CwPrivateKey.Text']),
			]),
			$dd(SC.ui.createTextBox({
				id: 'cwPrivateApiKeyBox',
				placeholder: cwApiSettings['CwApiPrivateKey'],
				autocomplete: "off"
			}, false)),
			$dt([
				SC.res['ConnectWiseManage.EditExtensionSettings.CwTimeEntryFlag.LabelText'],
				SC.ui.createInfoIcon(SC.res['ConnectWiseManage.EditExtensionSettings.CwTimeEntryFlag.Text']),
			]),
			$dd(
				$input({
					id: 'cwTimeEntryFlag',
					type: 'checkbox',
					checked: cwApiSettings['CwTimeEntryFlag'] === '1'
				}),
			),
		]),
		$div(
			$input({
				type: 'button',
				className: 'PSATestConnectionButton Loading',
				_commandName: 'SaveCredentialsAndTestPSAConnection',
				value: "Test Connection"
			})
		),
		resultPanel
	]);
	
	SC.dialog.showModalDialog('EditExtensionSettings',
		{
			titleResourceName: 'ConnectWiseManage.EditExtensionSettings.Title',
			content: [
				SC.ui.createTabs('PSATab',
					[{
						name: 'PSACredentialTab',
						link: $div({className: 'Header'}, $span("Credentials")),
						content: credentialsPanel,
					}, 
						{
							name: 'PSASettingsTab',
							link: $div({className: 'Header'}, $span("Settings")),
							content: psaSettingTabContainer,
						}]),
			],
			buttonTextResourceName: 'ConnectWiseManage.SaveButtonText',
			onExecuteCommandProc: function (dialogEventArgs, dialog, closeDialogProc, errorProc) {
				switch (dialogEventArgs.commandName) {
					case "SaveCredentialsAndTestPSAConnection":
						SC.css.ensureClass(dialogEventArgs.clickedElement, 'Loading', true);
						updateCredentialSettingValuesFromTextBoxes(cwApiSettings);
						SC.service.SaveConnectWiseApiSettings(
							cwApiSettings,
                            false,
							function () {
								SC.service.GetPossibleServiceBoardsAndCompanyNames(function (serviceBoardsAndCompanies) {
									if (serviceBoardsAndCompanies) {
										SC.service.GetPossibleServiceBoardRelevantProperties(cwApiSettings["CwCamEventServiceBoardID"] ? cwApiSettings["CwCamEventServiceBoardID"] : null, function (serviceBoardRelevantProperties) {
											SC.ui.setContents(psaSettingTabContainer, populatePSASettingTabContent(cwApiSettings, serviceBoardsAndCompanies, serviceBoardRelevantProperties));
											displayPSAConnectionStatus(true, resultPanel);
											SC.ui.setDisabled($('.TabLinks').children.item(1), false)
											SC.css.ensureClass(dialogEventArgs.clickedElement, 'Loading', false);
										});
									} else {
										displayPSAConnectionStatus(false, resultPanel, "Unable to connect to PSA");
										SC.css.ensureClass(dialogEventArgs.clickedElement, 'Loading', false);
									}
								});
							},
							function (error) {
								displayPSAConnectionStatus(false, resultPanel, error.message);
								SC.css.ensureClass(dialogEventArgs.clickedElement, 'Loading', false);
							},
						);

						break;
					case "SelectTab" :
						break;
					default:
						updateCredentialSettingValuesFromTextBoxes(cwApiSettings);
						if ($('cwSessionChatAsNote') != null) {
							cwApiSettings['CwSessionChatPostType'] = ($('cwSessionChatAsNote').checked ? 1 : 0) | ($('cwSessionChatAsAttachment').checked ? 2 : 0);
							cwApiSettings['CwSessionEventsPostType'] = ($('cwSessionEventsAsNote').checked ? 1 : 0) | ($('cwSessionEventsAsAttachment').checked ? 2 : 0);
							cwApiSettings['CwSessionNotesPostType'] = ($('cwSessionNotesAsNote').checked ? 1 : 0) | ($('cwSessionNotesAsAttachment').checked ? 2 : 0);
							cwApiSettings['CwCombineAttachments'] = $('cwCombineAttachments').checked ? 'true' : 'false';
							cwApiSettings['CwIncludeSessionDetailsLink'] = $('cwIncludeSessionDetailsLink').checked ? 'true' : 'false';
							cwApiSettings['CwShouldCreateTicketForCAMEvents'] = $('cwShouldSendCamEventsBox').checked ? 'true' : 'false';
							cwApiSettings['CwMapCompanyNameToCustomProperty'] = $('cwMapCompanyNameToCustomProperty').value ? $('cwMapCompanyNameToCustomProperty').value : null;
							cwApiSettings['CwCamEventTicketDefaultType'] = $('cwCamEventTicketDefaultTypeBox').value;
							cwApiSettings['CwCamEventServiceBoardID'] = $('cwSelectServiceBoard').value != SC.res['ConnectWiseManage.EditExtensionSettings.ServiceBoard.SelectText'] ? $('cwSelectServiceBoard').value : null;
							cwApiSettings['CwCamEventTicketDefaultStatusID'] = $('cwCamEventTicketDefaultStatusBox').value;
							cwApiSettings['CwCamEventTicketDefaultCompanyID'] = $('cwSelectCompany').value != SC.res['ConnectWiseManage.EditExtensionSettings.TicketCompany.SelectText'] ? $('cwSelectCompany').value : null;
						}
                        
                        SC.service.SaveConnectWiseApiSettings(
                            cwApiSettings,
                            true,
                            function () {
                                SC.service.CreatePodIfNonExistent()
                                closeDialogProc();
                                SC.pagedata.notifyDirty();
                            },
                            errorProc
                        );
                        break;
				}
			},
		}
	);

	SC.ui.setDisabled($('.TabLinks').children.item(1), true)
	
    SC.service.GetPossibleServiceBoardsAndCompanyNames(function (possibleBoardsAndCompanies) {
		SC.service.GetPossibleServiceBoardRelevantProperties(cwApiSettings["CwCamEventServiceBoardID"] ? cwApiSettings["CwCamEventServiceBoardID"] : null, function (serviceBoardRelevantProperties) {
			if (cwApiSettings.hasOwnProperty("IsSetup") && !SC.util.isNullOrEmpty(cwApiSettings["IsSetup"])) {
				if (possibleBoardsAndCompanies != null) {
					SC.ui.setContents(psaSettingTabContainer, populatePSASettingTabContent(cwApiSettings, possibleBoardsAndCompanies, serviceBoardRelevantProperties));
					displayPSAConnectionStatus(true, resultPanel);
					SC.ui.setSelected($('.TabLinks').children.item(1), true);
					SC.ui.setSelected($('.TabContents').children.item(1), true);
					SC.ui.setSelected($('.TabLinks').firstChild, false);
					SC.ui.setSelected($('.TabContents').firstChild, false);
					SC.ui.setDisabled($('.TabLinks').children.item(1), false)
				} else {
					displayPSAConnectionStatus(false, resultPanel);
				}
			}
			
			SC.css.ensureClass($('.PSATestConnectionButton'), 'Loading', false);
		});
    });
}

var displayPSAConnectionStatus = function (connectionSuccess, saveButtonPanel, errorMessage) {
	if (connectionSuccess) {
		SC.ui.setContents(saveButtonPanel, $p({_textResource: 'ConnectWiseManage.SaveSettingsSuccessText'}));
		SC.css.ensureClass(saveButtonPanel, 'Success', true);
		SC.css.ensureClass(saveButtonPanel, 'Failure', false);
	} else {
		if (errorMessage === undefined) {
			SC.ui.setContents(saveButtonPanel, $p({_textResource: 'ConnectWiseManage.SaveSettingsWarningText'}));
		} else {
			SC.ui.setContents(saveButtonPanel, $p(errorMessage));
		}
		SC.css.ensureClass(saveButtonPanel, 'Success', false);
		SC.css.ensureClass(saveButtonPanel, 'Failure', true);
	}
}

SC.event.addGlobalHandler(SC.event.PreRender, function (eventArgs) {
	if (!extensionContext.settingValues.IsSetup &&
		SC.context.pageType === 'AdministrationPage' &&
		SC.context.tabKeys[SC.context.tabIndex] === 'Extensions') {
		SC.service.GetConnectWiseApiSettings(function (cwApiSettings) {
			openManageConfigurationModal(cwApiSettings);
		});
	}

	if (SC.context.pageType === 'AdministrationPage' &&
		SC.context.tabKeys[SC.context.tabIndex] === 'Extensions') {
		SC.service.UpdatePodNameIfNotPrivilegedAccess(
			function () { /*don't care*/ }, function (e) { console.log(e); }
		);
	}
});

var sendCommandToParent = function (commandName, commandData) {
	if (commandName)
		window.parent.postMessage({ _internalCommand: commandName, _internalCommandData: commandData || {} }, '*');
};

var updateCredentialSettingValuesFromTextBoxes = function (cwApiSettings) {
    cwApiSettings['CwUrl'] = $('cwUrlBox').value;
    cwApiSettings['ScServerUrl'] = $('scUrlBox').value;
    cwApiSettings['CwCompanyName'] = $('cwCompanyNameBox').value;
    cwApiSettings['CwApiPublicKey'] = $('cwPublicApiKeyBox').value;
	if (!SC.util.isNullOrEmpty($('cwPrivateApiKeyBox').value)) {
		cwApiSettings['CwApiPrivateKey'] = $('cwPrivateApiKeyBox').value;
	} else {
		delete cwApiSettings.CwApiPrivateKey; // We don't want to pass back the masked value, leave it as is
	}
    cwApiSettings['CwTimeEntryFlag'] = $('cwTimeEntryFlag').checked ? 1 : 0;
}

SC.event.addGlobalHandler(SC.event.PreRender, function () {
	window.addEventListener('message', function (eventArgs) {
		SC.util.includeStyleSheet(extensionContext.baseUrl + 'ManageIntegrationStyle.css');
		switch (eventArgs.data._externalCommand) {
			case 'RenderSessionDetailsFullWidthCommand':
				var applicablePaths = ['/', '/Guest', '/Host', '/Login'];
				if (!applicablePaths.includes(window.location.pathname))
					break;

				var elementsToHide = [
					$('.HeaderPanel'),
					$('.NavigationPanel'),
					$('.MasterPanel'),
					$('.MainDetailHeaderPanel'),
					$('.MainDetailPanel'),
					$('.ToggleDetailPanelButton'),
				];

				for (var i = 0; i < elementsToHide.length; i++)
					if (elementsToHide[i])
						SC.css.ensureClass(elementsToHide[i], 'HiddenElement', true);

				var outerPanel = $('.OuterPanel');
				var mainPanel = $('.MainPanel');
				var subDetailHeader = $('.SubDetailHeaderPanel');

				if (outerPanel)
					SC.css.ensureClass(outerPanel, 'OuterPanelOverride', true);

				if (mainPanel)
					SC.css.ensureClass(mainPanel, 'GridOverride', true);

				if (subDetailHeader)
					SC.css.ensureClass(subDetailHeader, 'FullSizeHeaderElement', true);

				var notifyPaths = ['/', '/Guest'];

				if (notifyPaths.includes(window.location.pathname))
					sendCommandToParent('OnPreRenderComplete');

				break;

			case 'LoadSessionCommand':
				var sessionID = eventArgs.data._externalCommandData;

				if (sessionID) {
					SC.service.GetUrlForSession(
						sessionID,
						function (url) {
							if (url)
								window.location.href = url;
						}
					);
				}

				break;
		}
	});

	sendCommandToParent('OnPreRender');
});

});</script>
<script>SC.extension.addInitializeProc('045d6e44-8bda-4c77-8d1a-275fc5597f69', function (extensionContext) {
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js
  license: MIT
  actual source: http://cdn.jsdelivr.net/g/filesaver.js
    (with minor modifications)
*/
window.saveAs=window.saveAs||function(e){"use strict";if(typeof e==="undefined"||typeof navigator!=="undefined"&&/MSIE [1-9]\./.test(navigator.userAgent)){return}var t=e.document,n=function(){return e.URL||e.webkitURL||e},r=t.createElementNS("http://www.w3.org/1999/xhtml","a"),o="download"in r,a=function(e){var t=new MouseEvent("click");e.dispatchEvent(t)},i=/constructor/i.test(e.HTMLElement)||e.safari,f=/CriOS\/[\d]+/.test(navigator.userAgent),u=function(t){(e.setImmediate||e.setTimeout)(function(){throw t},0)},s="application/octet-stream",d=1e3*40,c=function(e){var t=function(){if(typeof e==="string"){n().revokeObjectURL(e)}else{e.remove()}};setTimeout(t,d)},l=function(e,t,n){t=[].concat(t);var r=t.length;while(r--){var o=e["on"+t[r]];if(typeof o==="function"){try{o.call(e,n||e)}catch(a){u(a)}}}},p=function(e){if(/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)){return new Blob([String.fromCharCode(65279),e],{type:e.type})}return e},v=function(t,u,d){if(!d){t=p(t)}var v=this,w=t.type,m=w===s,y,h=function(){l(v,"writestart progress write writeend".split(" "))},S=function(){if((f||m&&i)&&e.FileReader){var r=new FileReader;r.onloadend=function(){var t=f?r.result:r.result.replace(/^data:[^;]*;/,"data:attachment/file;");var n=e.open(t,"_blank");if(!n)e.location.href=t;t=undefined;v.readyState=v.DONE;h()};r.readAsDataURL(t);v.readyState=v.INIT;return}if(!y){y=n().createObjectURL(t)}if(m){e.location.href=y}else{var o=e.open(y,"_blank");if(!o){e.location.href=y}}v.readyState=v.DONE;h();c(y)};v.readyState=v.INIT;if(o){y=n().createObjectURL(t);setTimeout(function(){r.href=y;r.download=u;a(r);h();c(y);v.readyState=v.DONE});return}S()},w=v.prototype,m=function(e,t,n){return new v(e,t||e.name||"download",n)};if(typeof navigator!=="undefined"&&navigator.msSaveOrOpenBlob){return function(e,t,n){t=t||e.name||"download";if(!n){e=p(e)}return navigator.msSaveOrOpenBlob(e,t)}}w.abort=function(){};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return m}(typeof self!=="undefined"&&self||typeof window!=="undefined"&&window||this.content);if(typeof module!=="undefined"&&module.exports){module.exports.saveAs=saveAs}else if(typeof define!=="undefined"&&define!==null&&define.amd!==null){define("FileSaver.js",function(){return saveAs})}
});</script>
<script>SC.extension.addInitializeProc('045d6e44-8bda-4c77-8d1a-275fc5597f69', function (extensionContext) {
/*!

JSZip v3.1.5 - A JavaScript class for generating and reading zip files
<http://stuartk.com/jszip>

(c) 2009-2016 Stuart Knightley <stuart [at] stuartk.com>
Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/master/LICENSE.markdown.

JSZip uses the library pako released under the MIT license :
https://github.com/nodeca/pako/blob/master/LICENSE
*/
!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d=a("./utils"),e=a("./support"),f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a){for(var b,c,e,g,h,i,j,k=[],l=0,m=a.length,n=m,o="string"!==d.getTypeOf(a);l<a.length;)n=m-l,o?(b=a[l++],c=l<m?a[l++]:0,e=l<m?a[l++]:0):(b=a.charCodeAt(l++),c=l<m?a.charCodeAt(l++):0,e=l<m?a.charCodeAt(l++):0),g=b>>2,h=(3&b)<<4|c>>4,i=n>1?(15&c)<<2|e>>6:64,j=n>2?63&e:64,k.push(f.charAt(g)+f.charAt(h)+f.charAt(i)+f.charAt(j));return k.join("")},c.decode=function(a){var b,c,d,g,h,i,j,k=0,l=0,m="data:";if(a.substr(0,m.length)===m)throw new Error("Invalid base64 input, it looks like a data url.");a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");var n=3*a.length/4;if(a.charAt(a.length-1)===f.charAt(64)&&n--,a.charAt(a.length-2)===f.charAt(64)&&n--,n%1!==0)throw new Error("Invalid base64 input, bad content length.");var o;for(o=e.uint8array?new Uint8Array(0|n):new Array(0|n);k<a.length;)g=f.indexOf(a.charAt(k++)),h=f.indexOf(a.charAt(k++)),i=f.indexOf(a.charAt(k++)),j=f.indexOf(a.charAt(k++)),b=g<<2|h>>4,c=(15&h)<<4|i>>2,d=(3&i)<<6|j,o[l++]=b,64!==i&&(o[l++]=c),64!==j&&(o[l++]=d);return o}},{"./support":30,"./utils":32}],2:[function(a,b,c){"use strict";function d(a,b,c,d,e){this.compressedSize=a,this.uncompressedSize=b,this.crc32=c,this.compression=d,this.compressedContent=e}var e=a("./external"),f=a("./stream/DataWorker"),g=a("./stream/DataLengthProbe"),h=a("./stream/Crc32Probe"),g=a("./stream/DataLengthProbe");d.prototype={getContentWorker:function(){var a=new f(e.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new g("data_length")),b=this;return a.on("end",function(){if(this.streamInfo.data_length!==b.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),a},getCompressedWorker:function(){return new f(e.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},d.createWorkerFrom=function(a,b,c){return a.pipe(new h).pipe(new g("uncompressedSize")).pipe(b.compressWorker(c)).pipe(new g("compressedSize")).withStreamInfo("compression",b)},b.exports=d},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(a,b,c){"use strict";var d=a("./stream/GenericWorker");c.STORE={magic:"\0\0",compressWorker:function(a){return new d("STORE compression")},uncompressWorker:function(){return new d("STORE decompression")}},c.DEFLATE=a("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(a,b,c){"use strict";function d(){for(var a,b=[],c=0;c<256;c++){a=c;for(var d=0;d<8;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function e(a,b,c,d){var e=h,f=d+c;a^=-1;for(var g=d;g<f;g++)a=a>>>8^e[255&(a^b[g])];return a^-1}function f(a,b,c,d){var e=h,f=d+c;a^=-1;for(var g=d;g<f;g++)a=a>>>8^e[255&(a^b.charCodeAt(g))];return a^-1}var g=a("./utils"),h=d();b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var c="string"!==g.getTypeOf(a);return c?e(0|b,a,a.length,0):f(0|b,a,a.length,0)}},{"./utils":32}],5:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!0,c.date=null,c.compression=null,c.compressionOptions=null,c.comment=null,c.unixPermissions=null,c.dosPermissions=null},{}],6:[function(a,b,c){"use strict";var d=null;d="undefined"!=typeof Promise?Promise:a("lie"),b.exports={Promise:d}},{lie:58}],7:[function(a,b,c){"use strict";function d(a,b){h.call(this,"FlateWorker/"+a),this._pako=null,this._pakoAction=a,this._pakoOptions=b,this.meta={}}var e="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,f=a("pako"),g=a("./utils"),h=a("./stream/GenericWorker"),i=e?"uint8array":"array";c.magic="\b\0",g.inherits(d,h),d.prototype.processChunk=function(a){this.meta=a.meta,null===this._pako&&this._createPako(),this._pako.push(g.transformTo(i,a.data),!1)},d.prototype.flush=function(){h.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0)},d.prototype.cleanUp=function(){h.prototype.cleanUp.call(this),this._pako=null},d.prototype._createPako=function(){this._pako=new f[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var a=this;this._pako.onData=function(b){a.push({data:b,meta:a.meta})}},c.compressWorker=function(a){return new d("Deflate",a)},c.uncompressWorker=function(){return new d("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:59}],8:[function(a,b,c){"use strict";function d(a,b,c,d){f.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=b,this.zipPlatform=c,this.encodeFileName=d,this.streamFiles=a,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}var e=a("../utils"),f=a("../stream/GenericWorker"),g=a("../utf8"),h=a("../crc32"),i=a("../signature"),j=function(a,b){var c,d="";for(c=0;c<b;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},k=function(a,b){var c=a;return a||(c=b?16893:33204),(65535&c)<<16},l=function(a,b){return 63&(a||0)},m=function(a,b,c,d,f,m){var n,o,p=a.file,q=a.compression,r=m!==g.utf8encode,s=e.transformTo("string",m(p.name)),t=e.transformTo("string",g.utf8encode(p.name)),u=p.comment,v=e.transformTo("string",m(u)),w=e.transformTo("string",g.utf8encode(u)),x=t.length!==p.name.length,y=w.length!==u.length,z="",A="",B="",C=p.dir,D=p.date,E={crc32:0,compressedSize:0,uncompressedSize:0};b&&!c||(E.crc32=a.crc32,E.compressedSize=a.compressedSize,E.uncompressedSize=a.uncompressedSize);var F=0;b&&(F|=8),r||!x&&!y||(F|=2048);var G=0,H=0;C&&(G|=16),"UNIX"===f?(H=798,G|=k(p.unixPermissions,C)):(H=20,G|=l(p.dosPermissions,C)),n=D.getUTCHours(),n<<=6,n|=D.getUTCMinutes(),n<<=5,n|=D.getUTCSeconds()/2,o=D.getUTCFullYear()-1980,o<<=4,o|=D.getUTCMonth()+1,o<<=5,o|=D.getUTCDate(),x&&(A=j(1,1)+j(h(s),4)+t,z+="up"+j(A.length,2)+A),y&&(B=j(1,1)+j(h(v),4)+w,z+="uc"+j(B.length,2)+B);var I="";I+="\n\0",I+=j(F,2),I+=q.magic,I+=j(n,2),I+=j(o,2),I+=j(E.crc32,4),I+=j(E.compressedSize,4),I+=j(E.uncompressedSize,4),I+=j(s.length,2),I+=j(z.length,2);var J=i.LOCAL_FILE_HEADER+I+s+z,K=i.CENTRAL_FILE_HEADER+j(H,2)+I+j(v.length,2)+"\0\0\0\0"+j(G,4)+j(d,4)+s+z+v;return{fileRecord:J,dirRecord:K}},n=function(a,b,c,d,f){var g="",h=e.transformTo("string",f(d));return g=i.CENTRAL_DIRECTORY_END+"\0\0\0\0"+j(a,2)+j(a,2)+j(b,4)+j(c,4)+j(h.length,2)+h},o=function(a){var b="";return b=i.DATA_DESCRIPTOR+j(a.crc32,4)+j(a.compressedSize,4)+j(a.uncompressedSize,4)};e.inherits(d,f),d.prototype.push=function(a){var b=a.meta.percent||0,c=this.entriesCount,d=this._sources.length;this.accumulate?this.contentBuffer.push(a):(this.bytesWritten+=a.data.length,f.prototype.push.call(this,{data:a.data,meta:{currentFile:this.currentFile,percent:c?(b+100*(c-d-1))/c:100}}))},d.prototype.openedSource=function(a){this.currentSourceOffset=this.bytesWritten,this.currentFile=a.file.name;var b=this.streamFiles&&!a.file.dir;if(b){var c=m(a,b,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:c.fileRecord,meta:{percent:0}})}else this.accumulate=!0},d.prototype.closedSource=function(a){this.accumulate=!1;var b=this.streamFiles&&!a.file.dir,c=m(a,b,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(c.dirRecord),b)this.push({data:o(a),meta:{percent:100}});else for(this.push({data:c.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},d.prototype.flush=function(){for(var a=this.bytesWritten,b=0;b<this.dirRecords.length;b++)this.push({data:this.dirRecords[b],meta:{percent:100}});var c=this.bytesWritten-a,d=n(this.dirRecords.length,c,a,this.zipComment,this.encodeFileName);this.push({data:d,meta:{percent:100}})},d.prototype.prepareNextSource=function(){this.previous=this._sources.shift(),this.openedSource(this.previous.streamInfo),this.isPaused?this.previous.pause():this.previous.resume()},d.prototype.registerPrevious=function(a){this._sources.push(a);var b=this;return a.on("data",function(a){b.processChunk(a)}),a.on("end",function(){b.closedSource(b.previous.streamInfo),b._sources.length?b.prepareNextSource():b.end()}),a.on("error",function(a){b.error(a)}),this},d.prototype.resume=function(){return!!f.prototype.resume.call(this)&&(!this.previous&&this._sources.length?(this.prepareNextSource(),!0):this.previous||this._sources.length||this.generatedError?void 0:(this.end(),!0))},d.prototype.error=function(a){var b=this._sources;if(!f.prototype.error.call(this,a))return!1;for(var c=0;c<b.length;c++)try{b[c].error(a)}catch(a){}return!0},d.prototype.lock=function(){f.prototype.lock.call(this);for(var a=this._sources,b=0;b<a.length;b++)a[b].lock()},b.exports=d},{"../crc32":4,"../signature":23,"../stream/GenericWorker":28,"../utf8":31,"../utils":32}],9:[function(a,b,c){"use strict";var d=a("../compressions"),e=a("./ZipFileWorker"),f=function(a,b){var c=a||b,e=d[c];if(!e)throw new Error(c+" is not a valid compression method !");return e};c.generateWorker=function(a,b,c){var d=new e(b.streamFiles,c,b.platform,b.encodeFileName),g=0;try{a.forEach(function(a,c){g++;var e=f(c.options.compression,b.compression),h=c.options.compressionOptions||b.compressionOptions||{},i=c.dir,j=c.date;c._compressWorker(e,h).withStreamInfo("file",{name:a,dir:i,date:j,comment:c.comment||"",unixPermissions:c.unixPermissions,dosPermissions:c.dosPermissions}).pipe(d)}),d.entriesCount=g}catch(h){d.error(h)}return d}},{"../compressions":3,"./ZipFileWorker":8}],10:[function(a,b,c){"use strict";function d(){if(!(this instanceof d))return new d;if(arguments.length)throw new Error("The constructor with parameters has been removed in JSZip 3.0, please check the upgrade guide.");this.files={},this.comment=null,this.root="",this.clone=function(){var a=new d;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a}}d.prototype=a("./object"),d.prototype.loadAsync=a("./load"),d.support=a("./support"),d.defaults=a("./defaults"),d.version="3.1.5",d.loadAsync=function(a,b){return(new d).loadAsync(a,b)},d.external=a("./external"),b.exports=d},{"./defaults":5,"./external":6,"./load":11,"./object":15,"./support":30}],11:[function(a,b,c){"use strict";function d(a){return new f.Promise(function(b,c){var d=a.decompressed.getContentWorker().pipe(new i);d.on("error",function(a){c(a)}).on("end",function(){d.streamInfo.crc32!==a.decompressed.crc32?c(new Error("Corrupted zip : CRC32 mismatch")):b()}).resume()})}var e=a("./utils"),f=a("./external"),g=a("./utf8"),e=a("./utils"),h=a("./zipEntries"),i=a("./stream/Crc32Probe"),j=a("./nodejsUtils");b.exports=function(a,b){var c=this;return b=e.extend(b||{},{base64:!1,checkCRC32:!1,optimizedBinaryString:!1,createFolders:!1,decodeFileName:g.utf8decode}),j.isNode&&j.isStream(a)?f.Promise.reject(new Error("JSZip can't accept a stream when loading a zip file.")):e.prepareContent("the loaded zip file",a,!0,b.optimizedBinaryString,b.base64).then(function(a){var c=new h(b);return c.load(a),c}).then(function(a){var c=[f.Promise.resolve(a)],e=a.files;if(b.checkCRC32)for(var g=0;g<e.length;g++)c.push(d(e[g]));return f.Promise.all(c)}).then(function(a){for(var d=a.shift(),e=d.files,f=0;f<e.length;f++){var g=e[f];c.file(g.fileNameStr,g.decompressed,{binary:!0,optimizedBinaryString:!0,date:g.date,dir:g.dir,comment:g.fileCommentStr.length?g.fileCommentStr:null,unixPermissions:g.unixPermissions,dosPermissions:g.dosPermissions,createFolders:b.createFolders})}return d.zipComment.length&&(c.comment=d.zipComment),c})}},{"./external":6,"./nodejsUtils":14,"./stream/Crc32Probe":25,"./utf8":31,"./utils":32,"./zipEntries":33}],12:[function(a,b,c){"use strict";function d(a,b){f.call(this,"Nodejs stream input adapter for "+a),this._upstreamEnded=!1,this._bindStream(b)}var e=a("../utils"),f=a("../stream/GenericWorker");e.inherits(d,f),d.prototype._bindStream=function(a){var b=this;this._stream=a,a.pause(),a.on("data",function(a){b.push({data:a,meta:{percent:0}})}).on("error",function(a){b.isPaused?this.generatedError=a:b.error(a)}).on("end",function(){b.isPaused?b._upstreamEnded=!0:b.end()})},d.prototype.pause=function(){return!!f.prototype.pause.call(this)&&(this._stream.pause(),!0)},d.prototype.resume=function(){return!!f.prototype.resume.call(this)&&(this._upstreamEnded?this.end():this._stream.resume(),!0)},b.exports=d},{"../stream/GenericWorker":28,"../utils":32}],13:[function(a,b,c){"use strict";function d(a,b,c){e.call(this,b),this._helper=a;var d=this;a.on("data",function(a,b){d.push(a)||d._helper.pause(),c&&c(b)}).on("error",function(a){d.emit("error",a)}).on("end",function(){d.push(null)})}var e=a("readable-stream").Readable,f=a("../utils");f.inherits(d,e),d.prototype._read=function(){this._helper.resume()},b.exports=d},{"../utils":32,"readable-stream":16}],14:[function(a,b,c){"use strict";b.exports={isNode:"undefined"!=typeof Buffer,newBufferFrom:function(a,b){return new Buffer(a,b)},allocBuffer:function(a){return Buffer.alloc?Buffer.alloc(a):new Buffer(a)},isBuffer:function(a){return Buffer.isBuffer(a)},isStream:function(a){return a&&"function"==typeof a.on&&"function"==typeof a.pause&&"function"==typeof a.resume}}},{}],15:[function(a,b,c){"use strict";function d(a){return"[object RegExp]"===Object.prototype.toString.call(a)}var e=a("./utf8"),f=a("./utils"),g=a("./stream/GenericWorker"),h=a("./stream/StreamHelper"),i=a("./defaults"),j=a("./compressedObject"),k=a("./zipObject"),l=a("./generate"),m=a("./nodejsUtils"),n=a("./nodejs/NodejsStreamInputAdapter"),o=function(a,b,c){var d,e=f.getTypeOf(b),h=f.extend(c||{},i);h.date=h.date||new Date,null!==h.compression&&(h.compression=h.compression.toUpperCase()),"string"==typeof h.unixPermissions&&(h.unixPermissions=parseInt(h.unixPermissions,8)),h.unixPermissions&&16384&h.unixPermissions&&(h.dir=!0),h.dosPermissions&&16&h.dosPermissions&&(h.dir=!0),h.dir&&(a=q(a)),h.createFolders&&(d=p(a))&&r.call(this,d,!0);var l="string"===e&&h.binary===!1&&h.base64===!1;c&&"undefined"!=typeof c.binary||(h.binary=!l);var o=b instanceof j&&0===b.uncompressedSize;(o||h.dir||!b||0===b.length)&&(h.base64=!1,h.binary=!0,b="",h.compression="STORE",e="string");var s=null;s=b instanceof j||b instanceof g?b:m.isNode&&m.isStream(b)?new n(a,b):f.prepareContent(a,b,h.binary,h.optimizedBinaryString,h.base64);var t=new k(a,s,h);this.files[a]=t},p=function(a){"/"===a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},q=function(a){return"/"!==a.slice(-1)&&(a+="/"),a},r=function(a,b){return b="undefined"!=typeof b?b:i.createFolders,a=q(a),this.files[a]||o.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},s={load:function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},forEach:function(a){var b,c,d;for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],c=b.slice(this.root.length,b.length),c&&b.slice(0,this.root.length)===this.root&&a(c,d))},filter:function(a){var b=[];return this.forEach(function(c,d){a(c,d)&&b.push(d)}),b},file:function(a,b,c){if(1===arguments.length){if(d(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}var f=this.files[this.root+a];return f&&!f.dir?f:null}return a=this.root+a,o.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=r.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!==a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d<c.length;d++)delete this.files[c[d].name];return this},generate:function(a){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},generateInternalStream:function(a){var b,c={};try{if(c=f.extend(a||{},{streamFiles:!1,compression:"STORE",compressionOptions:null,type:"",platform:"DOS",comment:null,mimeType:"application/zip",encodeFileName:e.utf8encode}),c.type=c.type.toLowerCase(),c.compression=c.compression.toUpperCase(),"binarystring"===c.type&&(c.type="string"),!c.type)throw new Error("No output type specified.");f.checkSupport(c.type),"darwin"!==c.platform&&"freebsd"!==c.platform&&"linux"!==c.platform&&"sunos"!==c.platform||(c.platform="UNIX"),"win32"===c.platform&&(c.platform="DOS");var d=c.comment||this.comment||"";b=l.generateWorker(this,c,d)}catch(i){b=new g("error"),b.error(i)}return new h(b,c.type||"string",c.mimeType)},generateAsync:function(a,b){return this.generateInternalStream(a).accumulate(b)},generateNodeStream:function(a,b){return a=a||{},a.type||(a.type="nodebuffer"),this.generateInternalStream(a).toNodejsStream(b)}};b.exports=s},{"./compressedObject":2,"./defaults":5,"./generate":9,"./nodejs/NodejsStreamInputAdapter":12,"./nodejsUtils":14,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31,"./utils":32,"./zipObject":35}],16:[function(a,b,c){b.exports=a("stream")},{stream:void 0}],17:[function(a,b,c){"use strict";function d(a){e.call(this,a);for(var b=0;b<this.data.length;b++)a[b]=255&a[b]}var e=a("./DataReader"),f=a("../utils");f.inherits(d,e),d.prototype.byteAt=function(a){return this.data[this.zero+a]},d.prototype.lastIndexOfSignature=function(a){for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.length-4;f>=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f-this.zero;return-1},d.prototype.readAndCheckSignature=function(a){var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.readData(4);return b===f[0]&&c===f[1]&&d===f[2]&&e===f[3]},d.prototype.readData=function(a){if(this.checkOffset(a),0===a)return[];var b=this.data.slice(this.zero+this.index,this.zero+this.index+a);return this.index+=a,b},b.exports=d},{"../utils":32,"./DataReader":18}],18:[function(a,b,c){"use strict";function d(a){this.data=a,this.length=a.length,this.index=0,this.zero=0}var e=a("../utils");d.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.length<this.zero+a||a<0)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(a){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return e.transformTo("string",this.readData(a))},readData:function(a){},lastIndexOfSignature:function(a){},readAndCheckSignature:function(a){},readDate:function(){var a=this.readInt(4);return new Date(Date.UTC((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1))}},b.exports=d},{"../utils":32}],19:[function(a,b,c){"use strict";function d(a){e.call(this,a)}var e=a("./Uint8ArrayReader"),f=a("../utils");f.inherits(d,e),d.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.zero+this.index,this.zero+this.index+a);return this.index+=a,b},b.exports=d},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(a,b,c){"use strict";function d(a){e.call(this,a)}var e=a("./DataReader"),f=a("../utils");f.inherits(d,e),d.prototype.byteAt=function(a){return this.data.charCodeAt(this.zero+a)},d.prototype.lastIndexOfSignature=function(a){return this.data.lastIndexOf(a)-this.zero},d.prototype.readAndCheckSignature=function(a){var b=this.readData(4);return a===b},d.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.zero+this.index,this.zero+this.index+a);return this.index+=a,b},b.exports=d},{"../utils":32,"./DataReader":18}],21:[function(a,b,c){"use strict";function d(a){e.call(this,a)}var e=a("./ArrayReader"),f=a("../utils");f.inherits(d,e),d.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.zero+this.index,this.zero+this.index+a);return this.index+=a,b},b.exports=d},{"../utils":32,"./ArrayReader":17}],22:[function(a,b,c){"use strict";var d=a("../utils"),e=a("../support"),f=a("./ArrayReader"),g=a("./StringReader"),h=a("./NodeBufferReader"),i=a("./Uint8ArrayReader");b.exports=function(a){var b=d.getTypeOf(a);return d.checkSupport(b),"string"!==b||e.uint8array?"nodebuffer"===b?new h(a):e.uint8array?new i(d.transformTo("uint8array",a)):new f(d.transformTo("array",a)):new g(a)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(a,b,c){"use strict";c.LOCAL_FILE_HEADER="PK",c.CENTRAL_FILE_HEADER="PK",c.CENTRAL_DIRECTORY_END="PK",c.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",c.ZIP64_CENTRAL_DIRECTORY_END="PK",c.DATA_DESCRIPTOR="PK\b"},{}],24:[function(a,b,c){"use strict";function d(a){e.call(this,"ConvertWorker to "+a),this.destType=a}var e=a("./GenericWorker"),f=a("../utils");f.inherits(d,e),d.prototype.processChunk=function(a){this.push({data:f.transformTo(this.destType,a.data),meta:a.meta})},b.exports=d},{"../utils":32,"./GenericWorker":28}],25:[function(a,b,c){"use strict";function d(){e.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}var e=a("./GenericWorker"),f=a("../crc32"),g=a("../utils");g.inherits(d,e),d.prototype.processChunk=function(a){this.streamInfo.crc32=f(a.data,this.streamInfo.crc32||0),this.push(a)},b.exports=d},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(a,b,c){"use strict";function d(a){f.call(this,"DataLengthProbe for "+a),this.propName=a,this.withStreamInfo(a,0)}var e=a("../utils"),f=a("./GenericWorker");e.inherits(d,f),d.prototype.processChunk=function(a){if(a){var b=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=b+a.data.length}f.prototype.processChunk.call(this,a)},b.exports=d},{"../utils":32,"./GenericWorker":28}],27:[function(a,b,c){"use strict";function d(a){f.call(this,"DataWorker");var b=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,a.then(function(a){b.dataIsReady=!0,b.data=a,b.max=a&&a.length||0,b.type=e.getTypeOf(a),b.isPaused||b._tickAndRepeat()},function(a){b.error(a)})}var e=a("../utils"),f=a("./GenericWorker"),g=16384;e.inherits(d,f),d.prototype.cleanUp=function(){f.prototype.cleanUp.call(this),this.data=null},d.prototype.resume=function(){return!!f.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,e.delay(this._tickAndRepeat,[],this)),!0)},d.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(e.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},d.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var a=g,b=null,c=Math.min(this.max,this.index+a);if(this.index>=this.max)return this.end();switch(this.type){case"string":b=this.data.substring(this.index,c);break;case"uint8array":b=this.data.subarray(this.index,c);break;case"array":case"nodebuffer":b=this.data.slice(this.index,c)}return this.index=c,this.push({data:b,meta:{percent:this.max?this.index/this.max*100:0}})},b.exports=d},{"../utils":32,"./GenericWorker":28}],28:[function(a,b,c){"use strict";function d(a){this.name=a||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}d.prototype={push:function(a){this.emit("data",a)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(a){this.emit("error",a)}return!0},error:function(a){return!this.isFinished&&(this.isPaused?this.generatedError=a:(this.isFinished=!0,this.emit("error",a),this.previous&&this.previous.error(a),this.cleanUp()),!0)},on:function(a,b){return this._listeners[a].push(b),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(a,b){if(this._listeners[a])for(var c=0;c<this._listeners[a].length;c++)this._listeners[a][c].call(this,b)},pipe:function(a){return a.registerPrevious(this)},registerPrevious:function(a){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.streamInfo=a.streamInfo,this.mergeStreamInfo(),this.previous=a;var b=this;return a.on("data",function(a){b.processChunk(a)}),a.on("end",function(){b.end()}),a.on("error",function(a){b.error(a)}),this},pause:function(){return!this.isPaused&&!this.isFinished&&(this.isPaused=!0,this.previous&&this.previous.pause(),!0)},resume:function(){if(!this.isPaused||this.isFinished)return!1;this.isPaused=!1;var a=!1;return this.generatedError&&(this.error(this.generatedError),a=!0),this.previous&&this.previous.resume(),!a},flush:function(){},processChunk:function(a){this.push(a)},withStreamInfo:function(a,b){return this.extraStreamInfo[a]=b,this.mergeStreamInfo(),this},mergeStreamInfo:function(){for(var a in this.extraStreamInfo)this.extraStreamInfo.hasOwnProperty(a)&&(this.streamInfo[a]=this.extraStreamInfo[a])},lock:function(){if(this.isLocked)throw new Error("The stream '"+this+"' has already been used.");this.isLocked=!0,this.previous&&this.previous.lock()},toString:function(){var a="Worker "+this.name;return this.previous?this.previous+" -> "+a:a}},b.exports=d},{}],29:[function(a,b,c){"use strict";function d(a,b,c){switch(a){case"blob":return h.newBlob(h.transformTo("arraybuffer",b),c);case"base64":return k.encode(b);default:return h.transformTo(a,b)}}function e(a,b){var c,d=0,e=null,f=0;for(c=0;c<b.length;c++)f+=b[c].length;switch(a){case"string":return b.join("");case"array":return Array.prototype.concat.apply([],b);case"uint8array":for(e=new Uint8Array(f),c=0;c<b.length;c++)e.set(b[c],d),d+=b[c].length;return e;case"nodebuffer":return Buffer.concat(b);default:throw new Error("concat : unsupported type '"+a+"'")}}function f(a,b){return new m.Promise(function(c,f){var g=[],h=a._internalType,i=a._outputType,j=a._mimeType;a.on("data",function(a,c){g.push(a),b&&b(c)}).on("error",function(a){g=[],f(a)}).on("end",function(){try{var a=d(i,e(h,g),j);c(a)}catch(b){f(b)}g=[]}).resume()})}function g(a,b,c){var d=b;switch(b){case"blob":case"arraybuffer":d="uint8array";break;case"base64":d="string"}try{this._internalType=d,this._outputType=b,this._mimeType=c,h.checkSupport(d),this._worker=a.pipe(new i(d)),a.lock()}catch(e){this._worker=new j("error"),this._worker.error(e)}}var h=a("../utils"),i=a("./ConvertWorker"),j=a("./GenericWorker"),k=a("../base64"),l=a("../support"),m=a("../external"),n=null;if(l.nodestream)try{n=a("../nodejs/NodejsStreamOutputAdapter")}catch(o){}g.prototype={accumulate:function(a){return f(this,a)},on:function(a,b){var c=this;return"data"===a?this._worker.on(a,function(a){b.call(c,a.data,a.meta)}):this._worker.on(a,function(){h.delay(b,arguments,c)}),this},resume:function(){return h.delay(this._worker.resume,[],this._worker),this},pause:function(){return this._worker.pause(),this},toNodejsStream:function(a){if(h.checkSupport("nodestream"),"nodebuffer"!==this._outputType)throw new Error(this._outputType+" is not supported by this method");return new n(this,{objectMode:"nodebuffer"!==this._outputType},a)}},b.exports=g},{"../base64":1,"../external":6,"../nodejs/NodejsStreamOutputAdapter":13,"../support":30,"../utils":32,"./ConvertWorker":24,"./GenericWorker":28}],30:[function(a,b,c){"use strict";if(c.base64=!0,c.array=!0,c.string=!0,c.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,c.nodebuffer="undefined"!=typeof Buffer,c.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)c.blob=!1;else{var d=new ArrayBuffer(0);try{c.blob=0===new Blob([d],{type:"application/zip"}).size}catch(e){try{var f=self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder,g=new f;g.append(d),c.blob=0===g.getBlob("application/zip").size}catch(e){c.blob=!1}}}try{c.nodestream=!!a("readable-stream").Readable}catch(e){c.nodestream=!1}},{"readable-stream":16}],31:[function(a,b,c){"use strict";function d(){i.call(this,"utf-8 decode"),this.leftOver=null}function e(){i.call(this,"utf-8 encode")}for(var f=a("./utils"),g=a("./support"),h=a("./nodejsUtils"),i=a("./stream/GenericWorker"),j=new Array(256),k=0;k<256;k++)j[k]=k>=252?6:k>=248?5:k>=240?4:k>=224?3:k>=192?2:1;j[254]=j[254]=1;var l=function(a){var b,c,d,e,f,h=a.length,i=0;for(e=0;e<h;e++)c=a.charCodeAt(e),55296===(64512&c)&&e+1<h&&(d=a.charCodeAt(e+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),e++)),i+=c<128?1:c<2048?2:c<65536?3:4;for(b=g.uint8array?new Uint8Array(i):new Array(i),f=0,e=0;f<i;e++)c=a.charCodeAt(e),55296===(64512&c)&&e+1<h&&(d=a.charCodeAt(e+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),e++)),c<128?b[f++]=c:c<2048?(b[f++]=192|c>>>6,b[f++]=128|63&c):c<65536?(b[f++]=224|c>>>12,b[f++]=128|c>>>6&63,b[f++]=128|63&c):(b[f++]=240|c>>>18,b[f++]=128|c>>>12&63,b[f++]=128|c>>>6&63,b[f++]=128|63&c);return b},m=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return c<0?b:0===c?b:c+j[a[c]]>b?c:b},n=function(a){var b,c,d,e,g=a.length,h=new Array(2*g);for(c=0,b=0;b<g;)if(d=a[b++],d<128)h[c++]=d;else if(e=j[d],e>4)h[c++]=65533,b+=e-1;else{for(d&=2===e?31:3===e?15:7;e>1&&b<g;)d=d<<6|63&a[b++],e--;e>1?h[c++]=65533:d<65536?h[c++]=d:(d-=65536,h[c++]=55296|d>>10&1023,h[c++]=56320|1023&d)}return h.length!==c&&(h.subarray?h=h.subarray(0,c):h.length=c),f.applyFromCharCode(h)};c.utf8encode=function(a){return g.nodebuffer?h.newBufferFrom(a,"utf-8"):l(a)},c.utf8decode=function(a){return g.nodebuffer?f.transformTo("nodebuffer",a).toString("utf-8"):(a=f.transformTo(g.uint8array?"uint8array":"array",a),n(a))},f.inherits(d,i),d.prototype.processChunk=function(a){var b=f.transformTo(g.uint8array?"uint8array":"array",a.data);if(this.leftOver&&this.leftOver.length){if(g.uint8array){var d=b;b=new Uint8Array(d.length+this.leftOver.length),b.set(this.leftOver,0),b.set(d,this.leftOver.length)}else b=this.leftOver.concat(b);this.leftOver=null}var e=m(b),h=b;e!==b.length&&(g.uint8array?(h=b.subarray(0,e),this.leftOver=b.subarray(e,b.length)):(h=b.slice(0,e),this.leftOver=b.slice(e,b.length))),this.push({data:c.utf8decode(h),meta:a.meta})},d.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:c.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},c.Utf8DecodeWorker=d,f.inherits(e,i),e.prototype.processChunk=function(a){this.push({data:c.utf8encode(a.data),meta:a.meta})},c.Utf8EncodeWorker=e},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(a,b,c){"use strict";function d(a){var b=null;return b=i.uint8array?new Uint8Array(a.length):new Array(a.length),f(a,b)}function e(a){return a}function f(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);return b}function g(a){var b=65536,d=c.getTypeOf(a),e=!0;if("uint8array"===d?e=n.applyCanBeUsed.uint8array:"nodebuffer"===d&&(e=n.applyCanBeUsed.nodebuffer),e)for(;b>1;)try{return n.stringifyByChunk(a,d,b)}catch(f){b=Math.floor(b/2)}return n.stringifyByChar(a)}function h(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];
return b}var i=a("./support"),j=a("./base64"),k=a("./nodejsUtils"),l=a("core-js/library/fn/set-immediate"),m=a("./external");c.newBlob=function(a,b){c.checkSupport("blob");try{return new Blob([a],{type:b})}catch(d){try{var e=self.BlobBuilder||self.WebKitBlobBuilder||self.MozBlobBuilder||self.MSBlobBuilder,f=new e;return f.append(a),f.getBlob(b)}catch(d){throw new Error("Bug : can't construct the Blob.")}}};var n={stringifyByChunk:function(a,b,c){var d=[],e=0,f=a.length;if(f<=c)return String.fromCharCode.apply(null,a);for(;e<f;)"array"===b||"nodebuffer"===b?d.push(String.fromCharCode.apply(null,a.slice(e,Math.min(e+c,f)))):d.push(String.fromCharCode.apply(null,a.subarray(e,Math.min(e+c,f)))),e+=c;return d.join("")},stringifyByChar:function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(a[c]);return b},applyCanBeUsed:{uint8array:function(){try{return i.uint8array&&1===String.fromCharCode.apply(null,new Uint8Array(1)).length}catch(a){return!1}}(),nodebuffer:function(){try{return i.nodebuffer&&1===String.fromCharCode.apply(null,k.allocBuffer(1)).length}catch(a){return!1}}()}};c.applyFromCharCode=g;var o={};o.string={string:e,array:function(a){return f(a,new Array(a.length))},arraybuffer:function(a){return o.string.uint8array(a).buffer},uint8array:function(a){return f(a,new Uint8Array(a.length))},nodebuffer:function(a){return f(a,k.allocBuffer(a.length))}},o.array={string:g,array:e,arraybuffer:function(a){return new Uint8Array(a).buffer},uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return k.newBufferFrom(a)}},o.arraybuffer={string:function(a){return g(new Uint8Array(a))},array:function(a){return h(new Uint8Array(a),new Array(a.byteLength))},arraybuffer:e,uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return k.newBufferFrom(new Uint8Array(a))}},o.uint8array={string:g,array:function(a){return h(a,new Array(a.length))},arraybuffer:function(a){return a.buffer},uint8array:e,nodebuffer:function(a){return k.newBufferFrom(a)}},o.nodebuffer={string:g,array:function(a){return h(a,new Array(a.length))},arraybuffer:function(a){return o.nodebuffer.uint8array(a).buffer},uint8array:function(a){return h(a,new Uint8Array(a.length))},nodebuffer:e},c.transformTo=function(a,b){if(b||(b=""),!a)return b;c.checkSupport(a);var d=c.getTypeOf(b),e=o[d][a](b);return e},c.getTypeOf=function(a){return"string"==typeof a?"string":"[object Array]"===Object.prototype.toString.call(a)?"array":i.nodebuffer&&k.isBuffer(a)?"nodebuffer":i.uint8array&&a instanceof Uint8Array?"uint8array":i.arraybuffer&&a instanceof ArrayBuffer?"arraybuffer":void 0},c.checkSupport=function(a){var b=i[a.toLowerCase()];if(!b)throw new Error(a+" is not supported by this platform")},c.MAX_VALUE_16BITS=65535,c.MAX_VALUE_32BITS=-1,c.pretty=function(a){var b,c,d="";for(c=0;c<(a||"").length;c++)b=a.charCodeAt(c),d+="\\x"+(b<16?"0":"")+b.toString(16).toUpperCase();return d},c.delay=function(a,b,c){l(function(){a.apply(c||null,b||[])})},c.inherits=function(a,b){var c=function(){};c.prototype=b.prototype,a.prototype=new c},c.extend=function(){var a,b,c={};for(a=0;a<arguments.length;a++)for(b in arguments[a])arguments[a].hasOwnProperty(b)&&"undefined"==typeof c[b]&&(c[b]=arguments[a][b]);return c},c.prepareContent=function(a,b,e,f,g){var h=m.Promise.resolve(b).then(function(a){var b=i.blob&&(a instanceof Blob||["[object File]","[object Blob]"].indexOf(Object.prototype.toString.call(a))!==-1);return b&&"undefined"!=typeof FileReader?new m.Promise(function(b,c){var d=new FileReader;d.onload=function(a){b(a.target.result)},d.onerror=function(a){c(a.target.error)},d.readAsArrayBuffer(a)}):a});return h.then(function(b){var h=c.getTypeOf(b);return h?("arraybuffer"===h?b=c.transformTo("uint8array",b):"string"===h&&(g?b=j.decode(b):e&&f!==!0&&(b=d(b))),b):m.Promise.reject(new Error("Can't read the data of '"+a+"'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?"))})}},{"./base64":1,"./external":6,"./nodejsUtils":14,"./support":30,"core-js/library/fn/set-immediate":36}],33:[function(a,b,c){"use strict";function d(a){this.files=[],this.loadOptions=a}var e=a("./reader/readerFor"),f=a("./utils"),g=a("./signature"),h=a("./zipEntry"),i=(a("./utf8"),a("./support"));d.prototype={checkSignature:function(a){if(!this.reader.readAndCheckSignature(a)){this.reader.index-=4;var b=this.reader.readString(4);throw new Error("Corrupted zip or bug: unexpected signature ("+f.pretty(b)+", expected "+f.pretty(a)+")")}},isSignature:function(a,b){var c=this.reader.index;this.reader.setIndex(a);var d=this.reader.readString(4),e=d===b;return this.reader.setIndex(c),e},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2);var a=this.reader.readData(this.zipCommentLength),b=i.uint8array?"uint8array":"array",c=f.transformTo(b,a);this.zipComment=this.loadOptions.decodeFileName(c)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.reader.skip(4),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;e<d;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readData(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a<this.files.length;a++)b=this.files[a],this.reader.setIndex(b.localHeaderOffset),this.checkSignature(g.LOCAL_FILE_HEADER),b.readLocalPart(this.reader),b.handleUTF8(),b.processAttributes()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readAndCheckSignature(g.CENTRAL_FILE_HEADER);)a=new h({zip64:this.zip64},this.loadOptions),a.readCentralPart(this.reader),this.files.push(a);if(this.centralDirRecords!==this.files.length&&0!==this.centralDirRecords&&0===this.files.length)throw new Error("Corrupted zip or bug: expected "+this.centralDirRecords+" records in central dir, got "+this.files.length)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(g.CENTRAL_DIRECTORY_END);if(a<0){var b=!this.isSignature(0,g.LOCAL_FILE_HEADER);throw b?new Error("Can't find end of central directory : is this a zip file ? If it is, see https://stuk.github.io/jszip/documentation/howto/read_zip.html"):new Error("Corrupted zip: can't find end of central directory")}this.reader.setIndex(a);var c=a;if(this.checkSignature(g.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===f.MAX_VALUE_16BITS||this.diskWithCentralDirStart===f.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===f.MAX_VALUE_16BITS||this.centralDirRecords===f.MAX_VALUE_16BITS||this.centralDirSize===f.MAX_VALUE_32BITS||this.centralDirOffset===f.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(g.ZIP64_CENTRAL_DIRECTORY_LOCATOR),a<0)throw new Error("Corrupted zip: can't find the ZIP64 end of central directory locator");if(this.reader.setIndex(a),this.checkSignature(g.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),!this.isSignature(this.relativeOffsetEndOfZip64CentralDir,g.ZIP64_CENTRAL_DIRECTORY_END)&&(this.relativeOffsetEndOfZip64CentralDir=this.reader.lastIndexOfSignature(g.ZIP64_CENTRAL_DIRECTORY_END),this.relativeOffsetEndOfZip64CentralDir<0))throw new Error("Corrupted zip: can't find the ZIP64 end of central directory");this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(g.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}var d=this.centralDirOffset+this.centralDirSize;this.zip64&&(d+=20,d+=12+this.zip64EndOfCentralSize);var e=c-d;if(e>0)this.isSignature(c,g.CENTRAL_FILE_HEADER)||(this.reader.zero=e);else if(e<0)throw new Error("Corrupted zip: missing "+Math.abs(e)+" bytes.")},prepareReader:function(a){this.reader=e(a)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=d},{"./reader/readerFor":22,"./signature":23,"./support":30,"./utf8":31,"./utils":32,"./zipEntry":34}],34:[function(a,b,c){"use strict";function d(a,b){this.options=a,this.loadOptions=b}var e=a("./reader/readerFor"),f=a("./utils"),g=a("./compressedObject"),h=a("./crc32"),i=a("./utf8"),j=a("./compressions"),k=a("./support"),l=0,m=3,n=function(a){for(var b in j)if(j.hasOwnProperty(b)&&j[b].magic===a)return j[b];return null};d.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readData(this.fileNameLength),a.skip(c),this.compressedSize===-1||this.uncompressedSize===-1)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize === -1 || uncompressedSize === -1)");if(b=n(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+f.pretty(this.compressionMethod)+" unknown (inner file : "+f.transformTo("string",this.fileName)+")");this.decompressed=new g(this.compressedSize,this.uncompressedSize,this.crc32,b,a.readData(this.compressedSize))},readCentralPart:function(a){this.versionMadeBy=a.readInt(2),a.skip(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4);var b=a.readInt(2);if(this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");a.skip(b),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readData(this.fileCommentLength)},processAttributes:function(){this.unixPermissions=null,this.dosPermissions=null;var a=this.versionMadeBy>>8;this.dir=!!(16&this.externalFileAttributes),a===l&&(this.dosPermissions=63&this.externalFileAttributes),a===m&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(a){if(this.extraFields[1]){var b=e(this.extraFields[1].value);this.uncompressedSize===f.MAX_VALUE_32BITS&&(this.uncompressedSize=b.readInt(8)),this.compressedSize===f.MAX_VALUE_32BITS&&(this.compressedSize=b.readInt(8)),this.localHeaderOffset===f.MAX_VALUE_32BITS&&(this.localHeaderOffset=b.readInt(8)),this.diskNumberStart===f.MAX_VALUE_32BITS&&(this.diskNumberStart=b.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});a.index<e;)b=a.readInt(2),c=a.readInt(2),d=a.readData(c),this.extraFields[b]={id:b,length:c,value:d}},handleUTF8:function(){var a=k.uint8array?"uint8array":"array";if(this.useUTF8())this.fileNameStr=i.utf8decode(this.fileName),this.fileCommentStr=i.utf8decode(this.fileComment);else{var b=this.findExtraFieldUnicodePath();if(null!==b)this.fileNameStr=b;else{var c=f.transformTo(a,this.fileName);this.fileNameStr=this.loadOptions.decodeFileName(c)}var d=this.findExtraFieldUnicodeComment();if(null!==d)this.fileCommentStr=d;else{var e=f.transformTo(a,this.fileComment);this.fileCommentStr=this.loadOptions.decodeFileName(e)}}},findExtraFieldUnicodePath:function(){var a=this.extraFields[28789];if(a){var b=e(a.value);return 1!==b.readInt(1)?null:h(this.fileName)!==b.readInt(4)?null:i.utf8decode(b.readData(a.length-5))}return null},findExtraFieldUnicodeComment:function(){var a=this.extraFields[25461];if(a){var b=e(a.value);return 1!==b.readInt(1)?null:h(this.fileComment)!==b.readInt(4)?null:i.utf8decode(b.readData(a.length-5))}return null}},b.exports=d},{"./compressedObject":2,"./compressions":3,"./crc32":4,"./reader/readerFor":22,"./support":30,"./utf8":31,"./utils":32}],35:[function(a,b,c){"use strict";var d=a("./stream/StreamHelper"),e=a("./stream/DataWorker"),f=a("./utf8"),g=a("./compressedObject"),h=a("./stream/GenericWorker"),i=function(a,b,c){this.name=a,this.dir=c.dir,this.date=c.date,this.comment=c.comment,this.unixPermissions=c.unixPermissions,this.dosPermissions=c.dosPermissions,this._data=b,this._dataBinary=c.binary,this.options={compression:c.compression,compressionOptions:c.compressionOptions}};i.prototype={internalStream:function(a){var b=null,c="string";try{if(!a)throw new Error("No output type specified.");c=a.toLowerCase();var e="string"===c||"text"===c;"binarystring"!==c&&"text"!==c||(c="string"),b=this._decompressWorker();var g=!this._dataBinary;g&&!e&&(b=b.pipe(new f.Utf8EncodeWorker)),!g&&e&&(b=b.pipe(new f.Utf8DecodeWorker))}catch(i){b=new h("error"),b.error(i)}return new d(b,c,"")},async:function(a,b){return this.internalStream(a).accumulate(b)},nodeStream:function(a,b){return this.internalStream(a||"nodebuffer").toNodejsStream(b)},_compressWorker:function(a,b){if(this._data instanceof g&&this._data.compression.magic===a.magic)return this._data.getCompressedWorker();var c=this._decompressWorker();return this._dataBinary||(c=c.pipe(new f.Utf8EncodeWorker)),g.createWorkerFrom(c,a,b)},_decompressWorker:function(){return this._data instanceof g?this._data.getContentWorker():this._data instanceof h?this._data:new e(this._data)}};for(var j=["asText","asBinary","asNodeBuffer","asUint8Array","asArrayBuffer"],k=function(){throw new Error("This method has been removed in JSZip 3.0, please check the upgrade guide.")},l=0;l<j.length;l++)i.prototype[j[l]]=k;b.exports=i},{"./compressedObject":2,"./stream/DataWorker":27,"./stream/GenericWorker":28,"./stream/StreamHelper":29,"./utf8":31}],36:[function(a,b,c){a("../modules/web.immediate"),b.exports=a("../modules/_core").setImmediate},{"../modules/_core":40,"../modules/web.immediate":56}],37:[function(a,b,c){b.exports=function(a){if("function"!=typeof a)throw TypeError(a+" is not a function!");return a}},{}],38:[function(a,b,c){var d=a("./_is-object");b.exports=function(a){if(!d(a))throw TypeError(a+" is not an object!");return a}},{"./_is-object":51}],39:[function(a,b,c){var d={}.toString;b.exports=function(a){return d.call(a).slice(8,-1)}},{}],40:[function(a,b,c){var d=b.exports={version:"2.3.0"};"number"==typeof __e&&(__e=d)},{}],41:[function(a,b,c){var d=a("./_a-function");b.exports=function(a,b,c){if(d(a),void 0===b)return a;switch(c){case 1:return function(c){return a.call(b,c)};case 2:return function(c,d){return a.call(b,c,d)};case 3:return function(c,d,e){return a.call(b,c,d,e)}}return function(){return a.apply(b,arguments)}}},{"./_a-function":37}],42:[function(a,b,c){b.exports=!a("./_fails")(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},{"./_fails":45}],43:[function(a,b,c){var d=a("./_is-object"),e=a("./_global").document,f=d(e)&&d(e.createElement);b.exports=function(a){return f?e.createElement(a):{}}},{"./_global":46,"./_is-object":51}],44:[function(a,b,c){var d=a("./_global"),e=a("./_core"),f=a("./_ctx"),g=a("./_hide"),h="prototype",i=function(a,b,c){var j,k,l,m=a&i.F,n=a&i.G,o=a&i.S,p=a&i.P,q=a&i.B,r=a&i.W,s=n?e:e[b]||(e[b]={}),t=s[h],u=n?d:o?d[b]:(d[b]||{})[h];n&&(c=b);for(j in c)k=!m&&u&&void 0!==u[j],k&&j in s||(l=k?u[j]:c[j],s[j]=n&&"function"!=typeof u[j]?c[j]:q&&k?f(l,d):r&&u[j]==l?function(a){var b=function(b,c,d){if(this instanceof a){switch(arguments.length){case 0:return new a;case 1:return new a(b);case 2:return new a(b,c)}return new a(b,c,d)}return a.apply(this,arguments)};return b[h]=a[h],b}(l):p&&"function"==typeof l?f(Function.call,l):l,p&&((s.virtual||(s.virtual={}))[j]=l,a&i.R&&t&&!t[j]&&g(t,j,l)))};i.F=1,i.G=2,i.S=4,i.P=8,i.B=16,i.W=32,i.U=64,i.R=128,b.exports=i},{"./_core":40,"./_ctx":41,"./_global":46,"./_hide":47}],45:[function(a,b,c){b.exports=function(a){try{return!!a()}catch(b){return!0}}},{}],46:[function(a,b,c){var d=b.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=d)},{}],47:[function(a,b,c){var d=a("./_object-dp"),e=a("./_property-desc");b.exports=a("./_descriptors")?function(a,b,c){return d.f(a,b,e(1,c))}:function(a,b,c){return a[b]=c,a}},{"./_descriptors":42,"./_object-dp":52,"./_property-desc":53}],48:[function(a,b,c){b.exports=a("./_global").document&&document.documentElement},{"./_global":46}],49:[function(a,b,c){b.exports=!a("./_descriptors")&&!a("./_fails")(function(){return 7!=Object.defineProperty(a("./_dom-create")("div"),"a",{get:function(){return 7}}).a})},{"./_descriptors":42,"./_dom-create":43,"./_fails":45}],50:[function(a,b,c){b.exports=function(a,b,c){var d=void 0===c;switch(b.length){case 0:return d?a():a.call(c);case 1:return d?a(b[0]):a.call(c,b[0]);case 2:return d?a(b[0],b[1]):a.call(c,b[0],b[1]);case 3:return d?a(b[0],b[1],b[2]):a.call(c,b[0],b[1],b[2]);case 4:return d?a(b[0],b[1],b[2],b[3]):a.call(c,b[0],b[1],b[2],b[3])}return a.apply(c,b)}},{}],51:[function(a,b,c){b.exports=function(a){return"object"==typeof a?null!==a:"function"==typeof a}},{}],52:[function(a,b,c){var d=a("./_an-object"),e=a("./_ie8-dom-define"),f=a("./_to-primitive"),g=Object.defineProperty;c.f=a("./_descriptors")?Object.defineProperty:function(a,b,c){if(d(a),b=f(b,!0),d(c),e)try{return g(a,b,c)}catch(h){}if("get"in c||"set"in c)throw TypeError("Accessors not supported!");return"value"in c&&(a[b]=c.value),a}},{"./_an-object":38,"./_descriptors":42,"./_ie8-dom-define":49,"./_to-primitive":55}],53:[function(a,b,c){b.exports=function(a,b){return{enumerable:!(1&a),configurable:!(2&a),writable:!(4&a),value:b}}},{}],54:[function(a,b,c){var d,e,f,g=a("./_ctx"),h=a("./_invoke"),i=a("./_html"),j=a("./_dom-create"),k=a("./_global"),l=k.process,m=k.setImmediate,n=k.clearImmediate,o=k.MessageChannel,p=0,q={},r="onreadystatechange",s=function(){var a=+this;if(q.hasOwnProperty(a)){var b=q[a];delete q[a],b()}},t=function(a){s.call(a.data)};m&&n||(m=function(a){for(var b=[],c=1;arguments.length>c;)b.push(arguments[c++]);return q[++p]=function(){h("function"==typeof a?a:Function(a),b)},d(p),p},n=function(a){delete q[a]},"process"==a("./_cof")(l)?d=function(a){l.nextTick(g(s,a,1))}:o?(e=new o,f=e.port2,e.port1.onmessage=t,d=g(f.postMessage,f,1)):k.addEventListener&&"function"==typeof postMessage&&!k.importScripts?(d=function(a){k.postMessage(a+"","*")},k.addEventListener("message",t,!1)):d=r in j("script")?function(a){i.appendChild(j("script"))[r]=function(){i.removeChild(this),s.call(a)}}:function(a){setTimeout(g(s,a,1),0)}),b.exports={set:m,clear:n}},{"./_cof":39,"./_ctx":41,"./_dom-create":43,"./_global":46,"./_html":48,"./_invoke":50}],55:[function(a,b,c){var d=a("./_is-object");b.exports=function(a,b){if(!d(a))return a;var c,e;if(b&&"function"==typeof(c=a.toString)&&!d(e=c.call(a)))return e;if("function"==typeof(c=a.valueOf)&&!d(e=c.call(a)))return e;if(!b&&"function"==typeof(c=a.toString)&&!d(e=c.call(a)))return e;throw TypeError("Can't convert object to primitive value")}},{"./_is-object":51}],56:[function(a,b,c){var d=a("./_export"),e=a("./_task");d(d.G+d.B,{setImmediate:e.set,clearImmediate:e.clear})},{"./_export":44,"./_task":54}],57:[function(a,b,c){(function(a){"use strict";function c(){k=!0;for(var a,b,c=l.length;c;){for(b=l,l=[],a=-1;++a<c;)b[a]();c=l.length}k=!1}function d(a){1!==l.push(a)||k||e()}var e,f=a.MutationObserver||a.WebKitMutationObserver;if(f){var g=0,h=new f(c),i=a.document.createTextNode("");h.observe(i,{characterData:!0}),e=function(){i.data=g=++g%2}}else if(a.setImmediate||"undefined"==typeof a.MessageChannel)e="document"in a&&"onreadystatechange"in a.document.createElement("script")?function(){var b=a.document.createElement("script");b.onreadystatechange=function(){c(),b.onreadystatechange=null,b.parentNode.removeChild(b),b=null},a.document.documentElement.appendChild(b)}:function(){setTimeout(c,0)};else{var j=new a.MessageChannel;j.port1.onmessage=c,e=function(){j.port2.postMessage(0)}}var k,l=[];b.exports=d}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],58:[function(a,b,c){"use strict";function d(){}function e(a){if("function"!=typeof a)throw new TypeError("resolver must be a function");this.state=s,this.queue=[],this.outcome=void 0,a!==d&&i(this,a)}function f(a,b,c){this.promise=a,"function"==typeof b&&(this.onFulfilled=b,this.callFulfilled=this.otherCallFulfilled),"function"==typeof c&&(this.onRejected=c,this.callRejected=this.otherCallRejected)}function g(a,b,c){o(function(){var d;try{d=b(c)}catch(e){return p.reject(a,e)}d===a?p.reject(a,new TypeError("Cannot resolve promise with itself")):p.resolve(a,d)})}function h(a){var b=a&&a.then;if(a&&("object"==typeof a||"function"==typeof a)&&"function"==typeof b)return function(){b.apply(a,arguments)}}function i(a,b){function c(b){f||(f=!0,p.reject(a,b))}function d(b){f||(f=!0,p.resolve(a,b))}function e(){b(d,c)}var f=!1,g=j(e);"error"===g.status&&c(g.value)}function j(a,b){var c={};try{c.value=a(b),c.status="success"}catch(d){c.status="error",c.value=d}return c}function k(a){return a instanceof this?a:p.resolve(new this(d),a)}function l(a){var b=new this(d);return p.reject(b,a)}function m(a){function b(a,b){function d(a){g[b]=a,++h!==e||f||(f=!0,p.resolve(j,g))}c.resolve(a).then(d,function(a){f||(f=!0,p.reject(j,a))})}var c=this;if("[object Array]"!==Object.prototype.toString.call(a))return this.reject(new TypeError("must be an array"));var e=a.length,f=!1;if(!e)return this.resolve([]);for(var g=new Array(e),h=0,i=-1,j=new this(d);++i<e;)b(a[i],i);return j}function n(a){function b(a){c.resolve(a).then(function(a){f||(f=!0,p.resolve(h,a))},function(a){f||(f=!0,p.reject(h,a))})}var c=this;if("[object Array]"!==Object.prototype.toString.call(a))return this.reject(new TypeError("must be an array"));var e=a.length,f=!1;if(!e)return this.resolve([]);for(var g=-1,h=new this(d);++g<e;)b(a[g]);return h}var o=a("immediate"),p={},q=["REJECTED"],r=["FULFILLED"],s=["PENDING"];b.exports=e,e.prototype["catch"]=function(a){return this.then(null,a)},e.prototype.then=function(a,b){if("function"!=typeof a&&this.state===r||"function"!=typeof b&&this.state===q)return this;var c=new this.constructor(d);if(this.state!==s){var e=this.state===r?a:b;g(c,e,this.outcome)}else this.queue.push(new f(c,a,b));return c},f.prototype.callFulfilled=function(a){p.resolve(this.promise,a)},f.prototype.otherCallFulfilled=function(a){g(this.promise,this.onFulfilled,a)},f.prototype.callRejected=function(a){p.reject(this.promise,a)},f.prototype.otherCallRejected=function(a){g(this.promise,this.onRejected,a)},p.resolve=function(a,b){var c=j(h,b);if("error"===c.status)return p.reject(a,c.value);var d=c.value;if(d)i(a,d);else{a.state=r,a.outcome=b;for(var e=-1,f=a.queue.length;++e<f;)a.queue[e].callFulfilled(b)}return a},p.reject=function(a,b){a.state=q,a.outcome=b;for(var c=-1,d=a.queue.length;++c<d;)a.queue[c].callRejected(b);return a},e.resolve=k,e.reject=l,e.all=m,e.race=n},{immediate:57}],59:[function(a,b,c){"use strict";var d=a("./lib/utils/common").assign,e=a("./lib/deflate"),f=a("./lib/inflate"),g=a("./lib/zlib/constants"),h={};d(h,e,f,g),b.exports=h},{"./lib/deflate":60,"./lib/inflate":61,"./lib/utils/common":62,"./lib/zlib/constants":65}],60:[function(a,b,c){"use strict";function d(a){if(!(this instanceof d))return new d(a);this.options=i.assign({level:s,method:u,chunkSize:16384,windowBits:15,memLevel:8,strategy:t,to:""},a||{});var b=this.options;b.raw&&b.windowBits>0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new l,this.strm.avail_out=0;var c=h.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==p)throw new Error(k[c]);if(b.header&&h.deflateSetHeader(this.strm,b.header),b.dictionary){var e;if(e="string"==typeof b.dictionary?j.string2buf(b.dictionary):"[object ArrayBuffer]"===m.call(b.dictionary)?new Uint8Array(b.dictionary):b.dictionary,c=h.deflateSetDictionary(this.strm,e),c!==p)throw new Error(k[c]);this._dict_set=!0}}function e(a,b){var c=new d(b);if(c.push(a,!0),c.err)throw c.msg||k[c.err];return c.result}function f(a,b){return b=b||{},b.raw=!0,e(a,b)}function g(a,b){return b=b||{},b.gzip=!0,e(a,b)}var h=a("./zlib/deflate"),i=a("./utils/common"),j=a("./utils/strings"),k=a("./zlib/messages"),l=a("./zlib/zstream"),m=Object.prototype.toString,n=0,o=4,p=0,q=1,r=2,s=-1,t=0,u=8;d.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?o:n,"string"==typeof a?e.input=j.string2buf(a):"[object ArrayBuffer]"===m.call(a)?e.input=new Uint8Array(a):e.input=a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new i.Buf8(f),e.next_out=0,e.avail_out=f),c=h.deflate(e,d),c!==q&&c!==p)return this.onEnd(c),this.ended=!0,!1;0!==e.avail_out&&(0!==e.avail_in||d!==o&&d!==r)||("string"===this.options.to?this.onData(j.buf2binstring(i.shrinkBuf(e.output,e.next_out))):this.onData(i.shrinkBuf(e.output,e.next_out)))}while((e.avail_in>0||0===e.avail_out)&&c!==q);return d===o?(c=h.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===p):d!==r||(this.onEnd(p),e.avail_out=0,!0)},d.prototype.onData=function(a){this.chunks.push(a)},d.prototype.onEnd=function(a){a===p&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=i.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=d,c.deflate=e,c.deflateRaw=f,c.gzip=g},{"./utils/common":62,"./utils/strings":63,"./zlib/deflate":67,"./zlib/messages":72,"./zlib/zstream":74}],61:[function(a,b,c){"use strict";function d(a){if(!(this instanceof d))return new d(a);this.options=h.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new l,this.strm.avail_out=0;var c=g.inflateInit2(this.strm,b.windowBits);if(c!==j.Z_OK)throw new Error(k[c]);this.header=new m,g.inflateGetHeader(this.strm,this.header)}function e(a,b){var c=new d(b);if(c.push(a,!0),c.err)throw c.msg||k[c.err];return c.result}function f(a,b){return b=b||{},b.raw=!0,e(a,b)}var g=a("./zlib/inflate"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/constants"),k=a("./zlib/messages"),l=a("./zlib/zstream"),m=a("./zlib/gzheader"),n=Object.prototype.toString;d.prototype.push=function(a,b){var c,d,e,f,k,l,m=this.strm,o=this.options.chunkSize,p=this.options.dictionary,q=!1;if(this.ended)return!1;d=b===~~b?b:b===!0?j.Z_FINISH:j.Z_NO_FLUSH,"string"==typeof a?m.input=i.binstring2buf(a):"[object ArrayBuffer]"===n.call(a)?m.input=new Uint8Array(a):m.input=a,m.next_in=0,m.avail_in=m.input.length;do{if(0===m.avail_out&&(m.output=new h.Buf8(o),m.next_out=0,m.avail_out=o),c=g.inflate(m,j.Z_NO_FLUSH),c===j.Z_NEED_DICT&&p&&(l="string"==typeof p?i.string2buf(p):"[object ArrayBuffer]"===n.call(p)?new Uint8Array(p):p,c=g.inflateSetDictionary(this.strm,l)),c===j.Z_BUF_ERROR&&q===!0&&(c=j.Z_OK,q=!1),c!==j.Z_STREAM_END&&c!==j.Z_OK)return this.onEnd(c),this.ended=!0,!1;m.next_out&&(0!==m.avail_out&&c!==j.Z_STREAM_END&&(0!==m.avail_in||d!==j.Z_FINISH&&d!==j.Z_SYNC_FLUSH)||("string"===this.options.to?(e=i.utf8border(m.output,m.next_out),f=m.next_out-e,k=i.buf2string(m.output,e),m.next_out=f,m.avail_out=o-f,f&&h.arraySet(m.output,m.output,e,f,0),this.onData(k)):this.onData(h.shrinkBuf(m.output,m.next_out)))),0===m.avail_in&&0===m.avail_out&&(q=!0)}while((m.avail_in>0||0===m.avail_out)&&c!==j.Z_STREAM_END);return c===j.Z_STREAM_END&&(d=j.Z_FINISH),d===j.Z_FINISH?(c=g.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===j.Z_OK):d!==j.Z_SYNC_FLUSH||(this.onEnd(j.Z_OK),m.avail_out=0,!0)},d.prototype.onData=function(a){this.chunks.push(a)},d.prototype.onEnd=function(a){a===j.Z_OK&&("string"===this.options.to?this.result=this.chunks.join(""):this.result=h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=d,c.inflate=e,c.inflateRaw=f,c.ungzip=e},{"./utils/common":62,"./utils/strings":63,"./zlib/constants":65,"./zlib/gzheader":68,"./zlib/inflate":70,"./zlib/messages":72,"./zlib/zstream":74}],62:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;f<d;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;b<c;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;b<c;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;f<d;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],63:[function(a,b,c){"use strict";function d(a,b){if(b<65537&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;d<b;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;j<256;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;f<h;f++)c=a.charCodeAt(f),55296===(64512&c)&&f+1<h&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=c<128?1:c<2048?2:c<65536?3:4;for(b=new e.Buf8(i),g=0,f=0;g<i;f++)c=a.charCodeAt(f),55296===(64512&c)&&f+1<h&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),c<128?b[g++]=c:c<2048?(b[g++]=192|c>>>6,b[g++]=128|63&c):c<65536?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;c<d;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;c<h;)if(f=a[c++],f<128)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&c<h;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:f<65536?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return c<0?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":62}],64:[function(a,b,c){"use strict";function d(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0;
}b.exports=d},{}],65:[function(a,b,c){"use strict";b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],66:[function(a,b,c){"use strict";function d(){for(var a,b=[],c=0;c<256;c++){a=c;for(var d=0;d<8;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function e(a,b,c,d){var e=f,g=d+c;a^=-1;for(var h=d;h<g;h++)a=a>>>8^e[255&(a^b[h])];return a^-1}var f=d();b.exports=e},{}],67:[function(a,b,c){"use strict";function d(a,b){return a.msg=I[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(E.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){F._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,E.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=G(a.adler,b,e,c):2===a.state.wrap&&(a.adler=H(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-la?a.strstart-(a.w_size-la):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ka,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&f<m);if(d=ka-(m-f),f=m-ka,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-la)){E.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=ja)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+1])&a.hash_mask;a.insert&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+ja-1])&a.hash_mask,a.prev[f&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=f,f++,a.insert--,!(a.lookahead+a.insert<ja)););}while(a.lookahead<la&&0!==a.strm.avail_in)}function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===J)return ua;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return ua;if(a.strstart-a.block_start>=a.w_size-la&&(h(a,!1),0===a.strm.avail_out))return ua}return a.insert=0,b===M?(h(a,!0),0===a.strm.avail_out?wa:xa):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?ua:ua}function o(a,b){for(var c,d;;){if(a.lookahead<la){if(m(a),a.lookahead<la&&b===J)return ua;if(0===a.lookahead)break}if(c=0,a.lookahead>=ja&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+ja-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),0!==c&&a.strstart-c<=a.w_size-la&&(a.match_length=l(a,c)),a.match_length>=ja)if(d=F._tr_tally(a,a.strstart-a.match_start,a.match_length-ja),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=ja){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+ja-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart;while(0!==--a.match_length);a.strstart++}else a.strstart+=a.match_length,a.match_length=0,a.ins_h=a.window[a.strstart],a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+1])&a.hash_mask;else d=F._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++;if(d&&(h(a,!1),0===a.strm.avail_out))return ua}return a.insert=a.strstart<ja-1?a.strstart:ja-1,b===M?(h(a,!0),0===a.strm.avail_out?wa:xa):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?ua:va}function p(a,b){for(var c,d,e;;){if(a.lookahead<la){if(m(a),a.lookahead<la&&b===J)return ua;if(0===a.lookahead)break}if(c=0,a.lookahead>=ja&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+ja-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),a.prev_length=a.match_length,a.prev_match=a.match_start,a.match_length=ja-1,0!==c&&a.prev_length<a.max_lazy_match&&a.strstart-c<=a.w_size-la&&(a.match_length=l(a,c),a.match_length<=5&&(a.strategy===U||a.match_length===ja&&a.strstart-a.match_start>4096)&&(a.match_length=ja-1)),a.prev_length>=ja&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-ja,d=F._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-ja),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+ja-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart);while(0!==--a.prev_length);if(a.match_available=0,a.match_length=ja-1,a.strstart++,d&&(h(a,!1),0===a.strm.avail_out))return ua}else if(a.match_available){if(d=F._tr_tally(a,0,a.window[a.strstart-1]),d&&h(a,!1),a.strstart++,a.lookahead--,0===a.strm.avail_out)return ua}else a.match_available=1,a.strstart++,a.lookahead--}return a.match_available&&(d=F._tr_tally(a,0,a.window[a.strstart-1]),a.match_available=0),a.insert=a.strstart<ja-1?a.strstart:ja-1,b===M?(h(a,!0),0===a.strm.avail_out?wa:xa):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?ua:va}function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ka){if(m(a),a.lookahead<=ka&&b===J)return ua;if(0===a.lookahead)break}if(a.match_length=0,a.lookahead>=ja&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ka;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&e<f);a.match_length=ka-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=ja?(c=F._tr_tally(a,1,a.match_length-ja),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=F._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return ua}return a.insert=0,b===M?(h(a,!0),0===a.strm.avail_out?wa:xa):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?ua:va}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===J)return ua;break}if(a.match_length=0,c=F._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return ua}return a.insert=0,b===M?(h(a,!0),0===a.strm.avail_out?wa:xa):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?ua:va}function s(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e}function t(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=D[a.level].max_lazy,a.good_match=D[a.level].good_length,a.nice_match=D[a.level].nice_length,a.max_chain_length=D[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=ja-1,a.match_available=0,a.ins_h=0}function u(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=$,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new E.Buf16(2*ha),this.dyn_dtree=new E.Buf16(2*(2*fa+1)),this.bl_tree=new E.Buf16(2*(2*ga+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new E.Buf16(ia+1),this.heap=new E.Buf16(2*ea+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new E.Buf16(2*ea+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function v(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=Z,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?na:sa,a.adler=2===b.wrap?0:1,b.last_flush=J,F._tr_init(b),O):d(a,Q)}function w(a){var b=v(a);return b===O&&t(a.state),b}function x(a,b){return a&&a.state?2!==a.state.wrap?Q:(a.state.gzhead=b,O):Q}function y(a,b,c,e,f,g){if(!a)return Q;var h=1;if(b===T&&(b=6),e<0?(h=0,e=-e):e>15&&(h=2,e-=16),f<1||f>_||c!==$||e<8||e>15||b<0||b>9||g<0||g>X)return d(a,Q);8===e&&(e=9);var i=new u;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<<i.w_bits,i.w_mask=i.w_size-1,i.hash_bits=f+7,i.hash_size=1<<i.hash_bits,i.hash_mask=i.hash_size-1,i.hash_shift=~~((i.hash_bits+ja-1)/ja),i.window=new E.Buf8(2*i.w_size),i.head=new E.Buf16(i.hash_size),i.prev=new E.Buf16(i.w_size),i.lit_bufsize=1<<f+6,i.pending_buf_size=4*i.lit_bufsize,i.pending_buf=new E.Buf8(i.pending_buf_size),i.d_buf=1*i.lit_bufsize,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,w(a)}function z(a,b){return y(a,b,$,aa,ba,Y)}function A(a,b){var c,h,k,l;if(!a||!a.state||b>N||b<0)return a?d(a,Q):Q;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===ta&&b!==M)return d(a,0===a.avail_out?S:Q);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===na)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=V||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=H(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=oa):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=V||h.level<2?4:0),i(h,ya),h.status=sa);else{var m=$+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=V||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=ma),m+=31-m%31,h.status=sa,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===oa)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=H(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=H(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=pa)}else h.status=pa;if(h.status===pa)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=H(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.name.length?255&h.gzhead.name.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=H(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=qa)}else h.status=qa;if(h.status===qa)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=H(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.comment.length?255&h.gzhead.comment.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=H(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=ra)}else h.status=ra;if(h.status===ra&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=sa)):h.status=sa),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,O}else if(0===a.avail_in&&e(b)<=e(c)&&b!==M)return d(a,S);if(h.status===ta&&0!==a.avail_in)return d(a,S);if(0!==a.avail_in||0!==h.lookahead||b!==J&&h.status!==ta){var o=h.strategy===V?r(h,b):h.strategy===W?q(h,b):D[h.level].func(h,b);if(o!==wa&&o!==xa||(h.status=ta),o===ua||o===wa)return 0===a.avail_out&&(h.last_flush=-1),O;if(o===va&&(b===K?F._tr_align(h):b!==N&&(F._tr_stored_block(h,0,0,!1),b===L&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,O}return b!==M?O:h.wrap<=0?P:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?O:P)}function B(a){var b;return a&&a.state?(b=a.state.status,b!==na&&b!==oa&&b!==pa&&b!==qa&&b!==ra&&b!==sa&&b!==ta?d(a,Q):(a.state=null,b===sa?d(a,R):O)):Q}function C(a,b){var c,d,e,g,h,i,j,k,l=b.length;if(!a||!a.state)return Q;if(c=a.state,g=c.wrap,2===g||1===g&&c.status!==na||c.lookahead)return Q;for(1===g&&(a.adler=G(a.adler,b,l,0)),c.wrap=0,l>=c.w_size&&(0===g&&(f(c.head),c.strstart=0,c.block_start=0,c.insert=0),k=new E.Buf8(c.w_size),E.arraySet(k,b,l-c.w_size,c.w_size,0),b=k,l=c.w_size),h=a.avail_in,i=a.next_in,j=a.input,a.avail_in=l,a.next_in=0,a.input=b,m(c);c.lookahead>=ja;){d=c.strstart,e=c.lookahead-(ja-1);do c.ins_h=(c.ins_h<<c.hash_shift^c.window[d+ja-1])&c.hash_mask,c.prev[d&c.w_mask]=c.head[c.ins_h],c.head[c.ins_h]=d,d++;while(--e);c.strstart=d,c.lookahead=ja-1,m(c)}return c.strstart+=c.lookahead,c.block_start=c.strstart,c.insert=c.lookahead,c.lookahead=0,c.match_length=c.prev_length=ja-1,c.match_available=0,a.next_in=i,a.input=j,a.avail_in=h,c.wrap=g,O}var D,E=a("../utils/common"),F=a("./trees"),G=a("./adler32"),H=a("./crc32"),I=a("./messages"),J=0,K=1,L=3,M=4,N=5,O=0,P=1,Q=-2,R=-3,S=-5,T=-1,U=1,V=2,W=3,X=4,Y=0,Z=2,$=8,_=9,aa=15,ba=8,ca=29,da=256,ea=da+1+ca,fa=30,ga=19,ha=2*ea+1,ia=15,ja=3,ka=258,la=ka+ja+1,ma=32,na=42,oa=69,pa=73,qa=91,ra=103,sa=113,ta=666,ua=1,va=2,wa=3,xa=4,ya=3;D=[new s(0,0,0,0,n),new s(4,4,8,4,o),new s(4,5,16,8,o),new s(4,6,32,32,o),new s(4,4,16,16,p),new s(8,16,32,32,p),new s(8,16,128,128,p),new s(8,32,128,256,p),new s(32,128,258,1024,p),new s(32,258,258,4096,p)],c.deflateInit=z,c.deflateInit2=y,c.deflateReset=w,c.deflateResetKeep=v,c.deflateSetHeader=x,c.deflate=A,c.deflateEnd=B,c.deflateSetDictionary=C,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":62,"./adler32":64,"./crc32":66,"./messages":72,"./trees":73}],68:[function(a,b,c){"use strict";function d(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=d},{}],69:[function(a,b,c){"use strict";var d=30,e=12;b.exports=function(a,b){var c,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;c=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=c.dmax,l=c.wsize,m=c.whave,n=c.wnext,o=c.window,p=c.hold,q=c.bits,r=c.lencode,s=c.distcode,t=(1<<c.lenbits)-1,u=(1<<c.distbits)-1;a:do{q<15&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=r[p&t];b:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<<w)-1)];continue b}if(32&w){c.mode=e;break a}a.msg="invalid literal/length code",c.mode=d;break a}x=65535&v,w&=15,w&&(q<w&&(p+=B[f++]<<q,q+=8),x+=p&(1<<w)-1,p>>>=w,q-=w),q<15&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=s[p&u];c:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<<w)-1)];continue c}a.msg="invalid distance code",c.mode=d;break a}if(y=65535&v,w&=15,q<w&&(p+=B[f++]<<q,q+=8,q<w&&(p+=B[f++]<<q,q+=8)),y+=p&(1<<w)-1,y>k){a.msg="invalid distance too far back",c.mode=d;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&c.sane){a.msg="invalid distance too far back",c.mode=d;break a}if(z=0,A=o,0===n){if(z+=l-w,w<x){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(n<w){if(z+=l+n-w,w-=n,w<x){x-=w;do C[h++]=o[z++];while(--w);if(z=0,n<x){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,w<x){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(f<g&&h<j);x=q>>3,f-=x,q-=x<<3,p&=(1<<q)-1,a.next_in=f,a.next_out=h,a.avail_in=f<g?5+(g-f):5-(f-g),a.avail_out=h<j?257+(j-h):257-(h-j),c.hold=p,c.bits=q}},{}],70:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new s.Buf16(320),this.work=new s.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=L,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new s.Buf32(pa),b.distcode=b.distdyn=new s.Buf32(qa),b.sane=1,b.back=-1,D):G}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):G}function h(a,b){var c,d;return a&&a.state?(d=a.state,b<0?(c=0,b=-b):(c=(b>>4)+1,b<48&&(b&=15)),b&&(b<8||b>15)?G:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):G}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==D&&(a.state=null),c):G}function j(a){return i(a,sa)}function k(a){if(ta){var b;for(q=new s.Buf32(512),r=new s.Buf32(32),b=0;b<144;)a.lens[b++]=8;for(;b<256;)a.lens[b++]=9;for(;b<280;)a.lens[b++]=7;for(;b<288;)a.lens[b++]=8;for(w(y,a.lens,0,288,q,0,a.work,{bits:9}),b=0;b<32;)a.lens[b++]=5;w(z,a.lens,0,32,r,0,a.work,{bits:5}),ta=!1}a.lencode=q,a.lenbits=9,a.distcode=r,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<f.wbits,f.wnext=0,f.whave=0,f.window=new s.Buf8(f.wsize)),d>=f.wsize?(s.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),s.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(s.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whave<f.wsize&&(f.whave+=e))),0}function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,r,pa,qa,ra,sa,ta,ua,va,wa,xa,ya,za,Aa=0,Ba=new s.Buf8(4),Ca=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!a||!a.state||!a.output||!a.input&&0!==a.avail_in)return G;c=a.state,c.mode===W&&(c.mode=X),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,o=i,p=j,xa=D;a:for(;;)switch(c.mode){case L:if(0===c.wrap){c.mode=X;break}for(;n<16;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(2&c.wrap&&35615===m){c.check=0,Ba[0]=255&m,Ba[1]=m>>>8&255,c.check=u(c.check,Ba,2,0),m=0,n=0,c.mode=M;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=ma;break}if((15&m)!==K){a.msg="unknown compression method",c.mode=ma;break}if(m>>>=4,n-=4,wa=(15&m)+8,0===c.wbits)c.wbits=wa;else if(wa>c.wbits){a.msg="invalid window size",c.mode=ma;break}c.dmax=1<<wa,a.adler=c.check=1,c.mode=512&m?U:W,m=0,n=0;break;case M:for(;n<16;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.flags=m,(255&c.flags)!==K){a.msg="unknown compression method",c.mode=ma;break}if(57344&c.flags){a.msg="unknown header flags set",c.mode=ma;break}c.head&&(c.head.text=m>>8&1),512&c.flags&&(Ba[0]=255&m,Ba[1]=m>>>8&255,c.check=u(c.check,Ba,2,0)),m=0,n=0,c.mode=N;case N:for(;n<32;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.time=m),512&c.flags&&(Ba[0]=255&m,Ba[1]=m>>>8&255,Ba[2]=m>>>16&255,Ba[3]=m>>>24&255,c.check=u(c.check,Ba,4,0)),m=0,n=0,c.mode=O;case O:for(;n<16;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.xflags=255&m,c.head.os=m>>8),512&c.flags&&(Ba[0]=255&m,Ba[1]=m>>>8&255,c.check=u(c.check,Ba,2,0)),m=0,n=0,c.mode=P;case P:if(1024&c.flags){for(;n<16;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length=m,c.head&&(c.head.extra_len=m),512&c.flags&&(Ba[0]=255&m,Ba[1]=m>>>8&255,c.check=u(c.check,Ba,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=Q;case Q:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wa=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),s.arraySet(c.head.extra,e,g,q,wa)),512&c.flags&&(c.check=u(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=R;case R:if(2048&c.flags){if(0===i)break a;q=0;do wa=e[g+q++],c.head&&wa&&c.length<65536&&(c.head.name+=String.fromCharCode(wa));while(wa&&q<i);if(512&c.flags&&(c.check=u(c.check,e,q,g)),i-=q,g+=q,wa)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=S;case S:if(4096&c.flags){if(0===i)break a;q=0;do wa=e[g+q++],c.head&&wa&&c.length<65536&&(c.head.comment+=String.fromCharCode(wa));while(wa&&q<i);if(512&c.flags&&(c.check=u(c.check,e,q,g)),i-=q,g+=q,wa)break a}else c.head&&(c.head.comment=null);c.mode=T;case T:if(512&c.flags){for(;n<16;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(65535&c.check)){a.msg="header crc mismatch",c.mode=ma;break}m=0,n=0}c.head&&(c.head.hcrc=c.flags>>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=W;break;case U:for(;n<32;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}a.adler=c.check=d(m),m=0,n=0,c.mode=V;case V:if(0===c.havedict)return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,F;a.adler=c.check=1,c.mode=W;case W:if(b===B||b===C)break a;case X:if(c.last){m>>>=7&n,n-=7&n,c.mode=ja;break}for(;n<3;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}switch(c.last=1&m,m>>>=1,n-=1,3&m){case 0:c.mode=Y;break;case 1:if(k(c),c.mode=ca,b===C){m>>>=2,n-=2;break a}break;case 2:c.mode=_;break;case 3:a.msg="invalid block type",c.mode=ma}m>>>=2,n-=2;break;case Y:for(m>>>=7&n,n-=7&n;n<32;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if((65535&m)!==(m>>>16^65535)){a.msg="invalid stored block lengths",c.mode=ma;break}if(c.length=65535&m,m=0,n=0,c.mode=Z,b===C)break a;case Z:c.mode=$;case $:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;s.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=W;break;case _:for(;n<14;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.nlen=(31&m)+257,m>>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=ma;break}c.have=0,c.mode=aa;case aa:for(;c.have<c.ncode;){for(;n<3;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.lens[Ca[c.have++]]=7&m,m>>>=3,n-=3}for(;c.have<19;)c.lens[Ca[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,ya={bits:c.lenbits},xa=w(x,c.lens,0,19,c.lencode,0,c.work,ya),c.lenbits=ya.bits,xa){a.msg="invalid code lengths set",c.mode=ma;break}c.have=0,c.mode=ba;case ba:for(;c.have<c.nlen+c.ndist;){for(;Aa=c.lencode[m&(1<<c.lenbits)-1],qa=Aa>>>24,ra=Aa>>>16&255,sa=65535&Aa,!(qa<=n);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(sa<16)m>>>=qa,n-=qa,c.lens[c.have++]=sa;else{if(16===sa){for(za=qa+2;n<za;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m>>>=qa,n-=qa,0===c.have){a.msg="invalid bit length repeat",c.mode=ma;break}wa=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sa){for(za=qa+3;n<za;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qa,n-=qa,wa=0,q=3+(7&m),m>>>=3,n-=3}else{for(za=qa+7;n<za;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qa,n-=qa,wa=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=ma;break}for(;q--;)c.lens[c.have++]=wa}}if(c.mode===ma)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=ma;break}if(c.lenbits=9,ya={bits:c.lenbits},xa=w(y,c.lens,0,c.nlen,c.lencode,0,c.work,ya),c.lenbits=ya.bits,xa){a.msg="invalid literal/lengths set",c.mode=ma;break}if(c.distbits=6,c.distcode=c.distdyn,ya={bits:c.distbits},xa=w(z,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,ya),c.distbits=ya.bits,xa){a.msg="invalid distances set",c.mode=ma;break}if(c.mode=ca,b===C)break a;case ca:c.mode=da;case da:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,v(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===W&&(c.back=-1);break}for(c.back=0;Aa=c.lencode[m&(1<<c.lenbits)-1],qa=Aa>>>24,ra=Aa>>>16&255,sa=65535&Aa,!(qa<=n);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(ra&&0===(240&ra)){for(ta=qa,ua=ra,va=sa;Aa=c.lencode[va+((m&(1<<ta+ua)-1)>>ta)],qa=Aa>>>24,ra=Aa>>>16&255,sa=65535&Aa,!(ta+qa<=n);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=ta,n-=ta,c.back+=ta}if(m>>>=qa,n-=qa,c.back+=qa,c.length=sa,0===ra){c.mode=ia;break}if(32&ra){c.back=-1,c.mode=W;break}if(64&ra){a.msg="invalid literal/length code",c.mode=ma;break}c.extra=15&ra,c.mode=ea;case ea:if(c.extra){for(za=c.extra;n<za;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=fa;case fa:for(;Aa=c.distcode[m&(1<<c.distbits)-1],qa=Aa>>>24,ra=Aa>>>16&255,sa=65535&Aa,!(qa<=n);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(0===(240&ra)){for(ta=qa,ua=ra,va=sa;Aa=c.distcode[va+((m&(1<<ta+ua)-1)>>ta)],qa=Aa>>>24,ra=Aa>>>16&255,sa=65535&Aa,!(ta+qa<=n);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=ta,n-=ta,c.back+=ta}if(m>>>=qa,n-=qa,c.back+=qa,64&ra){a.msg="invalid distance code",c.mode=ma;break}c.offset=sa,c.extra=15&ra,c.mode=ga;case ga:if(c.extra){for(za=c.extra;n<za;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.offset+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=ma;break}c.mode=ha;case ha:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=ma;break}q>c.wnext?(q-=c.wnext,r=c.wsize-q):r=c.wnext-q,q>c.length&&(q=c.length),pa=c.window}else pa=f,r=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pa[r++];while(--q);0===c.length&&(c.mode=da);break;case ia:if(0===j)break a;f[h++]=c.length,j--,c.mode=da;break;case ja:if(c.wrap){for(;n<32;){if(0===i)break a;i--,m|=e[g++]<<n,n+=8}if(p-=j,a.total_out+=p,c.total+=p,p&&(a.adler=c.check=c.flags?u(c.check,f,p,h-p):t(c.check,f,p,h-p)),p=j,(c.flags?m:d(m))!==c.check){a.msg="incorrect data check",c.mode=ma;break}m=0,n=0}c.mode=ka;case ka:if(c.wrap&&c.flags){for(;n<32;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(4294967295&c.total)){a.msg="incorrect length check",c.mode=ma;break}m=0,n=0}c.mode=la;case la:xa=E;break a;case ma:xa=H;break a;case na:return I;case oa:default:return G}return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,(c.wsize||p!==a.avail_out&&c.mode<ma&&(c.mode<ja||b!==A))&&l(a,a.output,a.next_out,p-a.avail_out)?(c.mode=na,I):(o-=a.avail_in,p-=a.avail_out,a.total_in+=o,a.total_out+=p,c.total+=p,c.wrap&&p&&(a.adler=c.check=c.flags?u(c.check,f,p,a.next_out-p):t(c.check,f,p,a.next_out-p)),a.data_type=c.bits+(c.last?64:0)+(c.mode===W?128:0)+(c.mode===ca||c.mode===Z?256:0),(0===o&&0===p||b===A)&&xa===D&&(xa=J),xa)}function n(a){if(!a||!a.state)return G;var b=a.state;return b.window&&(b.window=null),a.state=null,D}function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?G:(c.head=b,b.done=!1,D)):G}function p(a,b){var c,d,e,f=b.length;return a&&a.state?(c=a.state,0!==c.wrap&&c.mode!==V?G:c.mode===V&&(d=1,d=t(d,b,f,0),d!==c.check)?H:(e=l(a,b,f,f))?(c.mode=na,I):(c.havedict=1,D)):G}var q,r,s=a("../utils/common"),t=a("./adler32"),u=a("./crc32"),v=a("./inffast"),w=a("./inftrees"),x=0,y=1,z=2,A=4,B=5,C=6,D=0,E=1,F=2,G=-2,H=-3,I=-4,J=-5,K=8,L=1,M=2,N=3,O=4,P=5,Q=6,R=7,S=8,T=9,U=10,V=11,W=12,X=13,Y=14,Z=15,$=16,_=17,aa=18,ba=19,ca=20,da=21,ea=22,fa=23,ga=24,ha=25,ia=26,ja=27,ka=28,la=29,ma=30,na=31,oa=32,pa=852,qa=592,ra=15,sa=ra,ta=!0;c.inflateReset=g,c.inflateReset2=h,c.inflateResetKeep=f,c.inflateInit=j,c.inflateInit2=i,c.inflate=m,c.inflateEnd=n,c.inflateGetHeader=o,c.inflateSetDictionary=p,c.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":62,"./adler32":64,"./crc32":66,"./inffast":69,"./inftrees":71}],71:[function(a,b,c){"use strict";var d=a("../utils/common"),e=15,f=852,g=592,h=0,i=1,j=2,k=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],l=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],m=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],n=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];b.exports=function(a,b,c,o,p,q,r,s){var t,u,v,w,x,y,z,A,B,C=s.bits,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=null,O=0,P=new d.Buf16(e+1),Q=new d.Buf16(e+1),R=null,S=0;for(D=0;D<=e;D++)P[D]=0;for(E=0;E<o;E++)P[b[c+E]]++;for(H=C,G=e;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;F<G&&0===P[F];F++);for(H<F&&(H=F),K=1,D=1;D<=e;D++)if(K<<=1,K-=P[D],K<0)return-1;if(K>0&&(a===h||1!==G))return-1;for(Q[1]=0,D=1;D<e;D++)Q[D+1]=Q[D]+P[D];for(E=0;E<o;E++)0!==b[c+E]&&(r[Q[b[c+E]]++]=E);if(a===h?(N=R=r,y=19):a===i?(N=k,O-=257,R=l,S-=257,y=256):(N=m,R=n,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<<H,w=L-1,a===i&&L>f||a===j&&L>g)return 1;for(;;){z=D-J,r[E]<y?(A=0,B=r[E]):r[E]>y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<<D-J,u=1<<I,F=u;do u-=t,p[x+(M>>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<<D-1;M&t;)t>>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[c+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<<I;I+J<G&&(K-=P[I+J],!(K<=0));)I++,K<<=1;if(L+=1<<I,a===i&&L>f||a===j&&L>g)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":62}],72:[function(a,b,c){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],73:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length}function f(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b}function g(a){return a<256?ia[a]:ia[256+(a>>>7)]}function h(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function i(a,b,c){a.bi_valid>X-c?(a.bi_buf|=b<<a.bi_valid&65535,h(a,a.bi_buf),a.bi_buf=b>>X-a.bi_valid,a.bi_valid+=c-X):(a.bi_buf|=b<<a.bi_valid&65535,a.bi_valid+=c)}function j(a,b,c){i(a,c[2*b],c[2*b+1])}function k(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}function l(a){16===a.bi_valid?(h(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function m(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;f<=W;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,
c=a.heap_max+1;c<V;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function n(a,b,c){var d,e,f=new Array(W+1),g=0;for(d=1;d<=W;d++)f[d]=g=g+c[d-1]<<1;for(e=0;e<=b;e++){var h=a[2*e+1];0!==h&&(a[2*e]=k(f[h]++,h))}}function o(){var a,b,c,d,f,g=new Array(W+1);for(c=0,d=0;d<Q-1;d++)for(ka[d]=c,a=0;a<1<<ba[d];a++)ja[c++]=d;for(ja[c-1]=d,f=0,d=0;d<16;d++)for(la[d]=f,a=0;a<1<<ca[d];a++)ia[f++]=d;for(f>>=7;d<T;d++)for(la[d]=f<<7,a=0;a<1<<ca[d]-7;a++)ia[256+f++]=d;for(b=0;b<=W;b++)g[b]=0;for(a=0;a<=143;)ga[2*a+1]=8,a++,g[8]++;for(;a<=255;)ga[2*a+1]=9,a++,g[9]++;for(;a<=279;)ga[2*a+1]=7,a++,g[7]++;for(;a<=287;)ga[2*a+1]=8,a++,g[8]++;for(n(ga,S+1,g),a=0;a<T;a++)ha[2*a+1]=5,ha[2*a]=k(a,5);ma=new e(ga,ba,R+1,S,W),na=new e(ha,ca,0,T,W),oa=new e(new Array(0),da,0,U,Y)}function p(a){var b;for(b=0;b<S;b++)a.dyn_ltree[2*b]=0;for(b=0;b<T;b++)a.dyn_dtree[2*b]=0;for(b=0;b<U;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*Z]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function q(a){a.bi_valid>8?h(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function r(a,b,c,d){q(a),d&&(h(a,c),h(a,~c)),G.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function s(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<=d[c]}function t(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_len&&s(b,a.heap[e+1],a.heap[e],a.depth)&&e++,!s(b,d,a.heap[e],a.depth));)a.heap[c]=a.heap[e],c=e,e<<=1;a.heap[c]=d}function u(a,b,c){var d,e,f,h,k=0;if(0!==a.last_lit)do d=a.pending_buf[a.d_buf+2*k]<<8|a.pending_buf[a.d_buf+2*k+1],e=a.pending_buf[a.l_buf+k],k++,0===d?j(a,e,b):(f=ja[e],j(a,f+R+1,b),h=ba[f],0!==h&&(e-=ka[f],i(a,e,h)),d--,f=g(d),j(a,f,c),h=ca[f],0!==h&&(d-=la[f],i(a,d,h)));while(k<a.last_lit);j(a,Z,b)}function v(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.stat_desc.has_stree,i=b.stat_desc.elems,j=-1;for(a.heap_len=0,a.heap_max=V,c=0;c<i;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=j<2?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)t(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],t(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,t(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],m(a,b),n(f,j,a.bl_count)}function w(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;d<=c;d++)e=g,g=b[2*(d+1)+1],++h<i&&e===g||(h<j?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*$]++):h<=10?a.bl_tree[2*_]++:a.bl_tree[2*aa]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function x(a,b,c){var d,e,f=-1,g=b[1],h=0,k=7,l=4;for(0===g&&(k=138,l=3),d=0;d<=c;d++)if(e=g,g=b[2*(d+1)+1],!(++h<k&&e===g)){if(h<l){do j(a,e,a.bl_tree);while(0!==--h)}else 0!==e?(e!==f&&(j(a,e,a.bl_tree),h--),j(a,$,a.bl_tree),i(a,h-3,2)):h<=10?(j(a,_,a.bl_tree),i(a,h-3,3)):(j(a,aa,a.bl_tree),i(a,h-11,7));h=0,f=e,0===g?(k=138,l=3):e===g?(k=6,l=3):(k=7,l=4)}}function y(a){var b;for(w(a,a.dyn_ltree,a.l_desc.max_code),w(a,a.dyn_dtree,a.d_desc.max_code),v(a,a.bl_desc),b=U-1;b>=3&&0===a.bl_tree[2*ea[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function z(a,b,c,d){var e;for(i(a,b-257,5),i(a,c-1,5),i(a,d-4,4),e=0;e<d;e++)i(a,a.bl_tree[2*ea[e]+1],3);x(a,a.dyn_ltree,b-1),x(a,a.dyn_dtree,c-1)}function A(a){var b,c=4093624447;for(b=0;b<=31;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return I;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return J;for(b=32;b<R;b++)if(0!==a.dyn_ltree[2*b])return J;return I}function B(a){pa||(o(),pa=!0),a.l_desc=new f(a.dyn_ltree,ma),a.d_desc=new f(a.dyn_dtree,na),a.bl_desc=new f(a.bl_tree,oa),a.bi_buf=0,a.bi_valid=0,p(a)}function C(a,b,c,d){i(a,(L<<1)+(d?1:0),3),r(a,b,c,!0)}function D(a){i(a,M<<1,3),j(a,Z,ga),l(a)}function E(a,b,c,d){var e,f,g=0;a.level>0?(a.strm.data_type===K&&(a.strm.data_type=A(a)),v(a,a.l_desc),v(a,a.d_desc),g=y(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,f<=e&&(e=f)):e=f=c+5,c+4<=e&&b!==-1?C(a,b,c,d):a.strategy===H||f===e?(i(a,(M<<1)+(d?1:0),3),u(a,ga,ha)):(i(a,(N<<1)+(d?1:0),3),z(a,a.l_desc.max_code+1,a.d_desc.max_code+1,g+1),u(a,a.dyn_ltree,a.dyn_dtree)),p(a),d&&q(a)}function F(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(ja[c]+R+1)]++,a.dyn_dtree[2*g(b)]++),a.last_lit===a.lit_bufsize-1}var G=a("../utils/common"),H=4,I=0,J=1,K=2,L=0,M=1,N=2,O=3,P=258,Q=29,R=256,S=R+1+Q,T=30,U=19,V=2*S+1,W=15,X=16,Y=7,Z=256,$=16,_=17,aa=18,ba=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ca=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],da=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],ea=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],fa=512,ga=new Array(2*(S+2));d(ga);var ha=new Array(2*T);d(ha);var ia=new Array(fa);d(ia);var ja=new Array(P-O+1);d(ja);var ka=new Array(Q);d(ka);var la=new Array(T);d(la);var ma,na,oa,pa=!1;c._tr_init=B,c._tr_stored_block=C,c._tr_flush_block=E,c._tr_tally=F,c._tr_align=D},{"../utils/common":62}],74:[function(a,b,c){"use strict";function d(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=d},{}]},{},[10])(10)});
});</script>
<script>SC.extension.addInitializeProc('045d6e44-8bda-4c77-8d1a-275fc5597f69', function (extensionContext) {
//@ts-check
function getSessionCount() {
	return Number(getSessionStorageItem('sessionCount')) || 0;
}

function setSessionCount(count) {
	setSessionStorageItem('sessionCount', count);
}

function getSnapshotCount(sessionId) {
	return Number(getSessionStorageItem(`${sessionId}.snapshotCount`)) || 0;
}

function getSnapshotsSelectedCount() {
	return Number(getSessionStorageItem('snapshotsSelectedCount')) || 0;

}

function setSnapshotsSelectedCount(count) {
	setSessionStorageItem('snapshotsSelectedCount', count);
}

function setSessionStorageItem(key, value) {
	sessionStorage.setItem('ConnectWiseView.' + key, value.toString());
}

function getSessionStorageItem(key) {
	return sessionStorage.getItem('ConnectWiseView.' + key);
}

function dataURLtoBlob(dataurl) {
	const parts = dataurl.split(','), mime = parts[0].match(/:(.*?);/)[1]
	if (parts[0].indexOf('base64') !== -1) {
		const bstr = atob(parts[1]);
		var n = bstr.length, u8arr = new Uint8Array(n)
		while (n--) {
			u8arr[n] = bstr.charCodeAt(n)
		}

		return new Blob([u8arr], { type: mime })
	}
	else {
		const raw = decodeURIComponent(parts[1])
		return new Blob([raw], { type: mime })
	}
}

function getFilenameSafeCurrentDate(date) {
	if (date == undefined)
		date = new Date();
	return date.toISOString().replace(/:/g, '.');
}

function showView() {
	setSessionCount(getSessionCount() + 1);
	new ConnectWiseView.Host(new ConnectWiseView.ConnectWiseControlHostProvider()).show();
}

function showSaveModal(snapshotCount, sessionId) {
	if (!snapshotCount) {
		cleanupViewSession(sessionId);
		return;
	}

	const onSnapshotSelectionChange = function (eventArgs) {
		var target;
		if (eventArgs.type == 'click') {
			target = document.querySelector(`#SnapshotCheck_${eventArgs.target.id.split('_')[1]}`); //todo
			target.checked = !target.checked;
		}
		else
			target = eventArgs.target;

		SC.css.ensureClass(eventArgs.target.parentNode, 'Checked', target.checked);

		var selectedCount = getSnapshotsSelectedCount();
		if (target.checked)
			selectedCount++;
		else
			selectedCount--;

		const saveButton = document.querySelector('.ButtonPanel input');
		if (selectedCount > 0)
			saveButton.disabled = false;
		else {
			selectedCount = 0;
			saveButton.disabled = true;
		}

		setSnapshotsSelectedCount(selectedCount);
	}

	const onSnapshotSelectionChangeAll = function (value) {
		document.querySelectorAll('.SnapshotCheckbox').forEach(function (checkbox) {
			checkbox.checked = value;
			SC.css.ensureClass(checkbox.parentNode, 'Checked', value);
		});

		setSnapshotsSelectedCount(value ? snapshotCount : 0);
		document.querySelector('.ButtonPanel input').disabled = !value; //save button
	}

	const buildThumbnailList = function () {
		var thumbs = [];
		var checkbox;
		for (var snapshotNumber = 1; snapshotNumber <= snapshotCount; snapshotNumber++) {
			checkbox = $input({ type: 'checkbox', id: `SnapshotCheck_${snapshotNumber}`, className: 'SnapshotCheckbox' });
			SC.event.addHandler(checkbox, 'change', onSnapshotSelectionChange);

			var thumb = $img({
				src: getSessionStorageItem(`${sessionId}.snapshot${snapshotNumber}`),
				id: `SnapshotThumb_${snapshotNumber}`
			});
			SC.event.addHandler(thumb, 'click', onSnapshotSelectionChange);

			var span = $span({ id: `SnapshotSpan_${snapshotNumber}`, className: 'CheckBox' });
			SC.event.addHandler(span, 'click', onSnapshotSelectionChange);

			thumbs.push($div([thumb, checkbox, span]));
		}
		return thumbs;
	};


	const buttonPanel = SC.dialog.createButtonPanel(SC.res['ConnectWiseView.SnapshotModal.SaveButtonLabel']);
	buttonPanel.firstChild.disabled = true;

	const selectAllButton = $button({ _textResource: 'ConnectWiseView.SnapshotModal.SelectAllLabel', className: 'SecondaryButton' });
	SC.event.addHandler(selectAllButton, 'click', function (eventArgs) {
		onSnapshotSelectionChangeAll(true);
	});

	const unselectAllButton = $button({ _textResource: 'ConnectWiseView.SnapshotModal.UnselectAllLabel', className: 'SecondaryButton' });
	SC.event.addHandler(unselectAllButton, 'click', function (eventArgs) {
		onSnapshotSelectionChangeAll(false);
	});

	const contentPanel = SC.dialog.createContentPanel([
		$div([
			$p(SC.res['ConnectWiseView.SnapshotModal.Message']),
			selectAllButton,
			unselectAllButton
		]),
		$div({ className: 'SnapshotContainer' }, buildThumbnailList())
	]);

	SC.dialog.showModalDialogRaw(
		'EditRole ViewModal',
		[
			SC.dialog.createTitlePanel(SC.res['ConnectWiseView.SnapshotModal.Title']),
			contentPanel,
			buttonPanel
		],
		function () {
			const selectedCount = getSnapshotsSelectedCount();
			if (selectedCount === 1) {
				const selectedSnapshot = document.querySelector('.SnapshotCheckbox:checked');
				const snapshotNumber = selectedSnapshot.id.split('_')[1];
				saveAs(
					dataURLtoBlob(getSessionStorageItem(`${sessionId}.snapshot${snapshotNumber}`)),
					`ViewSnapshot_${getSessionStorageItem(`${sessionId}.snapshot${snapshotNumber}Time`)}.jpg`
				);
			}
			if (selectedCount > 1) {
				var zip = new JSZip();

				document.querySelectorAll('.SnapshotCheckbox:checked').forEach(function (snapshotElement) {
					const snapshotNumber = snapshotElement.id.split('_')[1];
					zip.file(
						`ViewSnapshot_${getSessionStorageItem(`${sessionId}.snapshot${snapshotNumber}Time`)}.jpg`,
						getSessionStorageItem(`${sessionId}.snapshot${snapshotNumber}`).split(',')[1],
						{ base64: true }
					);
				});

				zip.generateAsync({ type: 'blob' }).then(function (blob) {
					saveAs(blob, `ConnectWiseView_${getFilenameSafeCurrentDate()}.zip`);
				});
			}

			const dialog = SC.dialog.getModalDialog();
			if (dialog) {
				SC.css.ensureClass(dialog, 'Hidden', true);
			}
			cleanupViewSession(sessionId);
		},
		null,
		function () {
			const dialog = SC.dialog.getModalDialog();
			if (dialog) {
				SC.css.ensureClass(dialog, 'Hidden', true);
			}
			cleanupViewSession(sessionId);
		}
	);
}

function cleanupViewSession(sessionId) {
	for (const key in sessionStorage) {
		if (key.startsWith(`ConnectWiseView.${sessionId}`)) {
			sessionStorage.removeItem(key);
		}
	}

	sessionStorage.removeItem('ConnectWiseView.snapshotsSelectedCount');

	if (getSessionCount() == 0)
		sessionStorage.removeItem('ConnectWiseView.sessionCount');
}


window.processViewSessionEnd = function (milliseconds, sessionId) {
	setSessionCount(getSessionCount() - 1);
	showSaveModal(getSnapshotCount(sessionId), sessionId);
}


window.processViewSnapshot = function (data, sessionId) {
	const snapshotNumber = getSnapshotCount(sessionId) + 1;

	setSessionStorageItem(`${sessionId}.snapshot${snapshotNumber}`, data);
	setSessionStorageItem(`${sessionId}.snapshot${snapshotNumber}Time`, getFilenameSafeCurrentDate());
	setSessionStorageItem(`${sessionId}.snapshotCount`, snapshotNumber);
}

SC.event.addGlobalHandler(SC.event.ExecuteCommand, function (eventArgs) {
	switch (eventArgs.commandName) {
		case 'LaunchViewSessionEx':
			const sourceUrl = SC.util.sanitizeUrl(extensionContext.settingValues.ConnectWiseViewBaseUrl + '/hosting/cw-control.js');

			if (document.querySelector(`script[src="${sourceUrl}"]`)) {
				showView();
			} else {
				const script = document.createElement('script');
				script.src = sourceUrl;
				script.onload = showView;
				document.body.appendChild(script);
			}
			break;

		case 'PopoutViewMenu':
			SC.popout.togglePanel(
				eventArgs.commandElement,
				function (popoutPanel) {
					SC.ui.setContents(popoutPanel,
						$div({ _commandName: 'LaunchViewSessionEx' }, [
							$img({
								src: `${extensionContext.baseUrl}Logo.svg`,
								alt: SC.res['ConnectWiseView.ButtonImageAltText'],
								title: SC.res['ConnectWiseView.ButtonImageAltText'],
							}),
							$span(SC.res['ConnectWiseView.ButtonLabel']),
						])
					);
					SC.css.ensureClass(popoutPanel, 'ViewPopout', true);
				}
			);
	}
});

SC.event.addGlobalHandler(SC.event.PreRender, function () {
	if (SC.context.pageBaseFileName == 'Guest')
		return;

	SC.util.includeStyleSheet(`${extensionContext.baseUrl}Style.css`);

	if (SC.context.productVersion.split('.')[0] < 20 || (SC.context.productVersion.split('.')[0] == 20 && SC.context.productVersion.split('.')[1] < 2)) {
		document.querySelector('.GlobalBar > .UserMenuButton').insertAdjacentElement( // Shell theme uses trayPanel to show CW View in 20.2
			'beforebegin',
			$div({ className: 'ViewBar' },
				$div({ className: 'ViewShellButton', _commandName: 'PopoutViewMenu' },
					$img({ src: `${extensionContext.baseUrl}Waffle Icon.svg` })
				)
			)
		);

		document.querySelector('.NavigationPanel > span').insertAdjacentElement( // New Solid Theme uses Waffle Icon to show CW View in 20.2
			'afterend',
			$div({ className: 'ViewNavButton', _commandName: 'LaunchViewSessionEx' }, [
				$img({
					src: `${extensionContext.baseUrl}ViewLogo.svg`,
					alt: SC.res['ConnectWiseView.ButtonImageAltText'],
					title: SC.res['ConnectWiseView.ButtonImageAltText']
				}),
				$span(SC.res['ConnectWiseView.ButtonLabel'])
			])
		);
	}
});

SC.event.addGlobalHandler(SC.event.QueryCommandButtons, function (eventArgs) {
	if (SC.context.pageType == 'HostPage' || SC.context.pageType == 'AdministrationPage') {
		switch (eventArgs.area) {
			case 'TrayIconPanel':
				eventArgs.buttonDefinitions.push({
					commandName: 'LaunchViewSessionEx',
					text: SC.res['ConnectWiseView.ButtonLabel'],
					imageUrl: extensionContext.baseUrl + 'ViewLogo.svg',
					tooltipOrTitle: true, // tooltipOrTitle is no longer need after live-data branch got merged in, keep this here for backward compatibility
				});
				break;
			case 'TrayPanel':
				eventArgs.buttonDefinitions.push({
					commandName: 'PopoutViewMenu',
					imageUrl: extensionContext.baseUrl + 'Waffle Icon.svg',
				});
				break;
		}
	}
});

window.showModal = function (snapshotCount) {
	const sessionId = 'fakeSess';
	if (!Number(sessionStorage.getItem('ConnectWiseView.sessionCount'))) //no other sessions
		sessionStorage.setItem('ConnectWiseView.sessionCount', '1');
	var date = new Date();
	for (var snapshotNumber = 1; snapshotNumber <= snapshotCount; snapshotNumber++) {
		sessionStorage.setItem(`ConnectWiseView.${sessionId}.snapshot${snapshotNumber}`, (Math.random() > 0.5 ? '' : ''));
		date.setMilliseconds(date.getMilliseconds() + 1); //avoid same-naming
		sessionStorage.setItem(`ConnectWiseView.${sessionId}.snapshot${snapshotNumber}Time`, getFilenameSafeCurrentDate(date));
	}

	showSaveModal(snapshotCount);
}
});</script>
<script>SC.extension.addInitializeProc('158cfe2a-e19f-407a-a9b2-899be383abe7', function (extensionContext) {
SC.event.QueryTutorialLinks = 'querytutoriallinks';
SC.event.QueryUsefulLinks = 'queryusefullinks';
SC.event.QueryNeedSupportLinks = 'queryneedsupportlinks';
SC.event.QueryAdditionalSupportLinks = 'queryadditionalsupportlinks';
SC.event.QueryAdditionalGuidePanelLinks = 'queryadditionalguidepanellinks';

const $svg = window.$svg || function(fileNameOrContent, ...args) {
	var tagName = 'svg';
	var element = document.createElement(tagName);

	// Cache for loaded SVG content
	if (!window._svgCache) {
		window._svgCache = new Map();
	}

	function applySvgContent(svgContent) {
		// Create a sandboxed iframe for parsing SVG
		var iframe = document.createElement('iframe');
		iframe.style.display = 'none';
		iframe.sandbox = 'allow-same-origin'; // Minimal sandbox permissions
		document.body.appendChild(iframe);

		try {
			var iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
			iframeDoc.open();
			iframeDoc.write(svgContent);
			iframeDoc.close();

			var svgElement = iframeDoc.querySelector('svg');
			if (svgElement) {
				// Clone the SVG element safely to the main document
				var clonedSvg = document.importNode(svgElement, true);

				// Sanitize attributes to prevent script execution
				sanitizeSvgElement(clonedSvg);

				// Replace the placeholder element with the sanitized SVG
				if (element.parentNode) {
					element.parentNode.replaceChild(clonedSvg, element);
				}

				// Update the reference to point to the new SVG element
				element = clonedSvg;
			}
		} catch (error) {
			console.error('Error processing SVG content:', error);
		} finally {
			// Clean up the iframe
			document.body.removeChild(iframe);
		}
	}

	function sanitizeSvgElement(svgElement) {
		// Remove potentially dangerous attributes and elements
		var dangerousAttributes = ['onload', 'onerror', 'onclick', 'onmouseover', 'onmouseout'];
		var dangerousElements = ['script', 'foreignObject', 'use'];

		// Remove dangerous attributes from the SVG and all descendants
		var allElements = [svgElement].concat(Array.from(svgElement.querySelectorAll('*')));
		allElements.forEach(function(el) {
			dangerousAttributes.forEach(function(attr) {
				el.removeAttribute(attr);
			});

			// Remove any attribute that starts with 'on' (event handlers)
			Array.from(el.attributes).forEach(function(attr) {
				if (attr.name.toLowerCase().startsWith('on')) {
					el.removeAttribute(attr.name);
				}
			});
		});

		// Remove dangerous elements
		dangerousElements.forEach(function(tagName) {
			var elements = svgElement.querySelectorAll(tagName);
			Array.from(elements).forEach(function(el) {
				el.parentNode.removeChild(el);
			});
		});
	}

	// Check if fileName is direct SVG content or a URL
	var isSvgContent = fileNameOrContent.trim().startsWith('<svg');

	if (isSvgContent) {
		// Direct SVG content
		applySvgContent(fileNameOrContent);
	} else {
		// URL to SVG file
		if (window._svgCache.has(fileNameOrContent)) {
			var svgContent = window._svgCache.get(fileNameOrContent);
			applySvgContent(svgContent);
		} else {
			fetch(fileNameOrContent)
				.then(response => {
					if (!response.ok) {
						throw new Error(`Failed to load SVG file: ${fileNameOrContent}`);
					}
					return response.text();
				})
				.then(svgContent => {
					window._svgCache.set(fileNameOrContent, svgContent);
					applySvgContent(svgContent);
				})
				.catch(error => {
					console.error('Error loading SVG:', error);
				});
		}
	}

	return element;
};

SC.event.addGlobalHandler(SC.event.QueryCommandButtons, function (eventArgs) {
	if (SC.context.pageType == 'HostPage' || SC.context.pageType == 'AdministrationPage') {
		switch (eventArgs.area) {
			case 'HelpPopoutPanel':
				eventArgs.buttonDefinitions.push({
					commandName: 'ShowEnhancedHelp',
					text: SC.res['EnhancedHelp.ModalTitle.Text'],
				});
				break;
			case 'TrayPanel':
				eventArgs.buttonDefinitions.push({
					commandName: 'ShowEnhancedHelp',
					imageUrl: extensionContext.baseUrl + 'Icons/HelpIconDark.svg',
					className: 'EnhancedHelpButtonGlobalBar',
					title: SC.res['EnhancedHelp.ModalTitle.Text'],
				});
				break;
			case 'TrayIconPanel':
				eventArgs.buttonDefinitions.push({
					commandName: 'ShowEnhancedHelp',
					imageUrl: extensionContext.baseUrl + 'Icons/HelpIcon.svg',
					className: 'EnhancedHelpButtonGlobalBar',
					title: SC.res['EnhancedHelp.ModalTitle.Text'],
					tooltipOrTitle: true, // tooltipOrTitle is no longer need after live-data branch got merged in, keep this here for backward compatibility
				});
				break;
		}
	}
});

function createNewWindowLink(resourceKeyWord) {
	return $a({ _textResource: 'EnhancedHelp.' + resourceKeyWord + '.Text', href: SC.res['EnhancedHelp.' + resourceKeyWord + '.Url'], target: '_blank', className: resourceKeyWord });
}

function createNewWindowCardLink(resourceKeyWord, icon) {
	return $a({className: `CardLink CenterContent ${resourceKeyWord}`, href: SC.res['EnhancedHelp.' + resourceKeyWord + '.Url'], target: '_blank'}, [
		$svg(extensionContext.baseUrl + `Icons/${icon}.svg`),
		$h3({ _textResource: 'EnhancedHelp.' + resourceKeyWord + '.Text' }),
	])
}

SC.event.addGlobalHandler(SC.event.ExecuteCommand, function (eventArgs) {
	switch (eventArgs.commandName) {
		case 'ShowEnhancedHelp':
			if (SC.context.productVersion.split('.')[0] <= 19 && SC.context.productVersion.split('.')[1] <= 5) { // Added a new way to create modal in 19.6
				SC.dialog.showModalDialogRaw('EnhancedHelpOld', [
					SC.dialog.createTitlePanel(SC.res['EnhancedHelpOld.ModalTitle.Text']),
					SC.dialog.createContentPanel([
						$div({ className: 'GuidesPanel' }, [
							createNewWindowLink('ReleaseNotes'),
							createNewWindowLink('SecurityGuide'),
							createNewWindowLink('SupportGuide'),
							createNewWindowLink('AccessGuide'),
						]),
						$div({ className: 'HelpPanel' }, [
							$h4({ _textResource: 'EnhancedHelp.IdeasPanel.Title' }),
							SC.command.createCommandButtons([
								{ commandName: 'GiveFeedback' },
							]),
							createNewWindowLink('EnhancementRequest'),
						]),
						$div({ className: 'HelpPanel' }, [
							$h4({ _textResource: 'EnhancedHelp.NeedSupportPanel.Title' }),
							createNewWindowLink('SubmitTicket'),
							createNewWindowLink('StartChat'),
						]),
						$div({ className: 'MoreHelpPanel' }, [
							createNewWindowLink('OnlineHelp'),
							createNewWindowLink('UserForum'),
						]),
					]),
				]);
			}
			else {
				var retrievedAdditionalGuidePanelContent = SC.event.dispatchGlobalEvent(SC.event.QueryAdditionalGuidePanelLinks, { additionalGuidePanelLinks: [] });
				var retrievedTutorialsInfo = SC.event.dispatchGlobalEvent(SC.event.QueryTutorialLinks, { tutorialLinks: [] });
				var retrievedUsefulLinksInfo = SC.event.dispatchGlobalEvent(SC.event.QueryUsefulLinks, { usefulLinks: [] });
				var retrievedNeedSupportsInfo = SC.event.dispatchGlobalEvent(SC.event.QueryNeedSupportLinks, { needSupportLinks: [] });
				var retrievedAdditionalSupportLinksInfo = SC.event.dispatchGlobalEvent(SC.event.QueryAdditionalSupportLinks, { additionalLinks: [] });

				//So that onprem instances don't lose original links since there's now dynamically generated cloud stuff
				if (SC.util.isNullOrEmpty(SC.context.instanceID)) {
					retrievedNeedSupportsInfo = {
						needSupportLinks: [
							{ url: SC.res['EnhancedHelp.SubmitTicket.Url'], title: SC.res['EnhancedHelp.SubmitTicket.Text'] },
							{ url: SC.res['EnhancedHelp.StartChat.Url'], title: SC.res['EnhancedHelp.StartChat.Text'] },
						]
					};

					retrievedAdditionalSupportLinksInfo = {
						additionalLinks: [
							{ url: SC.res['EnhancedHelp.BrowseArticle.Url'], title: SC.res['EnhancedHelp.BrowseArticle.Text'], image: extensionContext.baseUrl + 'Icons/DocumentIcon.svg' },
							{ url: SC.res['EnhancedHelp.VisitForum.Url'], title: SC.res['EnhancedHelp.VisitForum.Text'], image: extensionContext.baseUrl + 'Icons/ChatIcon.svg' },
						]
					}
				}

				SC.dialog.showModalDialog('EnhancedHelp flow', {
					noBackdrop: true,
					isContentFullSize: true,
					content: [
						$div({ className: 'CenterContent' }, [
							$svg(extensionContext.baseUrl + 'Icons/BulbIcon.svg'),
							$h2({ _textResource: 'EnhancedHelp.ModalTitle.Text' }),
						]),
						$div({ className: 'EnhancedHelpGuides flow'}, [
							$h3({ _textResource: 'EnhancedHelp.Guides.Text' }),
							$div({ className: 'GuidesPanel' }, [
								createNewWindowCardLink('ReleaseNotes', 'FolderIcon'),
								createNewWindowCardLink('SecurityGuide', 'SecurityIcon'),
								createNewWindowCardLink('SupportGuide', 'RemoteSupportIcon'),
								createNewWindowCardLink('AccessGuide', 'MobileSupportIcon'),
								...retrievedAdditionalGuidePanelContent.additionalGuidePanelLinks.map(function (additionalGuidePanelLink) {
									return $a({className: `CardLink CenterContent`, href: additionalGuidePanelLink.url, target: '_blank'}, [
										$svg(additionalGuidePanelLink.image),
										$h3(additionalGuidePanelLink.title),
									])
								})
							]),
						]),
						$div({ className: 'HelpPanels' }, [
							$div({
								className: 'HelpPanel TutorialsPanel flow',
								_visible: retrievedTutorialsInfo.tutorialLinks.length !== 0,
							 }, [
								$div({ className: 'HelpPanelTitle IconText'}, [
									$svg(extensionContext.baseUrl + 'Icons/FolderIcon.svg'),
									$h3({ _textResource: 'EnhancedHelp.TutorialsPanel.Title' }),
								]),
								retrievedTutorialsInfo.tutorialLinks.map(function (tutorialInfo) {
									return $div({}, [
										$a({ className: 'noStyleLink', href: tutorialInfo.url, target: '_blank' }, tutorialInfo.title)
									]);
								})
							]),
							$div({
								className: 'HelpPanel IdeasPanel flow',
								_visible: retrievedUsefulLinksInfo.usefulLinks.length !== 0,
							 }, [
								$div({ className: 'HelpPanelTitle IconText'}, [
									$svg(extensionContext.baseUrl + 'Icons/LinkIcon.svg'),
									$h3({ _textResource: 'EnhancedHelp.IdeasPanel.Title' }),
								]),
								retrievedUsefulLinksInfo.usefulLinks.map(function (usefulLink) {
									return $div({}, [
										$a({ className: 'noStyleLink', href: usefulLink.url, target: '_blank' }, usefulLink.title)
									]);
								})
							]),
							$div({
								className: 'HelpPanel SupportPanel flow',
								_visible: retrievedNeedSupportsInfo.needSupportLinks.length !== 0,
							 }, [
								$div({ className: 'HelpPanelTitle IconText'}, [
									$svg(extensionContext.baseUrl + 'Icons/SupportIcon.svg'),
									$h3({ _textResource: 'EnhancedHelp.SupportPanel.Title' }),
								]),
								retrievedNeedSupportsInfo.needSupportLinks.map(function (needSupportLink) {
									return $div({}, [
										$a({ className: 'noStyleLink', href: needSupportLink.url, target: '_blank' }, needSupportLink.title)
									]);
								})
							]),
							$div({
								className: 'HelpPanel MoreHelpPanel',
								_visible: retrievedAdditionalSupportLinksInfo.additionalLinks.length !== 0,
							 },
								retrievedAdditionalSupportLinksInfo.additionalLinks.map(function (additionalLink) {
									return $a({ className: 'HelpPanelTitle IconText noStyleLink', href: additionalLink.url, target: '_blank' }, [
										$svg(additionalLink.image),
										$h3(additionalLink.title),
									])
								})
							)
						]),
					]
				});
			}
			break;
	}
});

SC.event.addGlobalHandler(SC.event.PreRender, function (eventArgs) {
	if (SC.context.pageType == 'HostPage' || SC.context.pageType == 'AdministrationPage') {
		SC.util.includeStyleSheet(extensionContext.baseUrl + 'HelpStyle.css');

		if (SC.context.productVersion.split('.')[0] < 20 || (SC.context.productVersion.split('.')[0] == 20 && SC.context.productVersion.split('.')[1] < 2)) { // New Solid Theme uses TrayIconPanel to show help icon in 20.2
			if ($('link[href*="App_Themes"]').href.indexOf('Shell') == -1) {
				SC.ui.addContent(
					$('.NavigationPanel'),
					$div(
						{
							_commandName: 'ShowEnhancedHelp',
							className: 'EnhancedHelpButtonNavigationPanel',
						},
						[
							$img({ src: extensionContext.baseUrl + 'Icons/HelpIcon.svg' }),
							$span(SC.res['EnhancedHelp.ModalTitle.Text']),
						]
					)
				);
				SC.ui.moveNodeUp($('.EnhancedHelpButtonNavigationPanel'));
				SC.ui.moveNodeUp($('.EnhancedHelpButtonNavigationPanel'));
			}
		}
	}
});

});</script>
<script>SC.extension.addInitializeProc('13cde0ce-420d-410e-9ca2-053a5f237bb1', function (extensionContext) {
SC.event.addGlobalHandler(SC.event.QueryTabContainsRelativeTimes, function (eventArgs) {
	if (isDiagnosticsTab(eventArgs.tabName))
		eventArgs.hasRelativeTimes = true;
});

SC.event.addGlobalHandler(SC.event.PreRender, function (eventArgs) {
	if (SC.context.pageType === 'HostPage')
		SC.util.includeStyleSheet(extensionContext.baseUrl + 'RemoteDiagnosticsToolkit.css');
});

SC.event.addGlobalHandler(SC.event.QueryCommandButtonState, function (eventArgs) {
	if (isDiagnosticsTab(eventArgs.commandArgument)) {
		eventArgs.isEnabled = eventArgs.isVisible = eventArgs.commandContext.sessionType === SC.types.SessionType.Access &&
			eventArgs.commandContext &&
			eventArgs.commandContext.sessions &&
			eventArgs.commandContext.sessions.length === 1 &&
			(eventArgs.commandContext.permissions & SC.types.SessionPermissions.RunCommandOutside) > 0 &&
			(eventArgs.commandContext.permissions & SC.types.SessionPermissions.RemoveCommand) > 0 &&
			!(eventArgs.commandArgument === 'RemoteDiagnosticToolkit.Users' && !extensionContext.custom.ShowUsersTab);
	}
	
	if (eventArgs.commandName === 'ExecuteRemoteCommand' && !extensionContext.custom.CanSendCommands && !(eventArgs.commandArgument === 'RemoveAdmin' && extensionContext.custom.ShowUsersTab)) {
		eventArgs.isEnabled = false;
		eventArgs.commandElement.parentElement.onmouseenter = function () { SC.tooltip.showPanel(eventArgs.commandElement.parentElement, SC.res['DiagnosticsToolkit.LicenseRestrictionTooltipMessage.Text']); };
		eventArgs.commandElement.parentElement.onmouseleave = function () { SC.tooltip.hidePanel(); };
	}
});

SC.event.addGlobalHandler(SC.event.QueryCommandButtons, function (eventArgs) {
	switch (eventArgs.area) {
		case 'HostDetailTabList':
			Array.prototype.push.apply(eventArgs.buttonDefinitions,
				commandTabNameMap.map(function (it) {
					return { 
						commandName: 'Select', 
						commandArgument: it.tabName, 
						text: SC.res['DiagnosticsToolkit.' + it.commandName + 'Tab.Label'], 
						imageUrl: extensionContext.baseUrl + 'Images/Tab' + it.commandName + '.svg', 
						tooltipOrTitle: true, }; // tooltipOrTitle is no longer need after live-data branch got merged in, keep this here for backward compatibility
				})
			);
			break;
		case 'DownloadLatestDiagnosticEventData':
			eventArgs.buttonDefinitions.push(
				{ commandName: 'DownloadEventData', text: SC.res['DiagnosticsToolkit.DownloadData.Label'] }
			);
			break;
	}
});

SC.event.addGlobalHandler(SC.event.ExecuteCommand, function (eventArgs) {
	const dataItem = SC.util.combineObjects.apply(this, SC.command.getEventDataItems(eventArgs));
	switch (eventArgs.commandName) {
		case 'RefreshDiagnostics':
			if (isSessionGuestConnected(dataItem.session)) {
				executeRemoteCommand("Get" + dataItem.commandName, null, dataItem.session.GuestOperatingSystemName, dataItem.SessionID);
				setLoadingIndicator(true);
			}
			break;
		case 'ExecuteRemoteCommand':
			if (isSessionGuestConnected(dataItem.session)) {
				executeRemoteCommand(eventArgs.commandArgument, dataItem.itemData, dataItem.session.GuestOperatingSystemName, dataItem.SessionID);
				setLoadingIndicator(true);
				SC.css.ensureClass(SC.command.getEventDataElement(eventArgs), 'Loading', true);
			}
			break;
		case 'DownloadEventData':
			var dt = new Date();
			var link = $a({
				download: SC.util.formatString(SC.res['DiagnosticsToolkit.DownloadData.FileNameFormat'], dataItem.session.Name, dataItem.commandName, dt.toLocaleDateString(), dt.toLocaleTimeString()),
				href: 'data:text/plain,' + window.encodeURIComponent(dataItem.eventParseResult.rawContent),
			});
			document.body.appendChild(link);
			link.click();
			document.body.removeChild(link);
			break;
	}
});

SC.event.addGlobalHandler(SC.event.InitializeTab, function (eventArgs) {
	if (isDiagnosticsTab(eventArgs.tabName)) {
		SC.ui.setContents(eventArgs.container, [
			$div({ className: 'DiagnosticsHeader' }, [
				$h2(SC.res['DiagnosticsToolkit.' + getDiagnosticsTabCommandName(eventArgs.tabName) + 'Tab.Label']),
				$div({ className: 'LastUpdatePanel' }, [
					$span({ className: 'LastUpdateTime' }),
					SC.command.createCommandButtons([{ commandName: 'RefreshDiagnostics', text: SC.res['DiagnosticsToolkit.Refresh.Button'] }])
				]),
				$div({ className: 'FilterBoxPanel' },
					SC.ui.createFilterBox({ id: 'diagnosticsFilterBox' }, function () { applyFilter(eventArgs.container); }),
				),
			]),
			$div({ className: 'InformationDisplayContainer' },
				extensionContext.custom.CanSendCommands || (extensionContext.custom.ShowUsersTab && eventArgs.tabName === 'RemoteDiagnosticToolkit.Users')
					? null
					: $div({className: 'RDTLicenseRestrictionContainer'}, [
						$img({className: 'RDTShoppingBagIcon', src: extensionContext.baseUrl + 'Images/shopping-bag-icon.png'}),
						$p({_innerHTMLToBeSanitized: SC.res['DiagnosticsToolkit.LicenseRestrictionMessage.Text']})
					]),
				$div({ className: 'EmptyPanel' },
					getEmptyStateContents(eventArgs.tabName)
				),
				$table({ className: 'DataTable' })
			),
			$div({ className: 'DownloadButtonPanel' }, [
				$div({ className: 'DownloadDataButton' }, SC.command.queryAndCreateCommandButtons('DownloadLatestDiagnosticEventData'))
			])
		]);

		setLoadingIndicator(true);
	}
});

SC.event.addGlobalHandler(SC.event.RefreshTab, function (eventArgs) {
	if (isDiagnosticsTab(eventArgs.tabName)) {
		var isGuestConnected = isSessionGuestConnected(eventArgs.session);

		var tryDeleteEvents = function (eventCollection, eventType, shouldDeleteFunc) {
			if (eventCollection)
				eventCollection.forEach(function (item, i) {
					if (shouldDeleteFunc(item, i)) {
						SC.service.DeleteDiagnosticCommandEvents(
							eventArgs.session.SessionID,
							item.ConnectionID || null,
							item.EventID,
							eventType
						);
					}
				});
		};

		var getQueuedEvents = function (parseResultPredicate) {
			return eventArgs.sessionDetails.Events
				.filter(function (e) { return e.EventType === SC.types.SessionEventType.QueuedCommand; })
				.filter(function (e) { return parseResultPredicate(parseQueuedCommandEvent(e.Data)); })
				.sort(function (x, y) { return x.Time - y.Time; });
		};

		var diagnosticEventPredicate = function (it) { return it.isValid && it.headers.Command === "Get" + getDiagnosticsTabCommandName(eventArgs.tabName); };
		var invalidatingEventPredicate = function (it) { return it.isValid && it.headers && it.headers['InvalidatesCommand']; };

		var queuedDiagnosticEvents = getQueuedEvents(diagnosticEventPredicate);

		var latestQueuedDiagnosticEvent = queuedDiagnosticEvents.length > 0 ? queuedDiagnosticEvents[0] : null;

		var queuedInvalidatingEvents = getQueuedEvents(invalidatingEventPredicate);

		var latestQueuedInvalidatingEvent = queuedInvalidatingEvents.length > 0 ? queuedInvalidatingEvents[0] : null;

		var versionParts = SC.context.productVersion.split('.');

		if (versionParts && versionParts.length > 1) {
			var ranEvents;
			if (SC.util.isVersion({ major: 22, minor: 9 }, null, { major: versionParts[0], minor: versionParts[1] })) {
				ranEvents = eventArgs.sessionDetails.Events
					.filter(function (e) {
						if (e.ConnectionID !== null && e.EventType == SC.types.SessionEventType.RanCommand) {
							var parseResult = parseRanCommandEvent(e.Data, 1);
							return parseResult.isValid;
						}
	
						return false;
					});
			}
			else
			{
				ranEvents = eventArgs.sessionDetails.Connections
					.map(function (c) {
						Array.prototype.forEach.call(c.Events, function (e) {
							e.ConnectionID = c.ConnectionID;
						});
		
						return c.Events;
					})
					.reduce(function (outputArray, events) { Array.prototype.push.apply(outputArray, events); return outputArray; }, [])
					.filter(function (e) {
						if (e.EventType === SC.types.SessionEventType.RanCommand) {
							var parseResult = parseRanCommandEvent(e.Data, 1);
							return parseResult.isValid;
						}
		
						return false;
					});
			}
		}

		var getRanEvents = function (parseResultPredicate) {
			return ranEvents
				.filter(function (e) { return parseResultPredicate(parseRanCommandEvent(e.Data, 1)); })
				.sort(function (x, y) { return x.Time - y.Time; });
		};

		var ranDiagnosticEvents = getRanEvents(diagnosticEventPredicate);

		var latestRanDiagnosticEvent = ranDiagnosticEvents.length > 0 ? ranDiagnosticEvents[0] : null;

		var ranInvalidatingEvents = getRanEvents(invalidatingEventPredicate);

		var latestRanInvalidatingEvent = ranInvalidatingEvents.length > 0 ? ranInvalidatingEvents[0] : null;

		var latestRanDiagnosticEventParseResult = latestRanDiagnosticEvent ? parseRanCommandEvent(latestRanDiagnosticEvent.Data, 2) : null;

		var isParseResultValid = latestRanDiagnosticEventParseResult && latestRanDiagnosticEventParseResult.isValid;

		eventArgs.container._dataItem = {
			commandName: getDiagnosticsTabCommandName(eventArgs.tabName),
			event: latestRanDiagnosticEvent,
			session: eventArgs.session,
			eventParseResult: latestRanDiagnosticEventParseResult,
		};

		setLoadingIndicator(!latestRanDiagnosticEvent || latestQueuedDiagnosticEvent || latestRanInvalidatingEvent || latestQueuedInvalidatingEvent);

		var informationDisplayContainer = eventArgs.container.querySelector('.InformationDisplayContainer');
		SC.css.ensureClass(informationDisplayContainer, 'Empty', !latestRanDiagnosticEvent || !isParseResultValid);

		SC.ui.setVisible($('.FilterBoxPanel'), latestRanDiagnosticEvent && isParseResultValid);

		if (isGuestConnected
			&& (!latestQueuedDiagnosticEvent || latestQueuedDiagnosticEvent.Time > 45000)
			&& (!latestRanDiagnosticEvent
				|| (latestRanInvalidatingEvent && latestRanInvalidatingEvent.Time < latestRanDiagnosticEvent.Time)
				|| (latestRanDiagnosticEvent.Time > 300000)
			)
		) {
			executeRemoteCommand('Get' + getDiagnosticsTabCommandName(eventArgs.tabName), null, eventArgs.session.GuestOperatingSystemName, eventArgs.session.SessionID);
			setLoadingIndicator(true);
		}

		var ranCommandInfos = ranEvents
			.map(function (ranEvent) {
				return {
					time: ranEvent.Time,
					parseResult: parseRanCommandEvent(ranEvent.Data, 1),
				};
			})
			.filter(function (eventInfo) {
				return eventInfo.parseResult.isValid
					&& eventInfo.parseResult.headers
					&& eventInfo.parseResult.headers.Command
					&& eventInfo.parseResult.headers.CommandKey;
			})
			.map(function (eventInfo) {
				return {
					ranEventTime: eventInfo.time,
					command: eventInfo.parseResult.headers.Command,
					commandKey: eventInfo.parseResult.headers.CommandKey,
				};
			});

		var unshownCommandInfos = eventArgs.sessionDetails.Events
			.filter(function (it) { return it.EventType === SC.types.SessionEventType.QueuedCommand; })
			.map(function (queuedCommandEvent) {
				return {
					id: queuedCommandEvent.EventID,
					time: queuedCommandEvent.Time,
					parseResult: parseQueuedCommandEvent(queuedCommandEvent.Data),
				};
			})
			.filter(function (eventInfo) {
				return eventInfo.parseResult.isValid
					&& eventInfo.parseResult.headers
					&& eventInfo.parseResult.headers.Command
					&& eventInfo.parseResult.headers.CommandKey
					&& eventInfo.parseResult.headers.CommandKeyIndices;
			})
			.map(function (eventInfo) {
				return {
					queuedEventID: eventInfo.id,
					queuedEventTime: eventInfo.time,
					command: eventInfo.parseResult.headers.Command,
					commandKey: eventInfo.parseResult.headers.CommandKey,
					commandKeyIndices: eventInfo.parseResult.headers.CommandKeyIndices,
				};
			})
			.filter(function (commandInfo) {
				return !latestRanDiagnosticEvent
					|| latestRanDiagnosticEvent.Time >= commandInfo.queuedEventTime
					|| !ranCommandInfos.some(function (ranCommandInfo) {
						return ranCommandInfo.command === commandInfo.command
							&& ranCommandInfo.commandKey === commandInfo.commandKey
							&& ranCommandInfo.ranEventTime < commandInfo.queuedEventTime
							&& ranCommandInfo.ranEventTime >= latestRanDiagnosticEvent.Time;
					});
			});

		tryDeleteEvents(
			queuedDiagnosticEvents,
			SC.types.SessionEventType.QueuedCommand,
			function (queuedDiagnosticEvent, i) { return i > 0 || latestRanDiagnosticEvent && latestRanDiagnosticEvent.Time < queuedDiagnosticEvent.Time; }
		);

		tryDeleteEvents(
			queuedInvalidatingEvents,
			SC.types.SessionEventType.QueuedCommand,
			function (queuedInvalidatingEvent) {
				return !unshownCommandInfos.some(function (unshownCommandInfo) {
					return unshownCommandInfo.queuedEventID === queuedInvalidatingEvent.EventID;
				});
			}
		);

		tryDeleteEvents(
			ranInvalidatingEvents,
			SC.types.SessionEventType.RanCommand,
			function (ranInvalidatingEvent, i) {
				if (i == 0 && (!latestRanDiagnosticEvent || latestRanDiagnosticEvent.Time >= ranInvalidatingEvent.Time))
					return false;

				var ranInvalidatingEventParseResult = parseRanCommandEvent(ranInvalidatingEvent.Data, 1);

				return !ranInvalidatingEventParseResult.isValid
					|| !ranInvalidatingEventParseResult.headers
					|| !ranInvalidatingEventParseResult.headers.Command
					|| !ranInvalidatingEventParseResult.headers.CommandKey
					|| !unshownCommandInfos.some(function (unshownCommandInfo) {
						return unshownCommandInfo.command === ranInvalidatingEventParseResult.headers.Command
							&& unshownCommandInfo.commandKey === ranInvalidatingEventParseResult.headers.CommandKey
							&& unshownCommandInfo.queuedEventTime >= ranInvalidatingEvent.Time;
					});
			}
		);

		tryDeleteEvents(ranDiagnosticEvents, SC.types.SessionEventType.RanCommand, function (ranDiagnosticEvent, i) { return i > 0; });

		if (latestRanDiagnosticEvent && isParseResultValid) {
			eventArgs.container.querySelector('.LastUpdateTime').innerHTML = "Updated " + SC.util.formatSecondsDuration(latestRanDiagnosticEvent.Time / 1000) + " ago";
			var buttonDefinitions = getButtonDefinitions(latestRanDiagnosticEventParseResult);
			var unavailableCommandsColumnIndex = latestRanDiagnosticEventParseResult.columnNames.findIndex(c => c == 'UnavailableCommands');
			SC.css.ensureClass($('.InformationDisplayContainer .DataTable'), 'NoActionCellDataTable', buttonDefinitions.length === 0);

			if (latestRanDiagnosticEventParseResult.data) {
				var hiddenColumnIndices = latestRanDiagnosticEventParseResult.headers && latestRanDiagnosticEventParseResult.headers['HiddenColumnIndices']
					? latestRanDiagnosticEventParseResult.headers['HiddenColumnIndices'].split(',').map(function (index) { return +index; })
					: [];

				// It would have been ideal to do all the styling in the RemoteDiagnosticsToolkit.css
				// file. However, since we do not have access to the required variables, like
				// the $shade1BackgroundColor, whose value changes depending on the theme, over there,
				// we had to do the styling in JavaScript so that we can programmatically determine
				// their correct (theme-based) values.
				var desiredBackgroundColor = '';

				SC.ui.findAncestor(informationDisplayContainer, function (currentElement) {
					var defaultBackgroundColor = 'rgba(0, 0, 0, 0)';
					var currentElementBackgroundColor = window.getComputedStyle(currentElement).backgroundColor;

					if (currentElementBackgroundColor !== defaultBackgroundColor) {
						desiredBackgroundColor = currentElementBackgroundColor;
						return true;
					}

					return false;
				});

				informationDisplayContainer.style.background = SC.util.formatString(
					'linear-gradient({0} 70%, hsla(0, 0%, 100%, 0)), ' +
					'linear-gradient(hsla(0, 0%, 100%, 0) 10px, {0} 30%), ' +
					'radial-gradient(at top, rgba(0, 0, 0, 0.2), transparent 70%), ' +
					'radial-gradient(at bottom, rgba(0, 0, 0, 0.2), transparent 70%)',
					desiredBackgroundColor
				);
				informationDisplayContainer.style.backgroundRepeat = 'no-repeat';
				informationDisplayContainer.style.backgroundSize = '100% 50px, 100% 50px, 100% 10px, 100% 10px';
				informationDisplayContainer.style.backgroundPosition = 'left top, right bottom, left 0px top 23px, right bottom';
				informationDisplayContainer.style.backgroundAttachment = 'local, local, scroll, scroll';
				informationDisplayContainer.style.backgroundColor = desiredBackgroundColor;

				var tableHeaderCellCssText = SC.util.formatString('background-color: {0}; background-clip: padding-box; opacity: 1.0;', desiredBackgroundColor);

				SC.ui.setContents(eventArgs.container.querySelector('table'), [
					$tr(
						$th({ className: 'ActionCell HeaderCell', _cssText: tableHeaderCellCssText }),
						latestRanDiagnosticEventParseResult.columnNames
							.filter(function (it, index) { return !hiddenColumnIndices.some(function (hiddenIndex) { return hiddenIndex === index; }); })
							.map(function (columnName) { return $th({ className: 'HeaderCell', _cssText: tableHeaderCellCssText }, columnName); })
					),
					latestRanDiagnosticEventParseResult.data.map(function (itemData) {
						return $tr({
							_dataItem: { itemData: itemData },
							_classNameMap: {
								'Loading': unshownCommandInfos.some(function (unshownCommandInfo) {
									return unshownCommandInfo.commandKey
										=== unshownCommandInfo
											.commandKeyIndices
											.split(',')
											.map(function (index) { return itemData[+index]; })
											.join('');
								}),
							},
						}, [
							$td({ className: 'ActionCell' }, SC.command.createCommandButtons(filterUnavailableCommands(unavailableCommandsColumnIndex, itemData, buttonDefinitions))),
							itemData
								.filter(function (it, index) { return !hiddenColumnIndices.some(function (hiddenIndex) { return hiddenIndex === index; }); })
								.map(function (cellData) { return $td(cellData); }),
						]);
					}),
				]);
			}

			applyFilter(eventArgs.container);
		} else {
			SC.ui.setContents(
				eventArgs.container.querySelector('.EmptyPanel'),
				getEmptyStateContents(eventArgs.tabName, isGuestConnected, isParseResultValid)
			);

			if (!isGuestConnected)
				setLoadingIndicator(false);
		}
	}
});

var commandTabNameMap = ['Processes', 'Software', 'EventLog', 'Services', 'Updates', 'Users'].map(function (it) {
	return { commandName: it, tabName: 'RemoteDiagnosticToolkit.' + it };
});

function isDiagnosticsTab(tabName) {
	return commandTabNameMap.find(function (it) { return it.tabName === tabName; }) ? true : false;
}

function getDiagnosticsTabCommandName(tabName) {
	return commandTabNameMap.find(function (it) { return it.tabName === tabName; }).commandName;
}

function getEmptyStateContents(tabName, isGuestConnected = true, isParseResultValid = true) {
	var tabCommandName = getDiagnosticsTabCommandName(tabName);
	return [
		$p(
			$img({
				src: extensionContext.baseUrl + 'Images/' + tabCommandName + 'Empty.png',
			})
		),
		$h2({ innerHTML: getEmptyStateTitle(tabCommandName, isGuestConnected, isParseResultValid) }),
		$p({ innerHTML: getEmptyStateText(tabCommandName, isGuestConnected, isParseResultValid) })
	];
}

function getEmptyStateTitle(tabCommandName, isGuestConnected, isParseResultValid) {
	var tabLabel = SC.res['DiagnosticsToolkit.' + tabCommandName + 'Tab.Label'];

	return isGuestConnected && isParseResultValid
		? SC.util.formatString(
			'{0} {1}',
			tabLabel,
			SC.res["DiagnosticsToolkit.EmptyTab.TitleLoadingSuffix"]
		)
		: SC.util.formatString(
			'{0} {1} {2}',
			SC.res['DiagnosticsToolkit.EmptyTab.TitlePrefix'],
			tabLabel,
			SC.res['DiagnosticsToolkit.EmptyTab.TitleSuffix']
		);
}

function getEmptyStateText(tabCommandName, isGuestConnected, isParseResultValid) {
	if (isGuestConnected) {
		return isParseResultValid
			? SC.util.formatString(SC.res['DiagnosticsToolkit.EmptyTab.TextFormat'], SC.res['DiagnosticsToolkit.' + tabCommandName + 'Tab.Label'])
			: SC.res['DiagnosticsToolkit.EmptyTab.ParseErrorText'];
	} else {
		return SC.res['DiagnosticsToolkit.EmptyTab.GuestNotConnectedText'];
	}
}

function isSessionGuestConnected(session) {
	return session && session.ActiveConnections && session.ActiveConnections.length > 0 ?
		session.ActiveConnections.some(function (it) { return it.ProcessType === SC.types.ProcessType.Guest; }) :
		false;
}

function applyFilter(container) {
	var valueUpper = container.querySelector("input").value.toUpperCase();
	var table = container.querySelector("table");
	Array.from(table.children).forEach((it, index) => SC.ui.setVisible(it, index === 0 || it.innerHTML.toUpperCase().includes(valueUpper)));
}

function setLoadingIndicator(addOrRemove) {
	var element = $('.LastUpdatePanel a');

	if (element)
		SC.css.ensureClass(element, 'LoadingIndicatorRight', addOrRemove);
}

function getButtonDefinitions(parseResult) {

	var availableCommands = parseResult.headers && parseResult.headers['AvailableCommands']
		? parseResult.headers['AvailableCommands'].split(',')
		: [];

	var buttonDefinitions = Array();

	if (availableCommands && availableCommands.length > 0) {
		for (var i = 0; i < availableCommands.length; i++)
			buttonDefinitions.push({
				commandName: 'ExecuteRemoteCommand',
				commandArgument: availableCommands[i],
				text: SC.res['DiagnosticsToolkit.MachineInteraction.' + availableCommands[i]],
			});
	}

	return buttonDefinitions;
}

function filterUnavailableCommands(unavailableCommandsColumnIndex, itemData, buttonDefinitions) {
	var filteredButtonDefinitions = buttonDefinitions;
	if (itemData[unavailableCommandsColumnIndex] && itemData[unavailableCommandsColumnIndex] != '')
		filteredButtonDefinitions = buttonDefinitions.filter(function (buttonDefinition) {
			return !itemData[unavailableCommandsColumnIndex].includes('|' + buttonDefinition.commandArgument + '|');
		});
	return filteredButtonDefinitions;
}

function executeRemoteCommand(remoteCommandName, itemData, operatingSystemName, sessionID) {
	var osType = operatingSystemName.indexOf("Windows") >= 0 || operatingSystemName.indexOf("Server") >= 0 ? "Windows"
		: operatingSystemName.indexOf("Linux") >= 0 ? "Linux"
			: operatingSystemName.indexOf("Mac") >= 0 ? "OSX"
				: "Unknown";

	var commandInfo = getCommandInfo(remoteCommandName, itemData, osType);

	var emptyLinePrefix, delimiter, modifier;

	if (commandInfo.processor === 'sh') {
		modifier = "echo ";
		delimiter = '';
		emptyLinePrefix = 'echo ';
	} else {
		modifier = "echo \"";
		delimiter = '\"';
		emptyLinePrefix = 'echo ""';
	}

	var eventData = "#!" + commandInfo.processor + "\n" +
		"#maxlength=50000000" + "\n" +
		"#timeout=900000" + "\n" +
		"#DIAGNOSTIC-REQUEST/2" + "\n" +
		"#Command: " + remoteCommandName + "\n" +
		"#CommandKeyIndices: " + (commandInfo.commandKeyIndices ? commandInfo.commandKeyIndices.join(',') : "") + "\n" +
		"#CommandKey: " + (commandInfo.commandKey || "") + "\n" +
		"#AvailableCommands: " + "\n" +
		"#InvalidatesCommand: " + (commandInfo.invalidatesCommand || "") + "\n" +
		"#HiddenColumnIndices: " + "\n" +
		modifier + "DIAGNOSTIC-RESPONSE/2" + delimiter + "\n" +
		modifier + "Command: " + remoteCommandName + delimiter + "\n" +
		modifier + "CommandKeyIndices: " + (commandInfo.commandKeyIndices ? commandInfo.commandKeyIndices.join(',') : "") + delimiter + "\n" +
		modifier + "CommandKey: " + (commandInfo.commandKey || "") + delimiter + "\n" +
		modifier + "ContentType: " + commandInfo.contentType + delimiter + "\n" +
		modifier + "AvailableCommands: " + (commandInfo.availableCommands ? commandInfo.availableCommands.join(",") : "") + delimiter + "\n" +
		modifier + "InvalidatesCommand: " + (commandInfo.invalidatesCommand ? commandInfo.invalidatesCommand : "") + delimiter + '\n' +
		modifier + "HiddenColumnIndices: " + (commandInfo.hiddenColumnIndices ? commandInfo.hiddenColumnIndices.join(',') : "") + delimiter + '\n' +
		emptyLinePrefix + "\n" + commandInfo.commandText;
	
	SC.service.AddDiagnosticEventToSession(sessionID, eventData);
}

function parseQueuedCommandEvent(content) {
	var parseResult = {
		isValid: content.startsWith("#!") && content.indexOf("DIAGNOSTIC-REQUEST/2") !== -1,
	};

	if (parseResult.isValid) {
		parseResult.headers = {};

		forEachTrimmedLine(content, function (line) {
			if (line.startsWith('#')) {
				var lineParts = line.substring(1).split(':');

				if (lineParts.length > 1)
					parseResult.headers[lineParts[0].trim()] = lineParts[1] ? lineParts[1].trim() : '';
			}
		});
	}

	return parseResult;
}

function parseRanCommandEvent(content, parseLevel) {
	var parseResult = {
		isValid: content.startsWith("DIAGNOSTIC-RESPONSE/2"), // don't bother with that bug BOM
	};

	if (parseResult.isValid && parseLevel >= 1) {
		parseResult.headers = {};

		var contentStartCharIndex = forEachTrimmedLine(content, function (line, lineIndex) {
			if (line === '') {
				return true;
			} else if (lineIndex >= 1) { // ignore status line
				var lineParts = line.split(':');
				parseResult.headers[lineParts[0].trim()] = lineParts[1] ? lineParts[1].trim() : '';
			}
		});

		if (parseLevel >= 2) {
			parseResult.rawContent = content.substring(contentStartCharIndex);

			if (parseResult.headers.ContentType === 'xml') {
				var document = getXmlDocument(parseResult.rawContent);

				if (document) {
					var objectElements = document.getElementsByTagName("Object");
					if (objectElements[0]) {
						parseResult.columnNames = Array.from(objectElements[0].children).map(function (columnElement) { return columnElement.attributes['Name'].value; });
						parseResult.data = Array.from(objectElements).map(function (objectElement) { return Array.from(objectElement.children).map(function (columnElement) { return columnElement.innerHTML; }); });
					} else {
						parseResult.isValid = false;
					}
				}
			} else if (parseResult.headers.ContentType === 'text') {
				forEachTrimmedLine(parseResult.rawContent, function (line, lineIndex) {
					var values = line.split(',').map(function (it) { return it.trim(); });

					if (lineIndex === 0) {
						parseResult.columnNames = values;
					} else {
						if (lineIndex === 1)
							parseResult.data = [];

						parseResult.data.push(values);
					}
				});
			}
		}
	}

	return parseResult;
}

function forEachTrimmedLine(text, doLineUntilFunc) {
	var currentCharIndex = 0;
	var lineIndex = 0;

	while (true) {
		var nextNewLineCharIndex = text.indexOf('\n', currentCharIndex);

		if (nextNewLineCharIndex === -1)
			break;

		var line = text.substring(currentCharIndex, nextNewLineCharIndex).trim(); // trim \r among other things

		currentCharIndex = nextNewLineCharIndex + 1;

		if (doLineUntilFunc(line, lineIndex++))
			break;
	}

	return currentCharIndex;
}

function getXmlDocument(xmlText) {
	if (window.DOMParser) {
		try {
			return (new DOMParser()).parseFromString(xmlText, "text/xml");
		}
		catch (e) { }
	}

	if (!document && window.ActiveXObject) {
		try {
			var document = new ActiveXObject('Microsoft.XMLDOM');
			document.async = false;
			if (!document.loadXML(xmlText))
				throw "malformed xml";
			return document;
		}
		catch (e) { }
	}
}

function quoteForPowerShell(string) {
	var escapedItemData = string.replaceAll("'", "''");
	return "'" + escapedItemData + "'";
}

function parseMsiExecuteCommand(uninstallString, identifyingNumber) {
	var expression = new RegExp("\\/[XxIi][ ]*" + identifyingNumber, '');
	return uninstallString.replace(expression, '/x "' + identifyingNumber + '" /q');
}

function getCommandInfo(remoteCommandName, itemData, osType) {
	var getCommandTextForLinuxDistributionBasedExecution = function (commandTextForRedHatDistributions, commandTextForDebianDistributions) {
		return SC.util.formatString(
			"if which rpm >/dev/null 2>&1; then {0}; elif which dpkg >/dev/null 2>&1; then {1}; fi",
			commandTextForRedHatDistributions,
			commandTextForDebianDistributions
		);
	}

	switch (remoteCommandName + '/' + osType) {
		case "GetProcesses/Windows": return { processor: 'ps', contentType: 'xml', hiddenColumnIndices: [], availableCommands: ['KillProcess'], commandText: "$Ram = Get-WMIObject Win32_PhysicalMemory | Measure -Property Capacity -Sum | %{$_.Sum}; Get-Process | Select @{N='ID';E={$_.Id}}, @{N='Process Name';E={$_.ProcessName}}, @{N='Memory (%)';E={[string]::Format(\"{0:p}\", $_.WorkingSet64/$Ram)}}, @{N='Memory (KB)';E={[string]::Format(\"{0:N0}\", $_.WorkingSet64/1024)}}, WS | Sort -Descending WS | Select 'ID', 'Process Name', 'Memory (%)', 'Memory (KB)' | ConvertTo-Xml -As Stream" };
		case "GetEventLog/Windows": return { processor: 'ps', contentType: 'xml', hiddenColumnIndices: [], availableCommands: [], commandText: SC.util.formatString("Get-EventLog Application -newest {0} | Select @{N='Time Written';E={$_.TimeWritten}}, @{N='Entry Type';E={$_.EntryType}}, @{N='Source';E={$_.Source}}, @{N='Event ID';E={$_.EventID}}, @{N='Message';E={$_.Message}} | Sort 'Time Written' -Descending | ConvertTo-Xml -As Stream | ForEach-Object { $_ -replace '>\\s+<', '><' }", SC.util.getBoundedValue(1, extensionContext.settingValues.EventLogRequestCount, 500)) };
		case "GetServices/Windows": return { processor: 'ps', contentType: 'xml', hiddenColumnIndices: [], availableCommands: ['StopService', 'StartService', 'RestartService'], commandText: "Get-Service | Select  @{N='Name';E={$_.Name}}, @{N='Display Name';E={$_.DisplayName}}, @{N='Status';E={$_.Status}}, @{N='Startup Type';E={$_.StartType}} | Sort 'Display Name' | ConvertTo-Xml -As Stream" };
		case "GetSoftware/Windows": return { processor: 'ps', contentType: 'xml', hiddenColumnIndices: [0, 4, 6], availableCommands: ['UninstallSoftware'], commandText: "$registryPath = if ([Environment]::Is64BitOperatingSystem) { 'HKLM:\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*', 'HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*' } else { 'HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*' } Get-ItemProperty $registryPath | Where-Object{![string]::IsNullOrEmpty($_.DisplayName)} | Select @{N='IdentifyingNumber';E={$_.PSChildName}}, @{N='Name';E={$_.DisplayName}}, @{N='Vendor';E={$_.Publisher}}, @{N='Version';E={$_.DisplayVersion}}, @{N='UninstallString';E={$_.UninstallString}}, @{N='Install Date';E={If ($_.InstallDate) { [datetime]::ParseExact($_.InstallDate, 'yyyyMMdd', $null).ToString('yyyy-MM-dd') } Else { $null }}}, @{N='UnavailableCommands';E={$(If (![string]::IsNullOrEmpty($_.UninstallString) -and $_.UninstallString.ToLower() -like 'msiexec*') {''} Else {'|UninstallSoftware|'})}} | Sort 'Name' | ConvertTo-Xml -As Stream" };
		case "GetUpdates/Windows": return { processor: 'ps', contentType: 'xml', hiddenColumnIndices: [0], availableCommands: ['InstallUpdate'], commandText: "$UpdateSession = New-Object -ComObject Microsoft.Update.Session" + "\n" + "$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()" + "\n" + "$Updates = @($UpdateSearcher.Search(\"IsHidden=0\").Updates)" + "\n" + "$Updates | Where-Object { !$_.IsInstalled } | Select-Object @{N='UpdateID';E={$_.Identity.UpdateID}}, @{N='Title';E={$_.Title}}, @{N='Downloaded';E={$_.IsDownloaded}}, @{N='Installed';E={$_.IsInstalled}}, @{N='Date Published'; E={[string]::Format(\"{0:d}\", $_.LastDeploymentChangeTime)}} | ConvertTo-Xml -As Stream" };
		case "GetUsers/Windows" : return { processor: 'ps', contentType: 'xml', hiddenColumnIndices: [4], availableCommands: ['RemoveAdmin'], commandText: "$users = @{}; Get-WmiObject Win32_UserAccount -Filter \"LocalAccount=True\" | % {$enabled = if ($_.Disabled) {\"False\"} else {\"True\"}; $camUser = if ($_.Description -eq \"[EPHEMERAL_USER_DO_NOT_REMOVE_THIS_UNLESS_DESIRED_PERMANENT]\") {$true} else {$false}; $objectProperties = @{Name = $_.Name; Domain = \"Local\"; Groups = @(); GroupString = \"\"; Enabled = $enabled; CamUser = $camUser}; $newUser = New-Object PSObject -Property $objectProperties; $users.Add($_.Name, $newUser)}; Get-WmiObject Win32_Group -Filter \"LocalAccount=True\" | % {$query = \"GroupComponent=`\"Win32_Group.Domain='$($_.Domain)',Name='$($_.Name)'`\"\"; $groupusers = Get-WmiObject Win32_GroupUser -Filter $query | select GroupComponent, PartComponent | Where-Object { $_.PartComponent -like \"*Win32_UserAccount*\" }; foreach ($groupuser in $groupusers) {$name = \"\"; $domain = \"\"; $enabled = \"N/A\"; if ($groupuser.PartComponent -match 'Name=\"([^\"]+)\"') {$name = $matches[1]} if ($groupuser.PartComponent -match 'Domain=\"([^\"]+)\"') {if ($matches[1] -ceq $env:COMPUTERNAME) {$domain = \"Local\"; $enabled = \"False\"} else {$domain = $matches[1]}} if($users.ContainsKey($name)) {$users[$name].Groups += $_.Name; if ($users[$name].Groups.Length -eq 1) {$users[$name].GroupString += $_.Name} else {$users[$name].GroupString += \", \" + $_.Name}} else {$objectProperties = @{Name   = $name; Domain = $domain; Groups = @($_.Name); GroupString = \"\" + $_.Name; Enabled = $enabled; CamUser = $false}; $newUser = New-Object PSObject -Property $objectProperties; $users.Add($name, $newUser)}}}; Get-WmiObject Win32_UserProfile | % {$userProfile = \"\"; if ($_.LocalPath -match 'Users\\\\(.+)') {$userProfile = $matches[1]; if (-not $users.ContainsKey($userProfile)) {$objectProperties = @{Name = $userProfile; Domain = \"-\"; Groups = @(); GroupString = \"-\"; Enabled = \"N/A\"; CamUser = $false}; $newUser = New-Object PSObject -Property $objectProperties; $users.Add($userProfile, $newUser)}}}; $disabledUsers = $users.Values | Where { $_.Enabled -eq \"False\" } | Sort -Property Name; $otherUsers = $users.Values | Where { $_.Enabled -ne \"False\" } | Sort -Property Name; $combinedUsers = @($otherUsers) + @($disabledUsers); $combinedUsers | Where {-not $_.CamUser} | Select @{N='Name';E={$_.Name}}, @{N='Domain';E={$_.Domain}}, @{N='Local Groups';E={$_.GroupString}}, @{N='Enabled';E={$_.Enabled}}, @{N='UnavailableCommands';E={$(If ($_.Groups -contains \"Administrators\") {''} Else {'|RemoveAdmin|'})}} | ConvertTo-Xml -As Stream"};

		case "GetProcesses/Linux": return { processor: 'sh', contentType: 'text', hiddenColumnIndices: [], availableCommands: ['KillProcess'], commandText: "ps -eo \"user,pid,time,pcpu,pmem,comm\" --sort -pmem | awk \'{print $1,\",\"$2,\",\"$3,\",\"$4,\",\"$5,\",\"$6 }\'" };
		case "GetEventLog/Linux": return { processor: 'sh', contentType: 'text', hiddenColumnIndices: [], availableCommands: [], commandText: SC.util.formatString("echo Event Log Entry ; dmesg -T | tail -{0}", SC.util.getBoundedValue(1, extensionContext.settingValues.EventLogRequestCount, 500)) };
		case "GetServices/Linux": return { processor: 'sh', contentType: 'text', hiddenColumnIndices: [], availableCommands: ['StopService', 'StartService', 'RestartService'], commandText: "echo Service Name ; ls /etc/init.d" };
		case "GetSoftware/Linux": return { processor: 'sh', contentType: 'text', hiddenColumnIndices: [], availableCommands: ['UninstallSoftware'], commandText: SC.util.formatString("echo Application Name ; {0}", getCommandTextForLinuxDistributionBasedExecution("rpm --query --all --queryformat \"%{NAME}\\n\"", "dpkg --get-selections | awk '$2 == \"install\" { print $1 }'")) };

		case "GetProcesses/OSX": return { processor: 'sh', contentType: 'text', hiddenColumnIndices: [], availableCommands: ['KillProcess'], commandText: "ps -eo \"user,pid,time,pcpu,pmem,comm\" -m | awk \'{print $1,\",\"$2,\",\"$3,\",\"$4,\",\"$5,\",\"$6 }\'" };
		case "GetEventLog/OSX": return { processor: 'sh', contentType: 'text', hiddenColumnIndices: [], availableCommands: [], commandText: SC.util.formatString("echo Event Log Entry ; log show --style syslog -last 500 | tail -n {0}", SC.util.getBoundedValue(1, extensionContext.settingValues.EventLogRequestCount, 500)) };
		case "GetServices/OSX": return {
			processor: 'sh', contentType: 'text', hiddenColumnIndices: [1], availableCommands: ['StartService', 'RestartService'],
			commandText: "headersText=$(echo \"Service Name\\t,Owner\";) && systemServices=$(ls /Library/LaunchDaemons | sed 's/\\.plist$//' | sed 's|$|\\t,system|') && userServices=$(ls /Library/LaunchAgents | sed 's/\\.plist$//' | sed 's|$|\\t,user|') && userId=$(stat -f '%u' /dev/console | grep -vx 0); if [[ $userId -ne 0 ]]; then" + "\n" +
				"	echo \"$headersText\"; echo \"$systemServices\"; echo \"$userServices\";" + "\n" +
				"else" + "\n" +
				"	echo \"$headersText\"; echo \"$systemServices\";" + "\n" +
				"fi",
		};
		case "GetSoftware/OSX": return { processor: 'sh', contentType: 'text', hiddenColumnIndices: [], availableCommands: [], commandText: "echo Application Name; ls /Applications" };

		case "KillProcess/Linux": return { processor: 'sh', invalidatesCommand: 'GetProcesses', commandKeyIndices: [1], commandKey: itemData[1], commandText: SC.util.formatString("kill {0}", typeof itemData[1] == 'string' ? quoteForPowerShell(itemData[1]) : '') };
		case "KillProcess/OSX": return { processor: 'sh', invalidatesCommand: 'GetProcesses', commandKeyIndices: [1], commandKey: itemData[1], commandText: SC.util.formatString("kill {0}", typeof itemData[1] == 'string' ? quoteForPowerShell(itemData[1]) : '') };
		case "KillProcess/Windows": return { processor: 'ps', invalidatesCommand: 'GetProcesses', commandKeyIndices: [0], commandKey: itemData[0], commandText: SC.util.formatString("Stop-Process {0} -ErrorAction SilentlyContinue -Force", typeof itemData[0] == 'string' ? quoteForPowerShell(itemData[0]) : '') };
		case "UninstallSoftware/Windows": return { processor: 'ps', invalidatesCommand: 'GetSoftware', commandKeyIndices: [0], commandKey: itemData[0], commandText: itemData[4].toLowerCase().startsWith("msiexec") ? SC.util.formatString(parseMsiExecuteCommand(itemData[4], itemData[0])) : SC.util.formatString("echo '{0}'", itemData[1]) };
		case "StopService/Windows": return { processor: 'ps', invalidatesCommand: 'GetServices', commandKeyIndices: [0], commandKey: itemData[0], commandText: SC.util.formatString("Stop-Service {0}", typeof itemData[0] == 'string' ? quoteForPowerShell(itemData[0]) : '') };
		case "StartService/Windows": return { processor: 'ps', invalidatesCommand: 'GetServices', commandKeyIndices: [0], commandKey: itemData[0], commandText: SC.util.formatString("Start-Service {0}", typeof itemData[0] == 'string' ? quoteForPowerShell(itemData[0]) : '') };
		case "RestartService/Windows": return { processor: 'ps', invalidatesCommand: 'GetServices', commandKeyIndices: [0], commandKey: itemData[0], commandText: SC.util.formatString("Restart-Service {0}", typeof itemData[0] == 'string' ? quoteForPowerShell(itemData[0]) : '') };
		case "InstallUpdate/Windows": return {
			processor: 'ps',
			invalidatesCommand: 'GetUpdates',
			commandKeyIndices: [0],
			commandKey: itemData[0],
			commandText:
				"$session = New-Object -ComObject \"Microsoft.Update.Session\"" + "\n" +
				"$searcher = $session.CreateUpdateSearcher()" + "\n" +
				SC.util.formatString("$search = \"(UpdateID = {0})\"", typeof itemData[0] == 'string' ? quoteForPowerShell(itemData[0]) : '') + "\n" +
				"$updateResult = $searcher.Search($search)" + "\n" +
				"$downloader = $session.CreateUpdateDownloader()" + "\n" +
				"$installer = $session.CreateUpdateInstaller()" + "\n" +
				"$downloader.Updates = $updateResult.Updates" + "\n" +
				"$installer.Updates = $updateResult.Updates" + "\n" +
				"$result = ''" + "\n" +
				"Try{ $result = $downloader.Download() } Catch{ If($_ -match \"HRESULT: 0x80240044\") { $result = \"Insufficient permissions. Could not install updates under this identity.\" }}" + "\n" +
				"Try{ $result = $installer.Install() } Catch{ If($_ -match \"HRESULT: 0x80240044\") { $result = \"Insufficient permissions. Could not install updates under this identity.\" }}" + "\n" +
				"$result"
		};
		case "RemoveAdmin/Windows": return { processor: 'ps', invalidatesCommand: 'GetUsers', commandKeyIndices: [0], commandKey: itemData[0], commandText:  SC.util.formatString("Remove-LocalGroupMember -Group \"Administrators\" -Member {0}", quoteForPowerShell(itemData[0])) }

		case "StopService/Linux": return { processor: 'sh', invalidatesCommand: 'GetServices', commandKeyIndices: [0], commandKey: itemData[0], commandText: SC.util.formatString("/etc/init.d/{0} stop", itemData[0]) };
		case "StartService/Linux": return { processor: 'sh', invalidatesCommand: 'GetServices', commandKeyIndices: [0], commandKey: itemData[0], commandText: SC.util.formatString("/etc/init.d/{0} start", itemData[0]) };
		case "RestartService/Linux": return { processor: 'sh', invalidatesCommand: 'GetServices', commandKeyIndices: [0], commandKey: itemData[0], commandText: SC.util.formatString("/etc/init.d/{0} restart", itemData[0]) };
		case "UninstallSoftware/Linux": return { processor: 'sh', invalidatesCommand: 'GetSoftware', commandKeyIndices: [0], commandKey: itemData[0], commandText: getCommandTextForLinuxDistributionBasedExecution(SC.util.formatString("rpm --erase {0}", itemData[0]), SC.util.formatString("dpkg --remove {0}", itemData[0])) };

		case "StartService/OSX":
		case "RestartService/OSX": return { processor: 'sh', invalidatesCommand: 'GetServices', commandKeyIndices: [1, 0], commandKey: '' + itemData[1] + itemData[0], commandText: SC.util.formatString("launchctl kickstart " + (remoteCommandName == "RestartService" ? "-k " : "") + "{0}/{1}", itemData[1] == "system" ? "system" : "gui/$(stat -f '%u' /dev/console | grep -vx 0)", itemData[0]) };

		default: throw "unhandled commandName/osType combination";
	}
}

});</script>
<script>SC.extension.addInitializeProc('4bfb0c0d-b7a0-4911-b76e-df1d86fa88cd', function (extensionContext) {
// If Report Generator extension is enabled, add help link to extension options dropdown

var reportGeneratorExtensionId = extensionContext.baseUrl.split("/").slice(-2)[0];
var reportManagerHelpLink = "https://docs.connectwise.com/ConnectWise_Control_Documentation/Supported_extensions/Administration/Report_Manager";

SC.event.addGlobalHandler(SC.event.PreRender, function (eventArgs) {
	SC.util.includeStyleSheet(extensionContext.baseUrl + 'Style.css');
});

SC.event.addGlobalHandler(SC.event.QueryCommandButtonState, function (eventArgs) {
	if (eventArgs.commandName == 'EditExtensionSettings')
		if (eventArgs.commandContext.extensionInfo.ExtensionID == reportGeneratorExtensionId && eventArgs.commandElement._commandName == "EditExtensionSettings")
			SC.ui.addElement(
				eventArgs.target.parentElement,
				"A",
				{ href: "#", _commandName: 'ShowHelpLink_' + reportGeneratorExtensionId, innerHTML: 'Help' }
			);
});

SC.event.addGlobalHandler(SC.event.ExecuteCommand, function (eventArgs) {
	if (eventArgs.commandName == 'ShowHelpLink_' + reportGeneratorExtensionId)
		window.open(reportManagerHelpLink, '_blank');
});
});</script>
<script>SC.extension.addInitializeProc('8fabf97d-7b08-481b-ab06-3f501436e864', function (extensionContext) {
// If Report Manager extension is enabled, add help link to extension options dropdown

var reportManagerExtensionId = extensionContext.baseUrl.split("/").slice(-2)[0];
var reportManagerHelpLink = "https://help.screenconnect.com/Extension:Report_Manager";
var currentVersion = {major : Number(SC.context.productVersion.split(".")[0]), minor : Number(SC.context.productVersion.split(".")[1])}

SC.event.addGlobalHandler(SC.event.QueryCommandButtonState, function (eventArgs) {
	if (eventArgs.commandName == 'EditExtensionSettings')
		if (eventArgs.commandContext.extensionInfo.ExtensionID == reportManagerExtensionId && eventArgs.commandElement._commandName == "EditExtensionSettings")
			SC.ui.addElement(
				eventArgs.target.parentElement,
				"A",
				{ href: "#", _commandName: 'ShowHelpLink_' + reportManagerExtensionId, innerHTML: 'Help' }
			);
});

SC.event.addGlobalHandler(SC.event.ExecuteCommand, function (eventArgs) {
	if (eventArgs.commandName == 'ShowHelpLink_' + reportManagerExtensionId)
		window.open(reportManagerHelpLink, '_blank');
});

var ReportManagerMetaTables= {}

var getMetaTableFromReportManagerMetaTables = function(reportType) {
	if (!(reportType in ReportManagerMetaTables)) {
		ReportManagerMetaTables[reportType] = { Items: [] }
	}
	return ReportManagerMetaTables[reportType]
}

var httpGetReportAsync = function (theUrl) {
	return new Promise((resolve, reject) => {
		var xmlHttp = new XMLHttpRequest();
		xmlHttp.onreadystatechange = function () {
			if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {
				resolve(JSON.parse(xmlHttp.responseText));
			} else if (xmlHttp.readyState === 4) {
				console.log('Metaquery failed');
			}
		};
		xmlHttp.open("GET", theUrl, true);
		xmlHttp.send();
	});
};

var editReportProc = function () {
	var i;

	httpGetReportAsync(SC.context.scriptBaseUrl + 'Report.json')
		.then(sessionMetadataResponse => {
			if (getMetaTableFromReportManagerMetaTables('Session').Items.length === 0) {
				for (i = 0; i < sessionMetadataResponse.Items.length; i++) {
					if (SC.util.isVersion({'major': 22, minor: 9}, null, currentVersion)) {
							getMetaTableFromReportManagerMetaTables(sessionMetadataResponse.Items[i][0]).Items.push(sessionMetadataResponse.Items[i]);
					} else if (sessionMetadataResponse.Items[i][0] != 'SessionConnectionEvent') {
						getMetaTableFromReportManagerMetaTables(sessionMetadataResponse.Items[i][0]).Items.push(sessionMetadataResponse.Items[i]);
					}
				}
			}
			return httpGetReportAsync(SC.context.scriptBaseUrl + 'Report.json?Report=Security');
		})
		.then(securityMetadataResponse => {
			if (getMetaTableFromReportManagerMetaTables('SecurityEvent').Items.length === 0) {
				for (i = 0; i < securityMetadataResponse.Items.length; i++) {
					getMetaTableFromReportManagerMetaTables('SecurityEvent').Items.push(securityMetadataResponse.Items[i]);
				}
			}

			SC.util.includeStyleSheet(extensionContext.baseUrl + 'Style.css');
			var ReportDownloadBuilderSelectionPanel;
			SC.dialog.showModalDialogRaw('ReportDownloadBuilder',
				[
					SC.dialog.createTitlePanel(SC.res['ReportDownloadBuilder.Title']),
					$div(
						$div({ className: 'CommandPanel' }, [
							SC.command.queryAndCreateCommandButtons('ReportDownloadBuilderEditorPanel'),
						])
					),
					$div(
						$div({ className: 'MasterPanel' },
							ReportDownloadBuilderSelectionPanel = $div({ id: 'ReportDownloadBuilderSelectionPanel', className: 'MasterSelectionPanel' })
						),
						$div({ id: 'ReportDownloadBuilderEditorPanel', className: 'DetailPanel' })
					)
				],
				null,
				null,
				null
			);

			SC.service.GetReportDefinitionStrings(function (reports) {
				if (reports[0] !== '') {
					var parsedReportString;
					for (i = 0; i < reports.length - 1; i++) {
						parsedReportString = reports[i].split('?'); // [report name, report definition]
						addReportFileProc(decodeURIComponent(parsedReportString[0]), null, false, true, '?' + parsedReportString[1]);
						loadReportFileProc(decodeURIComponent(parsedReportString[0]), parsedReportString[1]);
					}
					tryEditReportFileProc(ReportDownloadBuilderSelectionPanel.childNodes[0]._commandArgument);

				} else {
					updateReportViewProc();
				}
			});
		});
};

var addReportFileProc = function (reportName, reportLoadFileName, isDirty, validReport, definition) {
	var i = 0;
	// maintain lexical order
	if ($('ReportDownloadBuilderSelectionPanel').childNodes.length > 0) {
		for (var j = 0; j < $('ReportDownloadBuilderSelectionPanel').childNodes.length; j++) {
			if (reportName.toLowerCase() > $('ReportDownloadBuilderSelectionPanel').childNodes[j]._commandArgument.toLowerCase()) {
				i++;
			} else {
				break;
			}
		}
	}
	SC.ui.insertChild($('ReportDownloadBuilderSelectionPanel'), createReportSelectionLinkFunc(reportName), i);
	SC.ui.insertChild($('ReportDownloadBuilderEditorPanel'), createReportEditPanelFunc(reportName, reportLoadFileName, isDirty, validReport, definition), i);

	updateReportViewProc();
};


var loadReportFileProc = function (reportName, reportDefinition) {

	var i;
	if (reportDefinition === '') {
		$('report' + reportName)._validReport = false;
		$('groupFields' + reportName).childNodes.length === 2 ? SC.ui.removeChildAt($('groupFields' + reportName), 1) : null;
		$('selectFields' + reportName).childNodes.length === 2 ? SC.ui.removeChildAt($('selectFields' + reportName), 1) : null;
		$('reportDefinitionContent' + reportName).style.display = 'none';
		$('groupFields' + reportName).style.display = 'none';
		$('aggregateFilterDiv' + reportName).style.display = 'none';
		updateReportViewProc();
	} else if (reportDefinition.split('&')[0].split('=')[0] === 'InvalidGrouped') {
		$('report' + reportName)._validReport = false;
		$('groupFields' + reportName).childNodes.length === 2 ? SC.ui.removeChildAt($('groupFields' + reportName), 1) : null;
		$('selectFields' + reportName).childNodes.length === 2 ? SC.ui.removeChildAt($('selectFields' + reportName), 1) : null;
		$('reportDefinitionContent' + reportName).style.display = 'block';
		$('groupFields' + reportName).style.display = 'none';
		$('aggregateFilterDiv' + reportName).style.display = 'none';
		$('filter' + reportName).value = '';
		$('aggregateFilter' + reportName).value = '';

		var parsedDefinition = reportDefinition.split('&');
		if (parsedDefinition[1].search('ReportType') !== -1) {
			var reportType = parsedDefinition[1].split('=')[1];
			for (i = 0; i < $('reportType' + reportName).length; i++) {
				if ($('reportType' + reportName).options[i].value === reportType) {
					$('reportType' + reportName).selectedIndex = i;
					break;
				}
			}
			$('filterExample' + reportName).innerHTML = SC.res["ReportDownloadBuilder." + reportType + ".Filter.Example"];
			$('aggregateFilterExample' + reportName).innerHTML = SC.res["ReportDownloadBuilder." + reportType + ".AggregateFilter.Example"];
		}

		$('reportExplanation' + reportName).innerHTML = SC.res['ReportDownloadBuilder.' + $('reportType' + reportName).options[$('reportType' + reportName).selectedIndex].value + '.Explanation'];

		SC.ui.findDescendent($('reportTypeSelection' + reportName), function (e) { return e.type === 'radio' && e.value === 'grouped' }).checked = true;
		SC.ui.findDescendent($('reportTypeSelection' + reportName), function (e) { return e.type === 'radio' && e.value === 'ungrouped' }).checked = false;
		SC.ui.insertChild($('groupFields' + reportName), generateReportFieldPickListDiv('GroupedGroup', $('reportType' + reportName), reportName), 1);
		SC.ui.insertChild($('selectFields' + reportName), generateReportFieldPickListDiv('GroupedSelect', $('reportType' + reportName), reportName), 1);
		$('groupFields' + reportName).style.display = 'block';
		$('aggregateFilterDiv' + reportName).style.display = 'block';

		i = 2;
		if (parsedDefinition.length > 2) {
			var sl = SC.ui.findDescendent($('selectFields' + reportName), function (e) { return e._listType === 'select' });
			var pl = SC.ui.findDescendent($('selectFields' + reportName), function (e) { return e._listType === 'pick' });
			while (i < parsedDefinition.length) {
				if (parsedDefinition[i].search('SelectFields') !== -1) {
					var selectField = parsedDefinition[i].split('=')[1];
					var selectIndex = sl.selectedIndex;
					var selectOptions = sl.options;
					var pickOptions = pl.options;
					var pickOptLength = pickOptions.length;
					for (var j = 0; j < selectOptions.length; j++) {
						if (selectOptions[j].value === selectField) {
							pickOptions[pickOptLength] = $option(sl[j].text);
							pickOptions[pickOptLength].value = sl[j].value;
							pickOptions[pickOptLength].title = sl[j].title;
							pickOptions[pickOptLength]._index = sl[j]._index;
							selectOptions[j] = null;
							break;
						}
					}

				} else if (parsedDefinition[i].search('AggregateFilter') !== -1) {
					var aggregateFilter = parsedDefinition[i].split('=')[1];
					$('aggregateFilter' + reportName).value = decodeURIComponent(aggregateFilter);
				} else if (parsedDefinition[i].search('Filter') !== -1) {
					var filter = parsedDefinition[i].split('=')[1];
					$('filter' + reportName).value = decodeURIComponent(filter);
				} else if (parsedDefinition[i].search('ItemLimit') !== -1) {
					var itemLimit = parsedDefinition[i].split('=')[1];
					$('itemLimit' + reportName).value = itemLimit;
				}

				i++;
			}
			sl.options.length > 0 ? sl.options[0].selected = true : '';
			pl.options.length > 0 ? pl.options[0].selected = true : '';
		}
		var gsl = SC.ui.findDescendent($('groupFields' + reportName), function (e) { return e._listType === 'select' });
		gsl.options[0].selected = true;
		updateReportViewProc();
	} else {
		var encounteredField = false;

		$('groupFields' + reportName).childNodes.length === 2 ? SC.ui.removeChildAt($('groupFields' + reportName), 1) : null;
		$('selectFields' + reportName).childNodes.length === 2 ? SC.ui.removeChildAt($('selectFields' + reportName), 1) : null;
		$('reportDefinitionContent' + reportName).style.display = 'block';
		$('groupFields' + reportName).style.display = 'none';
		$('aggregateFilterDiv' + reportName).style.display = 'none';
		$('filter' + reportName).value = '';
		$('aggregateFilter' + reportName).value = '';

		var parsedDefinition = reportDefinition.split('&');
		if (parsedDefinition[0].search('ReportType') !== -1) {
			var reportType = parsedDefinition[0].split('=')[1];
			for (i = 0; i < $('reportType' + reportName).length; i++) {
				if ($('reportType' + reportName).options[i].value === reportType) {
					$('reportType' + reportName).selectedIndex = i;
					break;
				}
			}
			$('filterExample' + reportName).innerHTML = SC.res["ReportDownloadBuilder." + reportType + ".Filter.Example"];
			$('aggregateFilterExample' + reportName).innerHTML = SC.res["ReportDownloadBuilder." + reportType + ".AggregateFilter.Example"];
		}

		$('reportExplanation' + reportName).innerHTML = SC.res['ReportDownloadBuilder.' + $('reportType' + reportName).options[$('reportType' + reportName).selectedIndex].value + '.Explanation'];
		i = 1;
		if (parsedDefinition.length > 1) {
			while (i < parsedDefinition.length) {
				if (parsedDefinition[i].search('GroupFields') !== -1) {
					if (!encounteredField) {

						SC.ui.findDescendent($('reportTypeSelection' + reportName), function (e) { return e.type === 'radio' && e.value === 'grouped' }).checked = true;
						SC.ui.findDescendent($('reportTypeSelection' + reportName), function (e) { return e.type === 'radio' && e.value === 'ungrouped' }).checked = false;
						SC.ui.insertChild($('groupFields' + reportName), generateReportFieldPickListDiv('GroupedGroup', $('reportType' + reportName), reportName), 1);
						SC.ui.insertChild($('selectFields' + reportName), generateReportFieldPickListDiv('GroupedSelect', $('reportType' + reportName), reportName), 1);
						$('groupFields' + reportName).style.display = 'block';
						$('aggregateFilterDiv' + reportName).style.display = 'block';

						encounteredField = true;
					}

					var groupField = parsedDefinition[i].split('=')[1];

					var gsl = SC.ui.findDescendent($('groupFields' + reportName), function (e) { return e._listType === 'select' });
					var selectIndex = gsl.selectedIndex;
					var selectOptions = gsl.options;
					var gpl = SC.ui.findDescendent($('groupFields' + reportName), function (e) { return e._listType === 'pick' });
					var pickOptions = gpl.options;
					var pickOptLength = pickOptions.length;
					for (var j = 0; j < selectOptions.length; j++) {
						if (selectOptions[j].value === groupField) {
							pickOptions[pickOptLength] = $option(gsl[j].text);
							pickOptions[pickOptLength].value = gsl[j].value;
							pickOptions[pickOptLength].title = gsl[j].title;
							pickOptions[pickOptLength]._index = gsl[j]._index;
							selectOptions[j] = null;
							break;
						}
					}

				} else if (parsedDefinition[i].search('SelectFields') !== -1) {
					if (!encounteredField) {

						SC.ui.findDescendent($('reportTypeSelection' + reportName), function (e) { return e.type === 'radio' && e.value === 'grouped' }).checked = false;
						SC.ui.findDescendent($('reportTypeSelection' + reportName), function (e) { return e.type === 'radio' && e.value === 'ungrouped' }).checked = true;
						SC.ui.insertChild($('groupFields' + reportName), generateReportFieldPickListDiv('GroupedGroup', $('reportType' + reportName), reportName), 1);
						SC.ui.insertChild($('selectFields' + reportName), generateReportFieldPickListDiv('NotGroupedSelect', $('reportType' + reportName), reportName), 1);

						encounteredField = true;
					}

					var selectField = parsedDefinition[i].split('=')[1];

					var ssl = SC.ui.findDescendent($('selectFields' + reportName), function (e) { return e._listType === 'select' });
					var selectIndex = ssl.selectedIndex;
					var selectOptions = ssl.options;
					var spl = SC.ui.findDescendent($('selectFields' + reportName), function (e) { return e._listType === 'pick' });
					var pickOptions = spl.options;
					var pickOptLength = pickOptions.length;
					for (var j = 0; j < selectOptions.length; j++) {
						if (selectOptions[j].value === selectField) {
							pickOptions[pickOptLength] = $option(ssl[j].text);
							pickOptions[pickOptLength].value = ssl[j].value;
							pickOptions[pickOptLength].title = ssl[j].title;
							pickOptions[pickOptLength]._index = ssl[j]._index;
							selectOptions[j] = null;
							break;
						}
					}

				} else if (parsedDefinition[i].search('AggregateFilter') !== -1) {
					var aggregateFilter = parsedDefinition[i].split('=')[1];
					$('aggregateFilter' + reportName).value = decodeURIComponent(aggregateFilter);
				} else if (parsedDefinition[i].search('Filter') !== -1) {
					var filter = parsedDefinition[i].split('=')[1];
					$('filter' + reportName).value = decodeURIComponent(filter);
				} else if (parsedDefinition[i].search('ItemLimit') !== -1) {
					var itemLimit = parsedDefinition[i].split('=')[1];
					$('itemLimit' + reportName).value = itemLimit;
				}

				i++;
			}

			// if have not encountered a single group or select field at this point, then the report is ungrouped with an empty set of select fields
			if (!encounteredField) {
				SC.ui.findDescendent($('reportTypeSelection' + reportName), function (e) { return e.type === 'radio' && e.value === 'grouped' }).checked = false;
				SC.ui.findDescendent($('reportTypeSelection' + reportName), function (e) { return e.type === 'radio' && e.value === 'ungrouped' }).checked = true;
				SC.ui.insertChild($('groupFields' + reportName), generateReportFieldPickListDiv('GroupedGroup', $('reportType' + reportName), reportName), 1);
				SC.ui.insertChild($('selectFields' + reportName), generateReportFieldPickListDiv('NotGroupedSelect', $('reportType' + reportName), reportName), 1);
			}

			var gsl = SC.ui.findDescendent($('groupFields' + reportName), function (e) { return e._listType === 'select' });
			var gpl = SC.ui.findDescendent($('groupFields' + reportName), function (e) { return e._listType === 'pick' });
			var ssl = SC.ui.findDescendent($('selectFields' + reportName), function (e) { return e._listType === 'select' });
			var spl = SC.ui.findDescendent($('selectFields' + reportName), function (e) { return e._listType === 'pick' });
			if (gsl && gsl.options[0]) {
				gsl.options[0].selected = true;
			}
			if (gpl && gpl.options[0]) {
				gpl.options[0].selected = true;
			}
			if (ssl && ssl.options[0]) {
				ssl.options[0].selected = true;
			}
			if (spl && spl.options[0]) {
				spl.options[0].selected = true;
			}
		}
	}
};

var checkForReportInputChange = function (reportName) {

	return function () {
		var valid = true;
		// if this is a grouped report, need to check that at least one group field is selected
		if (SC.ui.findDescendent($('reportTypeSelection' + reportName), function (e) { return e.type === 'radio' && e.value === 'grouped' }).checked === true) {
			valid = false;
			if (SC.ui.findDescendent($('groupFields' + reportName), function (e) { return e._listType === 'pick' }).options.length > 0) {
				valid = true;
			}
		}
		$('report' + reportName)._validReport = valid;

		// check if any changes made to the report since last saved
		if ($('report' + reportName)._reportDefinition !== getReportDefinitionString(reportName)) {
			$('report' + reportName)._isDirty = true;
		} else {
			$('report' + reportName)._isDirty = false;
		}

		updateReportViewProc();
	};
};

// generate a new group or select field selector based on the type of report
var generateReportFieldPickListDiv = function (fieldSelectionType, reportType, reportName) {

	// build a group or select field selector
	var buildPickListDiv = function (primaryOrAggregate, fieldType, reportType) {

		var pickDiv, i;

		var pickListDivBuilder = function (selectList, pickList) {

			var addButton = $button({ className: 'SecondaryButton' }, '>');
			var deleteButton = $button({ className: 'SecondaryButton' }, '<');
			var upButton = $button({ className: 'SecondaryButton' }, '∧');
			var downButton = $button({ className: 'SecondaryButton' }, '∨');

			SC.event.addHandler(addButton, 'click', addOptionToPickList(selectList, pickList));
			SC.event.addHandler(deleteButton, 'click', removeOptionFromPickList(selectList, pickList));
			SC.event.addHandler(addButton, 'click', checkForReportInputChange(reportName));
			SC.event.addHandler(deleteButton, 'click', checkForReportInputChange(reportName));

			SC.event.addHandler(upButton, 'click', function () {
				var pl = pickList;
				var pickIndex = pl.selectedIndex;
				var pickOptions = pl.options;
				var selectedIndices = [];
				for (var i = 0; i < pl.length; i++) {
					if (pickOptions[i].selected) {
						selectedIndices.push(i);
					}
				}
				if ((selectedIndices.length > 0) && (selectedIndices[0] !== 0)) {
					for (var j = 0; j < selectedIndices.length; j++) {
						pl.add($option(pl[selectedIndices[j]].text), selectedIndices[j] - 1);
						pickOptions[selectedIndices[j] - 1].value = pl[selectedIndices[j] + 1].value;
						pickOptions[selectedIndices[j] - 1].title = pl[selectedIndices[j] + 1].title;
						pickOptions[selectedIndices[j] - 1]._index = pl[selectedIndices[j] + 1]._index;
						pickOptions[selectedIndices[j] - 1].selected = true;
						pl.remove(selectedIndices[j] + 1);
					}
				}
			});
			SC.event.addHandler(upButton, 'click', checkForReportInputChange(reportName));

			SC.event.addHandler(downButton, 'click', function () {
				var pl = pickList;
				var pickIndex = pl.selectedIndex;
				var pickOptions = pl.options;
				var selectedIndices = [];
				for (var i = 0; i < pl.length; i++) {
					if (pickOptions[i].selected) {
						selectedIndices.push(i);
					}
				}
				if ((selectedIndices.length > 0) && (selectedIndices[selectedIndices.length - 1] < (pl.length - 1))) {
					for (var j = (selectedIndices.length - 1); j >= 0; j--) {
						pl.add($option(pl[selectedIndices[j]].text), selectedIndices[j] + 2);
						pickOptions[selectedIndices[j] + 2].value = pl[selectedIndices[j]].value;
						pickOptions[selectedIndices[j] + 2].title = pl[selectedIndices[j]].title;
						pickOptions[selectedIndices[j] + 2]._index = pl[selectedIndices[j]]._index;
						pickOptions[selectedIndices[j] + 2].selected = true;
						pl.remove(selectedIndices[j]);
					}
				}
			});
			SC.event.addHandler(downButton, 'click', checkForReportInputChange(reportName));

			return $div([
				$table(
					$tr([
						$td([selectList, $div({ className: 'pickListDescription' }, 'Available')]),
						$td([addButton, $br(), deleteButton]),
						$td([pickList, $div({ className: 'pickListDescription' }, 'Selected')]),
						$td([upButton, $br(), downButton])
					])
				)
			]);
		};

		var addOptionToPickList = function (selectList, pickList) {
			return function () {
				var sl = selectList;
				var selectIndex = sl.selectedIndex;
				var selectOptions = sl.options;
				var pl = pickList;
				var pickOptions = pl.options;
				var pickOptLength = pickOptions.length;
				for (var i = 0; i < pickOptLength; i++) {
					pickOptions[i].selected = false;
				}
				while (selectIndex > -1) {
					pickOptions[pickOptLength] = $option(sl[selectIndex].text);
					pickOptions[pickOptLength].value = sl[selectIndex].value;
					pickOptions[pickOptLength].title = sl[selectIndex].title;
					pickOptions[pickOptLength]._index = sl[selectIndex]._index;
					pickOptions[pickOptLength].selected = true;
					selectOptions[selectIndex] = null;
					selectIndex = sl.selectedIndex;
					pickOptLength = pickOptions.length;
				}
			};
		};


		var removeOptionFromPickList = function (selectList, pickList) {
			return function () {
				var sl = selectList;
				var selectOptions = sl.options;
				var selectOptLength = selectOptions.length;
				var pl = pickList;
				var pickIndex = pl.selectedIndex;
				var pickOptions = pl.options;
				for (var i = 0; i < selectOptLength; i++) {
					selectOptions[i].selected = false;
				}
				while (pickIndex > -1) {
					var j = 0;
					while (selectOptions[j] && (pickOptions[pickIndex]._index > selectOptions[j]._index)) {
						j++;
					}
					sl.add($option(pl[pickIndex].text), j);
					selectOptions[j].value = pl[pickIndex].value;
					selectOptions[j].title = pl[pickIndex].title;
					selectOptions[j]._index = pl[pickIndex]._index;
					selectOptions[j].selected = true;
					pickOptions[pickIndex] = null;
					pickIndex = pl.selectedIndex;
				}
			};
		};
		var name = reportName !== null ? reportName : Array.prototype.find.call($('ReportDownloadBuilderSelectionPanel').childNodes, function (l) { return SC.ui.isSelected(l); })._commandArgument;
		var pickList = $select({ id: primaryOrAggregate + 'pickList' + name, size: 7, multiple: true, _listType: 'pick' });
		var selectList = $select({ id: primaryOrAggregate + 'selectList' + name, size: 7, multiple: true, _listType: 'select' });
		var j = 0;
		var reportTypeValue = reportType.options[reportType.selectedIndex].value;
		if (reportTypeValue != 'SessionConnectionEvent' || SC.util.isVersion(null, {major: 22, minor : 9}, currentVersion)) {
			for (i = 0; i < getMetaTableFromReportManagerMetaTables(reportTypeValue).Items.length; i++) {
				if (getMetaTableFromReportManagerMetaTables(reportTypeValue).Items[i][1].toLowerCase() === primaryOrAggregate) {
					SC.ui.addContent(selectList, $option({
						label: getMetaTableFromReportManagerMetaTables(reportTypeValue).Items[i][3],
						value: getMetaTableFromReportManagerMetaTables(reportTypeValue).Items[i][3],
						title: SC.res[reportTypeValue + '.' + getMetaTableFromReportManagerMetaTables(reportTypeValue).Items[i][3] + '.Definition'],
						_index: j
					}, getMetaTableFromReportManagerMetaTables(reportTypeValue).Items[i][3]));
					j++;
				}
			}
			selectList.options[0].selected = true;
			pickDiv = pickListDivBuilder(selectList, pickList);
		}
		return pickDiv;
	};

	switch (fieldSelectionType) {
		case 'NotGroupedSelect':
			return buildPickListDiv('primary', 'selectFields', reportType);
		case 'GroupedGroup':
			return buildPickListDiv('primary', 'groupFields', reportType);
		case 'GroupedSelect':
			return buildPickListDiv('aggregate', 'selectFields', reportType);
	}
};

var createReportEditPanelFunc = function (reportName, reportLoadFileName, isDirty, validReport, definition) {

	var reportTypeInput, reportTypeSelection, groupFieldSelection, selectFieldsSelection, aggregateFilterContent, aggregateFilterInput, reportDefinitionContent,
		filterInput, itemLimitInput, filterExample, aggregateFilterExample;

	var inputs = ['Session', 'SessionConnection', 'SessionConnectionEvent', 'SessionEvent', 'SecurityEvent'];
	if (SC.util.isVersion({major: 22, minor : 9}, null, currentVersion)) {
		inputs = ['Session', 'SessionConnection', 'SessionEvent', 'SecurityEvent'];
	}
	var reportEditPanel = $div({ className: 'reportEditPanel', id: 'report' + reportName, _isDirty: isDirty, _reportDefinition: definition === null ? '' : definition, _validReport: validReport },
		$table([
			$tr([
				$td([
					$div({ id: 'rawReporter' + reportName }, [
						$div({ className: 'reportBuilderSection' }, [
							reportTypeSelection = $div({ className: 'aggregationSection', id: 'reportTypeSelection' + reportName }, [
								$label({ className: 'ReportBuilderHeader' }, SC.res['ReportDownloadBuilder.AggregationType.Label']),
								$table(
									$tr([
										$td([SC.ui.createRadioButtonOption('span', SC.res['ReportDownloadBuilder.UngroupedReport.Label'], 'reportType' + reportName, 'ungrouped', false, true)]),
										$td({ id: 'ungroupedTooltip' }, [$dfn({ _textResource: 'InfoIcon.Text', _dataMap: { tooltip: SC.res['ReportDownloadBuilder.UngroupedReport.Tooltip'] } })])
									]),
									$tr([
										$td([SC.ui.createRadioButtonOption('span', SC.res['ReportDownloadBuilder.GroupedReport.Label'], 'reportType' + reportName, 'grouped', false, true)]),
										$td({ id: 'groupedTooltip' }, [$dfn({ _textResource: 'InfoIcon.Text', _dataMap: { tooltip: SC.res['ReportDownloadBuilder.GroupedReport.Tooltip'] } })])
									])
								)
							]),
							reportDefinitionContent = $div({ id: 'reportDefinitionContent' + reportName }, [
								$div({ className: 'reportSection' }, [
									$div($label({ className: 'ReportBuilderHeader' }, SC.res['ReportDownloadBuilder.ReportType.Label'])),
									$div(reportTypeInput = $select({ className: 'reportTypeInput', id: 'reportType' + reportName }, inputs.map(function (reportType) {
										return $option({
											label: reportType,
											value: reportType
										}, reportType);
									}))),
									$div({ className: 'ReportExplanation', id: 'reportExplanation' + reportName }, SC.res['ReportDownloadBuilder.Session.Explanation'])
								]),
								groupFieldSelection = $div({ id: 'groupFields' + reportName, className: 'reportSection' }, [
									$label({ className: 'ReportBuilderHeader' }, SC.res['ReportDownloadBuilder.GroupFieldSet.Label'])
								]),
								selectFieldsSelection = $div({ id: 'selectFields' + reportName, className: 'reportSection' }, [
									$label({ className: 'ReportBuilderHeader' }, SC.res['ReportDownloadBuilder.SelectFieldSet.Label'])
								]),
								$div({ className: 'reportSection' }, [
									$label({ className: 'ReportBuilderHeader' }, SC.res['ReportDownloadBuilder.Filter.Label']),
									$div(filterInput = SC.ui.createElement('INPUT', { className: 'reportFilterInput', id: 'filter' + reportName, type: 'text' })),
									filterExample = $label({ id: 'filterExample' + reportName, className: 'filterExample' }, SC.res['ReportDownloadBuilder.Session.Filter.Example'])
								]),
								aggregateFilterContent = $div({ id: 'aggregateFilterDiv' + reportName, className: 'reportSection' }, [
									$label({ className: 'ReportBuilderHeader' }, SC.res['ReportDownloadBuilder.AggregateFilter.Label']),
									$div(aggregateFilterInput = SC.ui.createElement('INPUT', { className: 'reportFilterInput', id: 'aggregateFilter' + reportName, type: 'text' })),
									aggregateFilterExample = $label({ id: 'aggregateFilterExample' + reportName, className: 'filterExample' }, SC.res['ReportDownloadBuilder.Session.AggregateFilter.Example'])
								]),
								$div({ className: 'reportSection' }, [
									$label({ className: 'ReportBuilderHeader' }, SC.res['ReportDownloadBuilder.ItemLimit.Label']),
									$div(itemLimitInput = SC.ui.createElement('INPUT', { id: 'itemLimit' + reportName, type: 'number', value: SC.res['ReportDownloadBuilder.ItemLimit.DefaultValue'] }))
								])
							]),
						])
					])
				])
			])
		])
	);

	// initialize display
	reportDefinitionContent.style.display = 'none';
	groupFieldSelection.style.display = 'none';
	aggregateFilterContent.style.display = 'none';

	// add handlers
	SC.event.addHandler(aggregateFilterInput, 'input', checkForReportInputChange(reportName));
	SC.event.addHandler(filterInput, 'input', checkForReportInputChange(reportName));
	SC.event.addHandler(itemLimitInput, 'input', checkForReportInputChange(reportName));

	SC.event.addHandler(SC.ui.findDescendent(reportTypeSelection, function (e) { return e.type === 'radio' && e.value === 'ungrouped' }), 'click', function () {
		reportDefinitionContent.style.display = 'block';
		groupFieldSelection.style.display = 'none';
		aggregateFilterContent.style.display = 'none';
		reportTypeSelection.title = '';

		$('selectFields' + reportName).childNodes.length === 2 ? SC.ui.removeChildAt($('selectFields' + reportName), 1) : null;
		SC.ui.insertChild($('selectFields' + reportName), generateReportFieldPickListDiv('NotGroupedSelect', reportTypeInput, reportName), 1);
	});

	SC.event.addHandler(SC.ui.findDescendent(reportTypeSelection, function (e) { return e.type === 'radio' && e.value === 'grouped' }), 'click', function () {
		reportDefinitionContent.style.display = 'block';
		groupFieldSelection.style.display = 'block';
		aggregateFilterContent.style.display = 'block';
		reportTypeSelection.title = '';

		$('groupFields' + reportName).childNodes.length === 2 ? SC.ui.removeChildAt($('groupFields' + reportName), 1) : null;
		SC.ui.insertChild($('groupFields' + reportName), generateReportFieldPickListDiv('GroupedGroup', reportTypeInput, reportName), 1);
		$('selectFields' + reportName).childNodes.length === 2 ? SC.ui.removeChildAt($('selectFields' + reportName), 1) : null;
		SC.ui.insertChild($('selectFields' + reportName), generateReportFieldPickListDiv('GroupedSelect', reportTypeInput, reportName), 1);

	});

	SC.event.addHandler(SC.ui.findDescendent(reportTypeSelection, function (e) { return e.type === 'radio' && e.value === 'ungrouped' }), 'click', checkForReportInputChange(reportName));
	SC.event.addHandler(SC.ui.findDescendent(reportTypeSelection, function (e) { return e.type === 'radio' && e.value === 'grouped' }), 'click', checkForReportInputChange(reportName));

	var updateGroup = function (callback) {
		$('groupFields' + reportName).childNodes.length === 2 ? SC.ui.removeChildAt($('groupFields' + reportName), 1) : null;
		SC.ui.insertChild($('groupFields' + reportName), generateReportFieldPickListDiv('GroupedGroup', reportTypeInput, reportName), 1);
		$('selectFields' + reportName).childNodes.length === 2 ? SC.ui.removeChildAt($('selectFields' + reportName), 1) : null;
		SC.ui.insertChild($('selectFields' + reportName), generateReportFieldPickListDiv('GroupedSelect', reportTypeInput, reportName), 1);
		callback();
	};

	var updateNotGroup = function (callback) {
		$('selectFields' + reportName).childNodes.length === 2 ? SC.ui.removeChildAt($('selectFields' + reportName), 1) : null;
		SC.ui.insertChild($('selectFields' + reportName), generateReportFieldPickListDiv('NotGroupedSelect', reportTypeInput, reportName), 1);
		callback();
	};

	// update options in GroupFields and SelectFields dropdown if reportType changes
	SC.event.addHandler(reportTypeInput, 'change', function () {
		$('reportExplanation' + reportName).innerHTML = SC.res['ReportDownloadBuilder.' + reportTypeInput.options[reportTypeInput.selectedIndex].value + '.Explanation'];
		filterExample.innerHTML = SC.res['ReportDownloadBuilder.' + reportTypeInput.options[reportTypeInput.selectedIndex].value + '.Filter.Example'];
		aggregateFilterExample.innerHTML = SC.res['ReportDownloadBuilder.' + reportTypeInput.options[reportTypeInput.selectedIndex].value + '.AggregateFilter.Example'];
		reportTypeInput.options[reportTypeInput.selectedIndex].value
		if (SC.ui.getSelectedRadioButtonValue(reportTypeSelection) === 'grouped') {
			updateGroup(checkForReportInputChange(reportName));
		} else {
			updateNotGroup(checkForReportInputChange(reportName));
		}
	});

	return reportEditPanel;
};

var createReportSelectionLinkFunc = function (reportName) {
	return $a({ className: 'SelectionLink', _commandName: 'EditReport', _commandArgument: reportName });
};

var tryRemoveReportFileProc = function (reportName) {
	var index = getIndexOfReportFilePathFunc(reportName);

	if (index != -1) {
		SC.ui.removeChildAt($('ReportDownloadBuilderSelectionPanel'), index);
		SC.ui.removeChildAt($('ReportDownloadBuilderEditorPanel'), index);
		if ($('ReportDownloadBuilderSelectionPanel').childNodes.length !== 0) {
			if (index === $('ReportDownloadBuilderSelectionPanel').childNodes.length) {
				tryEditReportFileProc($('ReportDownloadBuilderSelectionPanel').childNodes[index - 1]._commandArgument);
			} else {
				tryEditReportFileProc($('ReportDownloadBuilderSelectionPanel').childNodes[index]._commandArgument);
			}
		}
	}

	updateReportViewProc();
};

var tryEditReportFileProc = function (reportName) {
	var index = getIndexOfReportFilePathFunc(reportName);

	Array.prototype.forEach.call($('ReportDownloadBuilderSelectionPanel').childNodes, function (l, i) {
		SC.ui.setSelected(l, i == index);
	});

	Array.prototype.forEach.call($('ReportDownloadBuilderEditorPanel').childNodes, function (p, i) {
		SC.ui.setVisible(p, i == index);
	});

	updateReportViewProc();
};

var getIndexOfReportFilePathFunc = function (reportName) {
	return Array.prototype.findIndex.call($('ReportDownloadBuilderSelectionPanel').childNodes, function (sl) { return sl._commandArgument == reportName; });
};

var getSelectedReportFileIndexFunc = function () {
	return Array.prototype.findIndex.call($('ReportDownloadBuilderSelectionPanel').childNodes, function (sl) { return SC.ui.isSelected(sl); });
};

var updateReportViewProc = function () {
	var commandPanel = document.querySelector('.ModalDialog.ReportDownloadBuilder .CommandPanel');

	var index = getSelectedReportFileIndexFunc();

	//update Clone and Delete command button states
	if ($('ReportDownloadBuilderSelectionPanel').childNodes.length > 0) {
		commandPanel.childNodes[1].className = '';
		commandPanel.childNodes[2].className = '';
	} else {
		commandPanel.childNodes[1].className = 'Disabled';
		commandPanel.childNodes[2].className = 'Disabled';
	}

	//update Save command button state
	if ($('ReportDownloadBuilderEditorPanel').childNodes[index]) {
		if ($('ReportDownloadBuilderEditorPanel').childNodes[index]._isDirty) {
			commandPanel.childNodes[3].className = '';
		} else {
			commandPanel.childNodes[3].className = 'Disabled';
		}
	} else {
		commandPanel.childNodes[3].className = 'Disabled';
	}

	//update Save All command button state
	if ($('ReportDownloadBuilderEditorPanel').childNodes[index]) {
		var enableSaveAll = false;
		for (var i = 0; i < $('ReportDownloadBuilderEditorPanel').childNodes.length; i++) {
			if ($('ReportDownloadBuilderEditorPanel').childNodes[i]._isDirty) {
				enableSaveAll = true;
			} else {
				enableSaveAll = enableSaveAll | false;
			}
		}
		if (enableSaveAll) {
			commandPanel.childNodes[4].className = '';
		} else {
			commandPanel.childNodes[4].className = 'Disabled';
		}
	} else {
		commandPanel.childNodes[4].className = 'Disabled';
	}

	//update Download and Email command button states
	if ($('ReportDownloadBuilderEditorPanel').childNodes[index]) {
		if ($('ReportDownloadBuilderEditorPanel').childNodes[index]._validReport) {
			commandPanel.childNodes[5].className = '';
			commandPanel.childNodes[6].className = '';
		} else {
			commandPanel.childNodes[5].className = 'Disabled';
			commandPanel.childNodes[6].className = 'Disabled';
		}
	} else {
		commandPanel.childNodes[5].className = 'Disabled';
		commandPanel.childNodes[6].className = 'Disabled';
	}

	Array.prototype.forEach.call($('ReportDownloadBuilderSelectionPanel').childNodes, function (sl, i) {
		var linkContent = sl._commandArgument;


		if ($('ReportDownloadBuilderEditorPanel').childNodes[i]._isDirty)
			linkContent += ' *';

		SC.ui.setInnerText(sl, linkContent);

		SC.css.ensureClass(sl, 'LoadError', sl._status == SC.types.ExtensionRuntimeStatus.LoadError);

		sl.title = (SC.util.isNullOrEmpty(sl._loadMessage) ? '' : sl._loadMessage);
	});
};

var getReportDefinitionString = function (reportName) {
	var selectedGroupFields = [];
	var selectedSelectFields = [];
	var reportDefinition;

	if (SC.ui.getSelectedRadioButtonValue($('reportTypeSelection' + reportName)) === 'grouped') {
		var pListGroup = SC.ui.findDescendent($('groupFields' + reportName), function (e) { return e._listType === 'pick' });

		for (i = 0; i < pListGroup.options.length; i++) {
			selectedGroupFields.push(pListGroup[i].value);
		}

		var pListSelect = SC.ui.findDescendent($('selectFields' + reportName), function (e) { return e._listType === 'pick' });
		for (i = 0; i < pListSelect.options.length; i++) {
			selectedSelectFields.push(pListSelect[i].value);
		}

		if (pListGroup.options.length === 0) {
			reportDefinition =
			{
				InvalidGrouped: 'true',
				ReportType: $('reportType' + reportName).options[$('reportType' + reportName).selectedIndex].value,
				GroupFields: [],
				SelectFields: selectedSelectFields,
				Filter: $('filter' + reportName).value.length > 0 ? $('filter' + reportName).value : [],
				AggregateFilter: $('aggregateFilter' + reportName).value.length > 0 ? $('aggregateFilter' + reportName).value : [],
				ItemLimit: $('itemLimit' + reportName).value.length > 0 ? $('itemLimit' + reportName).value : 10000
			};
		} else {
			reportDefinition =
			{
				ReportType: $('reportType' + reportName).options[$('reportType' + reportName).selectedIndex].value,
				GroupFields: selectedGroupFields,
				SelectFields: selectedSelectFields,
				Filter: $('filter' + reportName).value.length > 0 ? $('filter' + reportName).value : [],
				AggregateFilter: $('aggregateFilter' + reportName).value.length > 0 ? $('aggregateFilter' + reportName).value : [],
				ItemLimit: $('itemLimit' + reportName).value.length > 0 ? $('itemLimit' + reportName).value : 10000
			};
		}

	} else if (SC.ui.getSelectedRadioButtonValue($('reportTypeSelection' + reportName)) === 'ungrouped') {
		var pListSelect = SC.ui.findDescendent($('selectFields' + reportName), function (e) { return e._listType === 'pick' });
		for (i = 0; i < pListSelect.options.length; i++) {
			selectedSelectFields.push(pListSelect[i].value);
		}

		reportDefinition =
		{
			ReportType: $('reportType' + reportName).options[$('reportType' + reportName).selectedIndex].value,
			GroupFields: [],
			SelectFields: selectedSelectFields,
			Filter: $('filter' + reportName).value.length > 0 ? $('filter' + reportName).value : [],
			AggregateFilter: [],
			ItemLimit: $('itemLimit' + reportName).value.length > 0 ? $('itemLimit' + reportName).value : 10000
		};

	} else {
		reportDefinition =
		{
			ReportType: [],
			GroupFields: [],
			SelectFields: [],
			Filter: [],
			AggregateFilter: [],
			ItemLimit: []
		};
	}

	if (reportDefinition.ReportType === 'SecurityEvent') {
		reportDefinition.Report = 'Security';
	}

	return SC.util.getQueryString(reportDefinition);
};

var downloadReport = function (reportName, fileFormat) {
	if (fileFormat === 'csv') {
		SC.util.launchUrl(SC.context.scriptBaseUrl + 'Report.csv' + getReportDefinitionString(reportName));
	} else {
		window.open(SC.context.scriptBaseUrl + 'Report.' + fileFormat + getReportDefinitionString(reportName));
	}
};

var getUniqueReportName = function (desiredReportName) {
	var duplicate = false;

	for (var i = 0; i < $('ReportDownloadBuilderSelectionPanel').childNodes.length; i++) {
		if (desiredReportName === $('ReportDownloadBuilderSelectionPanel').childNodes[i]._commandArgument) {
			duplicate = true;
		}
	}

	if (duplicate) {
		var created = false;
		var duplicateIndicator = 1;
		var reportName = desiredReportName + '-' + duplicateIndicator;
		while (!created) {
			duplicate = false;
			for (var i = 0; i < $('ReportDownloadBuilderSelectionPanel').childNodes.length; i++) {
				if (reportName === $('ReportDownloadBuilderSelectionPanel').childNodes[i]._commandArgument) {
					duplicate = true;
				}
			}
			if (duplicate) {
				duplicateIndicator++;
				reportName = desiredReportName + '-' + duplicateIndicator;
			} else {
				return reportName;
			}
		}
	} else {
		return desiredReportName;
	}
};

var updateReportDefinition = function (reportName) {
	$('report' + reportName)._reportDefinition = getReportDefinitionString(reportName);
};

var makeReportClean = function (reportName) {
	$('report' + reportName)._isDirty = false;
};


var startSaveReportFileProc = function (reportName) {
	makeReportClean(reportName);
	updateReportDefinition(reportName);
	updateReportViewProc();
};

SC.event.addGlobalHandler(SC.event.QueryCommandButtons, function (eventArgs) {
	switch (eventArgs.area) {
		case 'ExtrasPopoutPanel':
			if (SC.context.pageType == 'AdministrationPage') {
				eventArgs.buttonDefinitions.push(
					{ commandName: 'ManageRawReports', text: SC.res['ReportDownloadBuilder.ButtonText'] }
				);
			}
			break;
		case 'ReportDownloadBuilderEditorPanel':
			Array.prototype.push.apply(eventArgs.buttonDefinitions, [
				{ commandName: 'NewReport' },
				{ commandName: 'CloneReport' },
				{ commandName: 'DeleteReport' },
				{ commandName: 'SaveReport' },
				{ commandName: 'SaveAllReports' },
				{ commandName: 'DownloadReport' },
				{ commandName: 'EmailReport' }
			]);
			break;
	}
});

SC.event.addGlobalHandler(SC.event.ExecuteCommand, function (eventArgs) {
	var dialog = SC.dialog.getModalDialog();
	switch (eventArgs.commandName) {
		case 'ManageRawReports':
			editReportProc();
			break;
		case 'NewReport':
			if (eventArgs.clickedElement.tagName == 'INPUT') {
				var unprocessedReportName = (eventArgs.clickedElement.value === '' ? SC.res['ReportDownloadBuilder.NewReportName.DefaultName'] : eventArgs.clickedElement.value);
				var reportFile = { ReportName: unprocessedReportName, ReportContent: '' };
				var reportName = getUniqueReportName(reportFile.ReportName);
				addReportFileProc(reportName, null, true, false, null);
				tryEditReportFileProc(reportName);
			} else {
				SC.popout.togglePanel(
					SC.ui.findDescendent(dialog, function (e) { return e._commandName == eventArgs.commandName; }),
					function (container) {
						SC.ui.setContents(container, [
							$p(SC.ui.createTextBox({ _commandName: eventArgs.commandName }, false, false, SC.res['ReportDownloadBuilder.NewReportName.Placeholder'])),
						]);
					},
					function (container) {
						SC.ui.findDescendentByTag(container, 'INPUT').focus();
					}
				);
			}
			break;
		case 'EditReport':
			tryEditReportFileProc(eventArgs.commandArgument);
			break;
		case 'DeleteReport':
			if (eventArgs.commandArgument) {
				var currentSelectionLink = Array.prototype.find.call($('ReportDownloadBuilderSelectionPanel').childNodes, function (l) { return SC.ui.isSelected(l); });
				SC.service.TryDeleteReportDefinitionString(encodeURIComponent(currentSelectionLink._commandArgument), function () {
					tryRemoveReportFileProc(currentSelectionLink._commandArgument);
				});
			} else {
				SC.popout.togglePanel(
					SC.ui.findDescendent(dialog, function (e) { return e._commandName == eventArgs.commandName; }),
					function (container) {
						var currentSelectionLink = Array.prototype.find.call($('ReportDownloadBuilderSelectionPanel').childNodes, function (l) { return SC.ui.isSelected(l); });
						SC.ui.setContents(container, [
							$p(SC.res['ReportDownloadBuilder.DeleteReport.ConfirmationText']),
							$p($input({ type: 'button', value: SC.res['ReportDownloadBuilder.DeleteReport.ButtonText'], _commandName: eventArgs.commandName, _commandArgument: true }))
						]);
					},
					function (container) {
						if (SC.ui.findDescendentByTag(container, 'INPUT') !== null) {
							SC.ui.findDescendentByTag(container, 'INPUT').focus();
						}
					}
				);
			}
			break;
		case 'SaveReport':
			var currentSelectionLink = Array.prototype.find.call($('ReportDownloadBuilderSelectionPanel').childNodes, function (l) { return SC.ui.isSelected(l); });
			var definition = getReportDefinitionString(currentSelectionLink._commandArgument);
			definition = definition !== '' ? definition : '?';
			SC.service.SaveReportDefinitionString(encodeURIComponent(currentSelectionLink._commandArgument), definition, function () {
				startSaveReportFileProc(currentSelectionLink._commandArgument);
			});
			break;
		case 'SaveAllReports':
			var selectionLinks = $('ReportDownloadBuilderSelectionPanel').childNodes;
			var reportEditPanels = $('ReportDownloadBuilderEditorPanel').childNodes;
			var reportNamesAndDefinitions = '';
			for (var i = 0; i < selectionLinks.length; i++) {
				if (reportEditPanels[i]._isDirty) {
					var definition = getReportDefinitionString(selectionLinks[i]._commandArgument);
					definition = definition !== '' ? definition : '?';
					startSaveReportFileProc(selectionLinks[i]._commandArgument);
					reportNamesAndDefinitions += encodeURIComponent(selectionLinks[i]._commandArgument) + definition + SC.res['ReportDownloadBuilder.Query.Delimiter'];
				}
			}

			SC.service.SaveAllReportDefinitionStrings(reportNamesAndDefinitions);
			break;
		case 'CloneReport':
			if (eventArgs.clickedElement.tagName == 'INPUT') {
				var currentSelectionLink = Array.prototype.find.call($('ReportDownloadBuilderSelectionPanel').childNodes, function (l) { return SC.ui.isSelected(l); });
				var unprocessedReportName = (eventArgs.clickedElement.value === '' ? SC.res['ReportDownloadBuilder.NewReportName.DefaultName'] : eventArgs.clickedElement.value);
				var reportFile = { ReportName: unprocessedReportName, ReportContent: '' };
				var reportName = getUniqueReportName(reportFile.ReportName);
				var definition = getReportDefinitionString(currentSelectionLink._commandArgument);

				var definitionForAddAndSave = definition !== '' ? definition : '?';
				var definitionForLoad = definitionForAddAndSave.charAt(0) !== '?' ? definitionForAddAndSave : definitionForAddAndSave.substring(1);

				addReportFileProc(reportName, null, false, true, definitionForAddAndSave);
				loadReportFileProc(reportName, definitionForLoad);
				tryEditReportFileProc(reportName);
				SC.service.SaveReportDefinitionString(encodeURIComponent(reportName), definitionForAddAndSave, function () {
					startSaveReportFileProc(reportName);
				});
			} else {
				SC.popout.togglePanel(
					SC.ui.findDescendent(dialog, function (e) { return e._commandName == eventArgs.commandName; }),
					function (container) {
						SC.ui.setContents(container, [
							$p(SC.ui.createTextBox({ _commandName: eventArgs.commandName }, false, false, SC.res['ReportDownloadBuilder.NewReportName.Placeholder'])),
						]);
					},
					function (container) {
						SC.ui.findDescendentByTag(container, 'INPUT').focus();
					}
				);
			}
			break;
		case 'DownloadReport':
			SC.popout.togglePanel(
				SC.ui.findDescendent(dialog, function (e) { return e._commandName == eventArgs.commandName; }),
				function (container) {
					var currentSelectionLink = Array.prototype.find.call($('ReportDownloadBuilderSelectionPanel').childNodes, function (l) { return SC.ui.isSelected(l); });
					var downloadFormatSelection = $select({ id: 'DownloadReportFormatSelector' }, ['CSV', 'XML', 'JSON'].map(function (downloadFormat) {
						return $option({
							label: downloadFormat,
							value: downloadFormat.toLowerCase()
						}, downloadFormat);
					}));
					var downloadButton = $input({ id: 'DownloadReportButton', type: 'button', value: SC.res['ReportDownloadBuilder.DownloadReport.Button.Text'] });
					var downloadURL = $input();
					downloadURL.value = SC.context.scriptBaseUrl + 'Report.csv' + getReportDefinitionString(currentSelectionLink._commandArgument);

					SC.ui.addContent(container, [
						$p([downloadFormatSelection, downloadButton]),
						$p([downloadURL]),
						$p([
							$input({
								id: 'CopyReportDownloadLink',
								type: 'button',
								value: SC.res['ReportDownloadBuilder.CopyDownloadURL.Button.Text'],
								_eventHandlerMap: {
									click: function (eventArgs) {
										downloadURL.select();

										try {
											document.execCommand('copy');
											SC.ui.setVisible(eventArgs.target.parentNode.lastChild, true);
										} catch (ex) {
											// don't care
										}
									}
								}
							}),
							$span({ id: 'CopyReportDownloadLinkSuccess', className: 'Success', _visible: false, innerHTML: SC.res['ReportDownloadBuilder.CopySuccessMessage'] })
						])
					]);

					downloadURL.select();

					SC.event.addHandler(downloadButton, 'click', function () {
						downloadReport(currentSelectionLink._commandArgument, downloadFormatSelection.value);
						downloadURL.select();
					});

					SC.event.addHandler(downloadFormatSelection, 'change', function () {
						downloadURL.value = SC.context.scriptBaseUrl + 'Report.' + downloadFormatSelection.value + getReportDefinitionString(currentSelectionLink._commandArgument);
						downloadURL.select();
						SC.ui.setVisible($('CopyReportDownloadLinkSuccess'), false);
					});

				},
				function (container) {

				}
			);
			break;
		case 'EmailReport':
			SC.popout.togglePanel(
				SC.ui.findDescendent(dialog, function (e) { return e._commandName == eventArgs.commandName; }),
				function (container) {
					var currentSelectionLink = Array.prototype.find.call($('ReportDownloadBuilderSelectionPanel').childNodes, function (l) { return SC.ui.isSelected(l); });
					var emailReportToAddress = $input({ id: 'emailReportToAddressInput', type: 'text', placeholder: SC.res['ReportDownloadBuilder.EmailReport.Placeholder'] });
					var emailReportButton = $input({ id: 'EmailReportButton', type: 'button', value: SC.res['ReportDownloadBuilder.EmailReport.Button.Text'] });
					var emailReportStatusMessage = $span({ innerHTML: SC.res['Command.EmailReport.DefaultMessage'] });
					var reportParameters = getReportDefinitionString(currentSelectionLink._commandArgument);

					SC.service.GetReportEmailDefaultToAddress(function (emailToAddress) {
						emailReportToAddress.value = emailToAddress;
						SC.ui.addContent(container, [
							$p([emailReportToAddress, emailReportButton]),
							$p([emailReportStatusMessage])
						]);
					});

					SC.event.addHandler(emailReportButton, 'click', function () {
						emailReportToAddress.disabled = true;
						emailReportButton.disabled = true;
						SC.service.EmailReport(emailReportToAddress.value, currentSelectionLink.innerHTML, reportParameters,
							function (response) {
								emailReportStatusMessage.innerHTML = response;
								emailReportToAddress.disabled = false;
								emailReportButton.disabled = false;
							}
						);
					}
					);
				},
				function (container) {

				}
			);
			break;
	}
});

});</script>
<script>SC.extension.addInitializeProc('6fadbbb8-9540-4612-8504-937c5083bca7', function (extensionContext) {
var securityToolkitExtensionId = extensionContext.baseUrl.split('/').slice(-2)[0];
var securityToolkitHelpLink = 'https://docs.connectwise.com/ConnectWise_Control_Documentation/Supported_extensions/Administration/Security_Toolkit';

SC.event.addGlobalHandler(SC.event.QueryCommandButtonState, function (eventArgs) {
	if (eventArgs.commandName == 'EditExtensionSettings')
		if (eventArgs.commandContext.extensionInfo.ExtensionID == securityToolkitExtensionId && eventArgs.commandElement._commandName == "EditExtensionSettings")
			eventArgs.target.parentElement.appendChild($a({ _commandName: 'ShowHelpLink_' + securityToolkitExtensionId, _textResource: 'SecurityToolkit.ShowHelpLink.ButtonText' }));
});

SC.event.addGlobalHandler(SC.event.ExecuteCommand, function (eventArgs) {
	if (eventArgs.commandName == 'ShowHelpLink_' + securityToolkitExtensionId)
		window.open(securityToolkitHelpLink, '_blank');
});

SC.event.addGlobalHandler(SC.event.PreRender, function (eventArgs) {
	if (SC.context.pageType === 'AdministrationPage' || (SC.context.pageType === 'HostPage' && SC.context.canAdminister === true))
		SC.util.includeStyleSheet(extensionContext.baseUrl + 'SecurityToolkit.css');
});

SC.event.addGlobalHandler(SC.event.QueryCommandButtons, function (eventArgs) {
	switch (eventArgs.area) {
		case 'ExtrasPopoutPanel':
			if (SC.context.pageType === 'AdministrationPage' || (SC.context.pageType === 'HostPage' && SC.context.canAdminister === true))
				eventArgs.buttonDefinitions.push(
					{ commandName: 'RemoveQueuedCommands', text: SC.res['SecurityToolkit.ExtrasPanel.RemoveQueuedCommands.Text'] }
				);
			break;
	}
});

SC.event.addGlobalHandler(SC.event.ExecuteCommand, function (eventArgs) {
	switch (eventArgs.commandName) {
		case 'RemoveQueuedCommands':
			removeQueuedCommands();
			break;
	}
});

var removeQueuedCommands = function () {
	SC.dialog.showConfirmationDialog(
		'RemoveQueuedCommands',
		SC.res['SecurityToolkit.RemoveCommandsActionPanel.Title'],
		$p({ innerHTML: SC.res['SecurityToolkit.RemoveCommandsActionPanel.Text'] }),
		SC.res['SecurityToolkit.RemoveCommandsActionPanel.ButtonText'],
		function (onSuccess, onFailure) {
			SC.service.RemoveAllQueuedCommands(
				function () { onSuccess(); SC.pagedata.notifyDirty(); },
				onFailure
			);
		}
	);
}

});</script>
<title>
	ScreenConnect Remote Support Software
</title></head>
<body>
	<div class="HiddenPanel"></div>
	<script>
		SC.ui.setVisible(document.body, false);
	</script>
	<div class="OuterPanel">
		<div class="HeaderPanel"></div>
		<div class="NavigationPanel ArrowNavigation" tabindex="10"></div>
		<div class="MainPanel">
			
	<div class="ContentPanel">
		<div>
			<div class="ActionPanel"></div>
		</div>
		<div class="InfoPanel"></div>
	</div>

		</div>
	</div>
	<script>
		SC.context.scriptBaseUrl = SC.util.getBaseUrl($('defaultScript').src);
	</script>
	
	<script>

		SC.event.addGlobalHandler(SC.event.ExecuteCommand, function (eventArgs) {
			var session = null;
			var hostAccessToken = null;

			switch (eventArgs.commandName) {
				case 'JoinBySessionID':
					session = window.getSessionInfo().Sessions.filter(function (s) { return s.SessionID == eventArgs.commandArgument; })[0];
					break;
				case 'JoinByTag':
					var taggedSessionInfo = window.getTaggedSessionInfo(eventArgs.commandArgument);
					hostAccessToken = taggedSessionInfo.HostAccessToken;
					session = window.getSessionInfo().Sessions.filter(function (s) { return s.SessionID == taggedSessionInfo.SessionID || (taggedSessionInfo.Code && s.Code.toLowerCase() == taggedSessionInfo.Code.toLowerCase()); })[0];
					break;
			}

			// older IE only allows launching urls on actual clicks and this could be sent by a keystroke
			if (session && (SC.command.doesClickDispatch(eventArgs.commandElement) || !SC.util.isCapable(SC.util.Caps.InternetExplorer, null, { major: 11 }))) {
				SC.launch.startJoinSession(
					{ session: session, hostAccessToken: hostAccessToken, processType: hostAccessToken ? SC.types.ProcessType.Host : SC.types.ProcessType.Guest },
					function (joinInfo, _, onSuccess, onFailure) {
						onSuccess(
							SC.util.getClientLaunchParameters(
								joinInfo.session.SessionID,
								joinInfo.session.SessionType,
								joinInfo.session.Name,
								joinInfo.fieldMap.participantName.value,
								null,
								joinInfo.hostAccessToken,
								joinInfo.processType
							)
						);
					}
				);
			}
		});

		SC.event.addGlobalHandler(SC.event.QueryJoinInfo, function (eventArgs) {
			if (eventArgs.session) {
				eventArgs.shouldShowPrompt = SC.util.getSessionTypeBooleanResource('JoinPanel.{0}PromptVisible', eventArgs.session.SessionType);
				eventArgs.promptText = SC.util.getSessionTypeResource('JoinPanel.{0}PromptMessage', eventArgs.session.SessionType);
				eventArgs.buttonText = SC.util.getSessionTypeResource('JoinPanel.{0}PromptButtonText', eventArgs.session.SessionType);

				eventArgs.fieldMap.participantName = {
					labelText: SC.util.getSessionTypeResource('JoinPanel.{0}ParticipantNameLabelText', eventArgs.session.SessionType),
					value: '',
					visible: SC.util.getSessionTypeBooleanResource('JoinPanel.{0}PromptParticipantNameVisible', eventArgs.session.SessionType),
				};
			}
		});

		SC.event.addGlobalHandler(SC.event.QueryParticipantJoinedCount, function (eventArgs) {
			var sessionInfo = window.getSessionInfo();
			var session = sessionInfo.Sessions.find(function (s) { return s.SessionID === eventArgs.clientLaunchParameters.s; });

			if (session !== undefined)
				eventArgs.participantJoinedCount = session.ActiveConnections.filter(function (ac) {
					if (eventArgs.clientLaunchParameters.n)
						return ac.ProcessType == SC.types.ProcessType.Host;

					return ac.ProcessType == SC.types.ProcessType.Guest && ac.ParticipantName == eventArgs.clientLaunchParameters.r;
				}).length;
		});

		SC.event.addGlobalHandler(SC.event.QueryPanels, function (eventArgs) {
			switch (eventArgs.area) {
				case 'GuestActionPanel':
					eventArgs.panelDefinitions.push({
						initProc: function (container) {
							SC.ui.setContents(container, $div({ className: 'Loading' }));
						},
						isVisibleProc: function (pass, previousPassVisibleCount, sessionInfo) {
							return pass == 1 && sessionInfo == null;
						}
					});

					eventArgs.panelDefinitions.push({
						initProc: function (container) {
							SC.ui.setContents(container, [
								$a({ _commandName: 'JoinByTag', _commandArgument: 'DefaultSession', className: 'GoLink Large', _attributeMap: { 'aria-label': SC.res['GuestActionPanel.ButtonDescription'] } }),
								$h2({ _htmlResource: 'GuestActionPanel.InvitationSession.Heading' }),
								$p({ _htmlResource: 'GuestActionPanel.InvitationSession.Message' }),
							]);
						},
						isVisibleProc: function (pass, previousPassVisibleCount, sessionInfo) {
							return pass == 3 &&
								previousPassVisibleCount == 0 &&
								sessionInfo != null &&
								sessionInfo.Sessions.find(function (s) { return s.SessionID == window.getTaggedSessionInfo('DefaultSession').SessionID; });
						}
					});

					eventArgs.panelDefinitions.push({
						initProc: function (container) {
							SC.ui.setContents(container, [
								$h2({ _htmlResource: 'GuestActionPanel.CodeSession.Heading' }),
								$p({ _htmlResource: 'GuestActionPanel.CodeSession.Message' }),
								$p({ className: 'GuestActionBar' }, [
									SC.ui.createSearchTextBox({ _commandName: 'JoinByTag', _commandArgument: 'DefaultCode', value: window.getTaggedSessionInfo('DefaultCode').Code || '' }, function (eventArgs) {
										var sessionCode = SC.util.getTrimmedOrNull(SC.event.getElement(eventArgs).value);
										window.setTaggedSessionInfo('DefaultCode', { Code: sessionCode });
									}),
									$a({ _commandName: 'JoinByTag', _commandArgument: 'DefaultCode', className: 'GoLink Medium', _attributeMap: { 'aria-label': SC.res['GuestActionPanel.ButtonDescription'] } }),
								]),
							]);
						},
						isVisibleProc: function (pass, previousPassVisibleCount, sessionInfo) {
							return pass == 5 && previousPassVisibleCount == 0 && sessionInfo != null && sessionInfo.DoNonPublicCodeSessionsExist;
						},
						refreshProc: function (container, sessionInfo, wasMadeVisible) {
							var taggedSessionInfo = window.getTaggedSessionInfo('DefaultCode');

							SC.ui.setDisabled(
								SC.ui.findDescendentByTag(container, 'A'),
								!sessionInfo.Sessions.find(function (s) { return taggedSessionInfo.Code && s.Code.toLowerCase() == taggedSessionInfo.Code.toLowerCase(); })
							);

							if (wasMadeVisible)
								SC.ui.findDescendentByTag(container, 'INPUT').focus();
						}
					});

					eventArgs.panelDefinitions.push({
						initProc: function (container) {
							SC.ui.setContents(container, [
								$h2({ _htmlResource: 'GuestActionPanel.PublicSession.Heading' }),
								$p({ _htmlResource: 'GuestActionPanel.PublicSession.Message' }),
								$p({ className: 'GuestActionBar' }, [
									$select(),
									$a({ _commandName: 'JoinBySessionID', className: 'GoLink Medium', _attributeMap: { 'aria-label': SC.res['GuestActionPanel.ButtonDescription'] } }),
								]),
							]);

							SC.event.addHandler(SC.ui.findDescendentByTag(container, 'SELECT'), 'change', function (eventArgs) {
								var selectBox = SC.event.getElement(eventArgs);
								SC.ui.findDescendentByTag(container, 'A')._commandArgument = selectBox.options[selectBox.selectedIndex].value;
							});
						},
						isVisibleProc: function (pass, previousPassVisibleCount, sessionInfo) {
							return pass == 5 && previousPassVisibleCount == 0 && sessionInfo != null && sessionInfo.Sessions.filter(function (s) { return s.IsPublic; }).length > 0;
						},
						refreshProc: function (container, sessionInfo, wasMadeVisible) {
							var selectBox = SC.ui.findDescendentByTag(container, 'SELECT');
							var link = SC.ui.findDescendentByTag(container, 'A');

							SC.ui.setContents(selectBox,
								sessionInfo.Sessions.filter(function (s) { return s.IsPublic; }).map(function (s) {
									return $option({ value: s.SessionID }, s.Name);
								})
							);

							var optionIndex = Array.prototype.findIndex.call(selectBox.options, function (o) { return o.value == link._commandArgument; });

							if (optionIndex != -1)
								selectBox.selectedIndex = optionIndex;
							else
								link._commandArgument = selectBox.options[selectBox.selectedIndex].value;
						}
					});

					eventArgs.panelDefinitions.push({
						initProc: function (container) {
							SC.ui.setContents(container, [
								$h2({ _htmlResource: 'GuestActionPanel.NoAvailableSessions.Heading' }),
								$p({ _htmlResource: 'GuestActionPanel.NoAvailableSessions.Message' }),
							]);
						},
						isVisibleProc: function (pass, previousPassVisibleCount, sessionInfo) {
							return pass == 8 && previousPassVisibleCount == 0;
						}
					});

					break;
			}
		});

		SC.event.addGlobalHandler(SC.event.QueryLiveData, function (eventArgs) {
			var getTaggedValuesFunc = function (propertyName) {
				return Object.keys(window._taggedSessionInfos)
					.map(function (key) { return window._taggedSessionInfos[key]; })
					.filter(function (_) { return _[propertyName]; })
					.map(function (_) { return _[propertyName]; });
			}

			eventArgs.requestInfoMap['GuestSessionInfo'] = {
				sessionCodes: getTaggedValuesFunc('Code'),
				sessionIDs: getTaggedValuesFunc('SessionID'),
			};
		});

		SC.event.addGlobalHandler(SC.event.PreRender, function () {
			window._taggedSessionInfos = {};

			SC.css.ensureClass(document.documentElement, 'ShowMenu', false);

			var queryStringMap = SC.util.parseQueryString(window.location.search);
			window.setTaggedSessionInfo('DefaultCode', { Code: queryStringMap.Code });
			window.setTaggedSessionInfo('DefaultSession', { SessionID: queryStringMap.Session, HostAccessToken: queryStringMap.HostAccessToken });

			var actionPanel = $('.ActionPanel');

			SC.panellist.queryAndInitializePanels(actionPanel);
			SC.panellist.refreshPanels(actionPanel, null);
		});

		SC.event.addGlobalHandler(SC.event.LiveDataRefreshed, function () {
			SC.panellist.refreshPanels($('.ActionPanel'), window.getSessionInfo());

			if (!window._hasJoinedDefault && !SC.util.isCapable(SC.util.Caps.InternetExplorer, null, { major: 11 })) {
				SC.command.dispatchExecuteCommand(window.document.body, window.document.body, window.document.body, 'JoinByTag', 'DefaultSession');
				window._hasJoinedDefault = true;
			}
		});

	</script>

	<script>

		SC.event.addGlobalHandler(SC.event.QueryCommandButtons, function (eventArgs) {
			switch (eventArgs.area) {
				case 'TrayIconPanel':
					eventArgs.buttonDefinitions.push({ commandName: 'ActionCenter', imageUrl: 'Images/ActionCenter.svg' });

					if (SC.context.isUserAdministrator)
						eventArgs.buttonDefinitions.push({ commandName: 'Navigate', commandArgument: 'Administration', imageUrl: 'Images/NavigationAdministration.svg' });

					eventArgs.buttonDefinitions.push(
						{ commandName: 'Extras', imageUrl: 'Images/Extras.svg' },
						{ commandName: 'Applications', imageUrl: 'Images/Applications.svg' }
					);
					break;
				case 'ExtrasNavigationPopoutPanel':
					eventArgs.buttonDefinitions.push(
						{ commandName: 'NavigateExtensionBrowser' }
					);
					break;
				case 'ToolsPanel':
					eventArgs.buttonDefinitions.push(
						{ commandName: 'Extras', imageUrl: 'Images/Extras.svg' },
						{ commandName: 'Login' }
					);
					break;
				case 'UserPopoutPanel':
					eventArgs.buttonDefinitions.push(
						{ commandName: 'NavigateControlPanel' },
						{ commandName: 'ChangePassword' },
						{ commandName: 'Logout' }
					);
					break;
				case 'UserHelpPopoutPanel':
					if (SC.context.pageType !== 'GuestPage' && SC.context.pageType != 'LoginPage') {
						eventArgs.buttonDefinitions.push({ commandName: 'GiveFeedback' });

						for (var i = 1; ; i++) {
							var resourceValue = SC.res['HelpPanel.Link' + i + '.Text'];

							if (resourceValue === undefined || resourceValue === '')
								break;

							var url = SC.util.sanitizeUrl(SC.res['HelpPanel.Link' + i + '.Url']);
							eventArgs.buttonDefinitions.push({ commandName: 'NavigateHelpLink', commandArgument: url, text: resourceValue, title: url });
						}
					}
					break;
			}
		});

		SC.event.addGlobalHandler(SC.event.QueryCommandButtonState, function (eventArgs) {
			switch (eventArgs.commandName) {
				case 'User':
				case 'ActionCenter':
					eventArgs.isVisible = SC.context.isUserAuthenticated;
					break;
				case 'Login':
					eventArgs.isVisible = SC.context.pageType != 'SetupWizardPage' && !SC.context.isUserAuthenticated && !SC.util.isCapable(SC.util.Caps.InternetExplorer, null, { major: 12 }); // Login page doesn't support IE
					break;
				case 'NavigateControlPanel':
					eventArgs.isVisible = !!SC.context.controlPanelUrl;
					break;
				case 'ChangePassword':
					eventArgs.isVisible = SC.context.canChangePassword;
					break;
				case 'Extras':
					eventArgs.isVisible = SC.popout.computePopoutCommandsVisible(eventArgs, ['', 'Navigation']);
					break;
				case 'Applications':
				case 'Help':
					eventArgs.isVisible = SC.popout.computePopoutCommandsVisible(eventArgs);
					break;
				case 'NavigateExtensionBrowser':
					eventArgs.isVisible = SC.context.isUserAdministrator;
					break;
			}
		});

		SC.event.addGlobalHandler(SC.event.ExecuteCommand, function (eventArgs) {
			switch (eventArgs.commandName) {
				case 'Extras':
					SC.popout.showPanelFromCommand(eventArgs, null, { subAreas: ['', 'Navigation'] });
					break;
				case 'Applications':
					SC.popout.showPanelFromCommand(eventArgs);
					break;
				case 'ActionCenter':
					SC.popout.showPanelFromCommand(eventArgs, null, {
						buildProc: function (popoutPanel) {
							var actionCenterInfo = SC.livedata.getResponseInfo(SC.livedata.ActionCenterInfo);

							SC.ui.setContents(popoutPanel, $div({ className: 'ActionCenterPanel' }, [
								$h2({ _textResource: 'ActionCenterPanel.Text' }),
								$ul({ className: 'List', _visible: SC.util.any(actionCenterInfo.ActionItems) },
									(actionCenterInfo.ActionItems || [])
										.map(function (it) {
											var parsedEventData = SC.util.parseEventData(it.Data);

											return $li({
												_eventHandlerMap: {
													click: function () {
														window.location.href = SC.nav.getHostUrl({
															sessionType: it.SessionType,
															sessionID: it.SessionID,
															tabName: SC.nav.getHostTabName(it.EventType),
															tabContext: it.EventID
														});
													},
												}
											}, [
												$img({ src: 'Images/Notification' + SC.util.getEnumValueName(SC.types.SessionEventType, it.EventType) + '.svg' }),
												$h3({ className: 'Type' }, SC.res['SessionEvent.' + SC.util.getEnumValueName(SC.types.SessionEventType, it.EventType) + '.Title']),
												$p({ className: 'Name', title: it.Name }, it.Name),
												$p({ className: 'DataContent', title: parsedEventData.content }, parsedEventData.content),
												$p({ className: 'Time' }, SC.util.formatDateTime(it.Time, { includeRelativeDate: true })),
											])
										})
								),
								$div({ className: 'EmptyPanel', _visible: !SC.util.any(actionCenterInfo.ActionItems) }, [
									$p($img({ src: 'images/EmptyActionCenter.svg' })),
									$h4({ _textResource: 'ActionCenterPanel.EmptyHeader' }),
									$p({ _textResource: 'ActionCenterPanel.EmptyText' }),
								]),
							]));
						},
					});
					break;
				case 'Login':
					SC.util.sendToLogin(SC.types.LoginReason.None, false);
					break;
				case 'Logout':
					SC.util.sendToLogin(SC.types.LoginReason.Logout, false);
					break;
				case 'User':
					SC.popout.showPanelFromCommand(eventArgs, null, { subAreas: ['Help', ''] });
					break;
				case 'NavigateControlPanel':
					window.open(SC.util.sanitizeUrl(SC.context.controlPanelUrl));
					break;
				case 'ChangePassword':
					var params = {};
					params[SC.context.loginUserNameParameterName] = eventArgs.commandArgument;
					window.location.href = SC.context.changePasswordPageUrl + SC.util.getQueryString(params);
					break;
				case 'NavigateHelpLink':
					window.open(eventArgs.commandArgument);
					break;
				case 'ToggleMenu':
					SC.css.toggleClass(document.documentElement, 'ShowMenu');
					break;
				case 'GiveFeedback':
					SC.dialog.showModalButtonDialog(
						'GiveFeedback',
						SC.res['Command.GiveFeedback.Text'],
						SC.res['Command.GiveFeedback.ButtonText'],
						'Default',
						function (container) {
							SC.ui.setContents(container, [
								$div({ _textResource: 'GiveFeedbackPanel.ReviewLabelText' }),
								$div({ className: 'RatingSelectionPanel' },
									['Good', 'Neutral', 'Bad'].map(function (rating) {
										return $span(
											$label({ className: rating }, [
												$input({ type: 'radio', name: 'rating', value: rating.toLowerCase() }),
												$div({ className: 'RadioImage' }),
												$span({ _textResource: 'GiveFeedbackPanel.' + rating + 'RatingLabelText' }),
											])
										);
									})
								),
								$div([
									$label({ _textResource: 'GiveFeedbackPanel.EmailLabelText' }, [
										$input({ type: 'email', id: 'email' }),
									]),
								]),
								$div([
									$label({ _textResource: 'GiveFeedbackPanel.CommentsLabelText' }, [
										SC.ui.createTextBox({ id: 'commentsBox' }, true),
									]),
								]),
							]);
						},
						function (eventArgs) {
							SC.service.SendFeedback(
								Array.prototype.map.call(document.querySelectorAll('input[name=rating]:checked'), function (e) { return e.value; })[0],
								$('commentsBox').value,
								$('email').value,
								function () {
									SC.dialog.showModalMessageBox(
										SC.res['GiveFeedbackPanel.SuccessHeading'],
										SC.res['GiveFeedbackPanel.SuccessMessage']
									);
								}
							);
						}
					);
					break;
				case 'ManageToolbox':
					SC.toolbox.showToolboxDialog(eventArgs.commandName, eventArgs.commandArgument);
					break;
				case 'Navigate':
					window.location.href = eventArgs.commandArgument;
					break;
				case 'NavigateExtensionBrowser':
					window.location.href = SC.context.administrationPageUrl + '?Tab=Extensions#ShowExtensionBrowser';
					break;
			}
		});

		SC.event.addGlobalHandler(SC.event.QueryNavigationLinks, function (eventArgs) {
			Array.prototype.push.apply(eventArgs.navigationLinks, SC.context.sessionTypeInfos.map(function (_) {
				return {
					href: SC.context.scriptBaseUrl + SC.context.hostPageUrl + '#' + SC.util.getEnumValueName(SC.types.SessionType, _.sessionType),
					text: SC.util.getSessionTypeResource('NavigationPanel.{0}LinkText', _.sessionType),
					imageUrl: SC.util.formatString('Images/Navigation{0}.svg', SC.util.getEnumValueName(SC.types.SessionType, _.sessionType)),
					sessionType: _.sessionType,
				}
			}));

			if (SC.context.isUserAdministrator && SC.context.canDisplayPAMDashboard)
				eventArgs.navigationLinks.push({
					href: SC.context.scriptBaseUrl + 'PAM',
					text: 'PAM',
					imageUrl: 'Images/PAMIcon.png',
				});
		});

		SC.event.addGlobalHandler(SC.event.QueryLiveData, function (eventArgs) {
			if (SC.context.isUserAuthenticated)
				SC.livedata.setRequestInfo(eventArgs, SC.livedata.ActionCenterInfo);
		});

		SC.event.addGlobalHandler(SC.event.LiveDataRefreshed, function () {
			SC.css.ensureClass($('.NavigationPanel .TrayIconPanel .ActionCenter'), 'NonEmpty', SC.util.any(SC.livedata.getResponseInfo(SC.livedata.ActionCenterInfo).ActionItems));
		});

		SC.event.addGlobalHandler('keydown', function (eventArgs) {
			if (SC.event.doesKeyEventIndicateTextEntryOrArrowKeyNavigation(eventArgs) && (!document.activeElement || SC.ui.isDefinitelyNotTextEntryElement(document.activeElement))) {
				var arrowKeyInfo = SC.event.getArrowKeyInfo(eventArgs);

				if (arrowKeyInfo && document.activeElement && SC.css.containsClass(document.activeElement, 'ArrowNavigation')) {
					eventArgs.preventDefault();
					SC.ui.setHiddenFocusAndClearOthers();

					var targetPreviousOrNext = arrowKeyInfo.isLeft || arrowKeyInfo.isUp;

					SC.event.dispatchEvent(document.activeElement, SC.event.KeyNavigation, {
						currentActiveElement: document.activeElement,
						currentSelectedElement: SC.ui.findDescendantBreadthFirst(document.activeElement, function (_) { return SC.ui.isSelected(_); }, !targetPreviousOrNext),
						targetPreviousOrNext: targetPreviousOrNext,
						arrowKeyInfo: arrowKeyInfo,
						hasShift: eventArgs.shiftKey,
					});
				} else {
					var queryTextEntryElementArgs = SC.event.dispatchGlobalEvent(SC.event.QueryTextEntryElement, {
						textEntryElement: null,
					});

					if (queryTextEntryElementArgs.textEntryElement) {
						if (!SC.event.doesKeyEventIndicateTextEntryNavigation(eventArgs))
							queryTextEntryElementArgs.textEntryElement.value = '';

						queryTextEntryElementArgs.textEntryElement.focus();
					}
				}
			}
		});

		SC.event.addGlobalHandler(SC.event.KeyNavigation, function (eventArgs) {
			// default handling for key navigation
			var elementToNavigateTo;

			if (eventArgs.currentSelectedElement) {
				elementToNavigateTo = SC.ui.getPreviousOrNextElementSibling(eventArgs.currentSelectedElement, eventArgs.targetPreviousOrNext) || eventArgs.currentSelectedElement;

				while (SC.util.isNullOrEmpty(elementToNavigateTo._commandName) && SC.ui.getPreviousOrNextElementSibling(elementToNavigateTo, eventArgs.targetPreviousOrNext)) {
					elementToNavigateTo = SC.ui.getPreviousOrNextElementSibling(elementToNavigateTo, eventArgs.targetPreviousOrNext);
				}
			} else {
				elementToNavigateTo = SC.ui.findDescendantBreadthFirst(eventArgs.currentActiveElement, function (_) { return !SC.util.isNullOrEmpty(_._commandName); }); // this can still be empty
			}

			SC.util.tryNavigateToElementUsingCommand(elementToNavigateTo, eventArgs.targetPreviousOrNext, eventArgs.hasShift);
		});

		SC.event.addGlobalHandler(SC.event.PreRender, function () {
			var resetInactivityProc = function () {
				window._lastNotifyActivityTime = new Date().getTime();

				if (SC.context.isUserAuthenticated && SC.context.loginAfterInactivityMilliseconds != 0) {
					if (window._loginAfterInactivityTimer)
						window.clearTimeout(window._loginAfterInactivityTimer);

					window._loginAfterInactivityTimer = window.setTimeout(function () { SC.util.sendToLogin(SC.types.LoginReason.IdleTooLong, true); }, Math.min(SC.context.loginAfterInactivityMilliseconds, 2147483647)); //interval stored as 32-bit signed int
				}
			};

			SC.context.prehandleServiceFailureProc = function (error) {
				if (error.statusCode === 403) {
					SC.util.sendToLogin(SC.types.LoginReason.PermissionsInsufficient, true);
					return true;
				}
				// we could send them to login page like this, but we'd rather just show the error in place (dialog, etc.) since the UI doesn't know ahead of time if an action might fail an access policy check
				// if (error.statusCode === 456) {
				// 	SC.util.sendToLogin(SC.types.LoginReason.AccessPolicyViolation, true);
				// 	return true;
				// }
				return false;
			}

			SC.context.unhandledServiceFailureProc = function (error) {
				SC.dialog.showModalErrorBox(error.detail || error.message);
			}

			resetInactivityProc();

			SC.ui.initializeWindowActivityTracking(function () {
				if (new Date().getTime() - window._lastNotifyActivityTime > SC.context.notifyActivityFrequencyMilliseconds) {
					resetInactivityProc();
					SC.service.NotifyActivity();
				}
			});

			var parameterlessUrl = SC.util.getParameterlessUrl(window.location.href);
			var createNavigationLinkFunc = function (_) {
				return $div({ _commandName: 'Navigate', _commandArgument: _.href, _selected: _.href == parameterlessUrl }, [
					$img({ src: _.imageUrl }),
					$span(_.text),
				]);
			};

			SC.ui.setContents($('.HeaderPanel'), [
				$a({ href: SC.context.guestPageUrl, className: 'LogoIconLink' }),
				$a({ _commandName: 'ToggleMenu', className: 'ShowMenuButton' }, ''),
				$h1({ className: 'LogoPanel' }),
				$div({ className: 'CommandPanel' }),
			]);

			SC.command.queryAndAddCommandButtons($('.HeaderPanel .CommandPanel'), 'ToolsPanel');
			SC.command.updateCommandButtonsState($('.HeaderPanel .CommandPanel'));

			var queryNavigationLinksEventArgs = SC.event.dispatchGlobalEvent(SC.event.QueryNavigationLinks, { navigationLinks: [] })

			SC.ui.setContents($('.NavigationPanel'), [
				queryNavigationLinksEventArgs.navigationLinks.map(createNavigationLinkFunc),
				$div({ className: 'FlexSpacer' }),
				$div({ className: 'TrayPanelContainer' }, [
					$div({ className: 'TrayIconPanel' }),
					$div({ className: 'UserMenuButton', _commandName: 'User' },
						$span(SC.context.userDisplayName == null ? '' : SC.context.userDisplayName.toUpperCase()[0]),
						$span(SC.context.userDisplayName)
					),
				]),
			]);

			SC.command.queryAndAddCommandButtons($('.NavigationPanel .TrayIconPanel'), 'TrayIconPanel', null, { descriptionRenderStyle: SC.command.DescriptionRenderStyle.Tooltip });
			SC.command.updateCommandButtonsState($('.NavigationPanel .TrayIconPanel'));

			var setSelectedFunc = function () {
				$$('.NavigationPanel > div')
					.filter(function (_) { return !SC.util.isNullOrEmpty(_._commandArgument); })
					.forEach(function (_) { SC.ui.setSelected(_, window.location.href.startsWith(_._commandArgument)); });
			};

			SC.event.addHandler(window, 'hashchange', setSelectedFunc);

			setSelectedFunc();

			SC.livedata.startLoop();
		});

		var isTouchEnabled = (typeof document.documentElement.ontouchstart !== 'undefined');
		SC.css.ensureClass(document.documentElement, 'TouchEnabled', isTouchEnabled);
		SC.css.ensureClass(document.documentElement, 'TouchDisabled', !isTouchEnabled);
		SC.css.ensureClass(document.documentElement, 'UserAuthenticated', SC.context.isUserAuthenticated);
		SC.css.ensureClass(document.documentElement, 'NativeClient', SC.util.isCapable(SC.util.Caps.NativeClient));
		SC.css.ensureClass(document.documentElement, 'HasMasterPanel', $('.MasterPanel'));
		SC.css.ensureClass(document.documentElement, 'LogoImageVisible', SC.util.getBooleanResource('LogoPanel.ImageVisible'));
		SC.css.ensureClass(document.documentElement, 'LogoIconVisible', SC.util.getBooleanResource('LogoPanel.IconVisible'));
		SC.css.ensureClass(document.documentElement, 'LogoHeadingVisible', SC.util.getBooleanResource('LogoPanel.HeadingVisible'));
		SC.css.ensureClass(document.documentElement, 'AnimationReduced', SC.util.getBooleanResource('Page.AnimationReduced'));
		SC.css.ensureClass(document.documentElement, SC.context.pageType, true);

		SC.extension.initializeExtensions();
		SC.event.dispatchGlobalEvent(SC.event.PreRender);
		SC.util.recordLifeCycleEvent(SC.event.PreRender);
		SC.ui.setVisible(document.body, true);
		SC.event.dispatchGlobalEvent(SC.event.PostRender);
		SC.util.recordLifeCycleEvent(SC.event.PostRender);

		$$('*[tabIndex]').forEach(function (_) {
			SC.event.addHandler(_, 'mousedown', function () {
				SC.ui.setHiddenFocusAndClearOthers(_);
			});
		});

		if (SC.context.focusedControlID)
			$(SC.context.focusedControlID).focus();
		else if (document.activeElement == document.body) {
			$('.NavigationPanel').focus();
			SC.ui.setHiddenFocusAndClearOthers($('.NavigationPanel'));
		}

	</script>
</body>
</html>
