diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..82fc81c --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ + +.vs/VSWorkspaceState.json +.vs/slnx.sqlite +.vs/GenericConfigGen/v17/.wsuo +.vs/GenericConfigGen/FileContentIndex/read.lock +.vs/GenericConfigGen/FileContentIndex/39c65145-15d2-48a1-9ecc-4f556d7ffacc.vsidx +.vs/GenericConfigGen/config/applicationhost.config +.vs/GenericConfigGen/FileContentIndex/85de9f2b-bb18-4c34-bba3-5fb4ba6dc3c9.vsidx +.vs/GenericConfigGen/FileContentIndex/2a9b0deb-b4b1-4da6-be2c-8bcb77feecf5.vsidx +*.vsidx +.vs/ProjectSettings.json +index2.html diff --git a/FileSaver.min.js b/FileSaver.min.js new file mode 100644 index 0000000..6d493b2 --- /dev/null +++ b/FileSaver.min.js @@ -0,0 +1,3 @@ +(function(a,b){if("function"==typeof define&&define.amd)define([],b);else if("undefined"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){"use strict";function b(a,b){return"undefined"==typeof b?b={autoBom:!1}:"object"!=typeof b&&(console.warn("Deprecated: Expected third argument to be a object"),b={autoBom:!b}),b.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\uFEFF",a],{type:a.type}):a}function c(a,b,c){var d=new XMLHttpRequest;d.open("GET",a),d.responseType="blob",d.onload=function(){g(d.response,b,c)},d.onerror=function(){console.error("could not download file")},d.send()}function d(a){var b=new XMLHttpRequest;b.open("HEAD",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent("click"))}catch(c){var b=document.createEvent("MouseEvents");b.initMouseEvent("click",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f="object"==typeof window&&window.window===window?window:"object"==typeof self&&self.self===self?self:"object"==typeof global&&global.global===global?global:void 0,a=/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),g=f.saveAs||("object"!=typeof window||window!==f?function(){}:"download"in HTMLAnchorElement.prototype&&!a?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement("a");g=g||b.name||"download",j.download=g,j.rel="noopener","string"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target="_blank")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:"msSaveOrOpenBlob"in navigator?function(f,g,h){if(g=g||f.name||"download","string"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement("a");i.href=f,i.target="_blank",setTimeout(function(){e(i)})}}:function(b,d,e,g){if(g=g||open("","_blank"),g&&(g.document.title=g.document.body.innerText="downloading..."),"string"==typeof b)return c(b,d,e);var h="application/octet-stream"===b.type,i=/constructor/i.test(f.HTMLElement)||f.safari,j=/CriOS\/[\d]+/.test(navigator.userAgent);if((j||h&&i||a)&&"undefined"!=typeof FileReader){var k=new FileReader;k.onloadend=function(){var a=k.result;a=j?a:a.replace(/^data:[^;]*;/,"data:attachment/file;"),g?g.location.href=a:location=a,g=null},k.readAsDataURL(b)}else{var l=f.URL||f.webkitURL,m=l.createObjectURL(b);g?g.location=m:location.href=m,g=null,setTimeout(function(){l.revokeObjectURL(m)},4E4)}});f.saveAs=g.saveAs=g,"undefined"!=typeof module&&(module.exports=g)}); + +//# sourceMappingURL=FileSaver.min.js.map \ No newline at end of file diff --git a/common.js b/common.js index 75d71d2..e23aa41 100644 --- a/common.js +++ b/common.js @@ -29,4 +29,31 @@ if (!String.prototype.template) { ; }); }; +} + +function WildcardToRegex(pattern) { + if (pattern == null) { return null; } + + var escapeReplace = function (data, original, replacement) { + var searchRegex = new RegExp("\\\\+\\" + original); + var newRegex = data.replace(searchRegex, function (match) { + var count = match.length - 1; + var halfCount = Math.floor(count / 2); + var newSlashes = Array(halfCount).join("\\"); + var result = newSlashes + ((halfCount % 2 === 0) ? replacement : original); + return result; + }); + return newRegex; + }; + + var toRegex = function (pattern, starMatchesEmpty) { + var reg = "^" + pattern.replace(/([.*+?^${}()|[\]/\\])/g, "\\$1") + "$"; + reg = reg.replace(/\d+/g, "\\d+"); // replace all numbers with \d+ + reg = reg.replace(/\s+/g, "\\s+"); // replace all numbers with \d+ + reg = reg.replace(/\\\*\\\{(\w+)\\\}/g, "(?<$1>.+)"); // replace *{} with named capture group + reg = reg.replace(/\(\?\.\+\)/g, ".*"); // replace *{} with named capture group + return reg; + }; + + return toRegex(pattern, false); } \ No newline at end of file diff --git a/default.html b/default.html deleted file mode 100644 index 5802a28..0000000 --- a/default.html +++ /dev/null @@ -1,1047 +0,0 @@ - - - - - AMP Configuration Generator - - - - - - - - - - - - - - -
-
- - -
-
-

AMP Configuration Generator

- Version 1.0
©2021 CubeCoders Limited
-
-
- - - -
-
-
- -
-
- -
-
-

Basic Information

-
-
- - -
This is what will show up within AMP as the name of the - application. -
-
-
- - -
Optional: useful for describing different variants/configurations - of - the same application.
-
-
-
-
- - -
Who are you? Take some credit for your work!
-
-
- - -
A link to where you can learn more about the application, such as - a store listing.
-
-
-
- -
- - -
-
-

Management and Console

-
- -
- - - - - - - - -
-
-
-
- -
This is in addition to the applications management type if it - accepts management over methods other than Standard IO
-
- - -
-
- -

Networking

-
AMP will automatically generate firewall rules to allow the application - ports through
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Port NumberUsage Type
- - - -
No ports have been added.
- You may add up to 3 ports. The RCON port does - not count towards this limit.
Maximum of 1 Steam Query and 1 RCON - Port.
-
- - - -
-

Update Sources

-
- -
- - - - - -
-
- -
- - -
This must be a direct URL that is not behind any access - gates.
-
-
- - - Unzip once downloaded - The downloaded file is a .zip that needs to be - decompressed. Does not support other archive types (such as .tar.gz) at this - time. - -
- - -
- - -
The App ID for the dedicated server application. You can find - this via SteamDB.
-
-
- - -
The App ID for the game itself. You can find this via SteamDB.
-
- - -
- - -
Must be a publicly accessible GitHub repository.
-
- - -
- - -
PNG or JPEG format, 460x215px.
-
- -
-
-
-

Configuration and Settings

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Display NameDescriptionField NameDefault ValueCommand Line
- - -
No settings have been added.
- -
- -

Startup and Shutdown

-
Application and Parameters
-
-
- - -
-
- - -
-
-
- - -
Don't include any arguments that come from the Configuration and - Settings section above. - -
-
-
-
- - -
The format to be used to add settings specified above to the - command line in place of {{$FormattedArgs}}. {0} is the field name and {1} the - value.
-
-
- - -
The character(s) used to separate different arguments in the - command line flags generated by settings. By default this is a single space.
-
-
-
- -
- - -
-
-
- -
- - - -
-
-
Shutdown
-
-
- - -
-
- - -
-
-

Server Events

-

These are regular expressions that when matched notifies AMP about in-application events such - as a successful startup, or users connecting/disconnecting. AMP will match these based on - output from either the servers standard output (if enabled) or whichever RCON/remote access - protocol is in use.

-

All expressions must match the entire subject string - so they must always start with a ^ and - end with a $. AMP uses named capture groups to pick out different components of an - expression.

-

Regex101 is an excellent resource to help you put together - and validate expressions. AMP uses the 'Javascript' regex flavour.

-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-

Validate and Review

-
- - -
This is generated assuming the default values and default port - numbers, these will change based on user-specified values or assignments made by AMP. -
-
-
-

- -

-

- - - -   - You have not yet validated your configuration. You will not be able to download your configuration until you have done this.

-

- - - -   - Validation Failed - You must address the following failures before you may continue.

-

- - - -   - Validation Passed with Warnings - You should consider addressing the following warnings.

-

- - - -   - Validation Passed - Great stuff! You may now download the completed configuration below.

-
-
-
Validation Issues:
- - - - - - - - - - - - - - - - - - - - - - -
Category - Issue - Recommentation -
-
Impact: -
No validation issues -
-
-
-
- - -
-

- - - -   - Make sure to keep a backup of your configuration by using the 'Export' option at the top of the page! You will need this to make further changes even after downloading the configuration and manifest.

-
-
-
Using the generated configuration
-

Place the .kvp and .json files in your ADS instance under the /Plugins/ADSModule/GenericTemplates directory along side the other .kvp and .json files.

-

Then restart ADS, and your new configuration will appear as an option when you select 'Create Instance'.

-
-

 

-
-
-
- -
-
-

Generated Data

- Values that are calculated automatically based on your input. - - - - - - - - - - - - -
-
- - - No Generated Value - -
-
-
- - - No Generated Value - -
-
-
-
-
- - - - - - - - - \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..3d91732 Binary files /dev/null and b/favicon.ico differ diff --git a/generator.js b/generator.js index 4796a7d..8c365ae 100644 --- a/generator.js +++ b/generator.js @@ -1,15 +1,12 @@ -function omitNonPublicMembers(key, value) -{ +function omitNonPublicMembers(key, value) { return (key.indexOf("_") === 0) ? undefined : value; } -function omitPrivateMembers(key, value) -{ +function omitPrivateMembers(key, value) { return (key.indexOf("__") === 0) ? undefined : value; } -function downloadString(data, filename) -{ +function downloadString(data, filename) { var element = document.createElement('a'); element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(data)); element.setAttribute('download', filename); @@ -20,14 +17,37 @@ function downloadString(data, filename) document.body.removeChild(element); } +ko.validation.init(); + class generatorViewModel { constructor() { var self = this; - - this.Meta_DisplayName = ko.observable(""); + this._availablePortOptions = ko.observableArray(['Custom Port', 'Main Game Port', 'Steam Query Port', 'RCON Port']); + this._compatibility = ko.observable("None"); + this.Meta_DisplayName = ko.observable("").extend({ required: "Please enter a first name" }); this.Meta_Description = ko.observable(""); - this.Meta_Author = ko.observable(""); + this.Meta_Arch = ko.observable("x86_64"); + this._Meta_Author = ko.observable(""); + this.Meta_Author = ko.computed(() => self._Meta_Author() + ' - Made with AMP Config Generator'); + this._Meta_GithubOrigin = ko.computed(() => 'https://github.com/' + self.Meta_Author() + '/AMPTemplates.git'); + this._Meta_GithubURL = ko.computed(() => 'https://github.com/' + self.Meta_Author() + '/AMPTemplates'); this.Meta_URL = ko.observable(""); + this.Meta_MinAMPVersion = ko.observable("2.4.6.6"); + this.Meta_SpecificDockerImage = ko.computed(() => self._compatibility() != "None" ? (self._compatibility().substring(self._compatibility().length - 4) == "Xvfb" ? `cubecoders/ampbase:xvfb` : `cubecoders/ampbase:wine`) : ``); + this.Meta_DockerRequired = ko.observable("False"); + this.Meta_ContainerPolicy = ko.observable("Supported"); + this.Meta_ContainerPolicyReason = ko.observable(""); + this.Meta_Prerequsites = ko.observable("[]"); + //this.Meta_ExtraContainerPackages = ko.observable(""); + //this.Meta_ConfigReleaseState = ko.observable("NotSpecified"); + //this.Meta_NoCommercialUsage = ko.observable("False"); + this.Meta_EndpointURIFormat = ko.observable(`steam://connect/{ip}:{GenericModule.App.Ports.$SteamQueryPort}`); + this.Meta_AppConfigId = function guid() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + } this._SupportsWindows = ko.observable(true); this._SupportsLinux = ko.observable(true); @@ -36,34 +56,83 @@ class generatorViewModel { this.App_HasReadableConsole = ko.observable(true); this.App_HasWritableConsole = ko.observable(true); this.App_DisplayName = ko.computed(() => this.Meta_DisplayName()); - - this.App_CommandLineArgs = ko.observable("+ip {{$ApplicationIPBinding}} +port {{$ApplicationPort1}} +queryport {{$ApplicationPort2}} +rconpassword \"{{$RemoteAdminPassword}}\" +maxusers {{$MaxUsers}} {{$FormattedArgs}}") + this.App_CommandLineArgs = ko.observable("{{$PlatformArgs}} {{$FormattedArgs}}") + this.App_WindowsCommandLineArgs = ko.observable(""); this.App_CommandLineParameterFormat = ko.observable("-{0} \"{1}\""); this.App_CommandLineParameterDelimiter = ko.observable(" "); - this.App_RapidStartup = ko.observable("false"); this.App_ApplicationReadyMode = ko.observable("Immediate"); - this.App_ExitMethod = ko.observable("String"); + this.App_ExitMethod = ko.observable("OS_CLOSE"); this.App_ExitString = ko.observable("stop"); - - this.Console_ThrowawayMessageRegex = ko.observable("^(WARNING|ERROR): Shader.+$"); - this.Console_AppReadyRegex = ko.observable("^Server is ready.$"); - this.Console_UserJoinRegex = ko.observable("^User (?.+?) \\((?-?\d+)\\) connected from \\[::ffff:(?.+?)\\]$"); - this.Console_UserLeaveRegex = ko.observable("^User (?.+?) \\((?-?\d+)\\) disconnected\\. Reason: (.+?)$"); - this.Console_UserChatRegex = ko.observable("^(?.+?): (?.+)$"); + //this.App_UseLinuxIOREDIR = ko.observable("False"); + this.App_ExitTimeout = ko.observable("30"); + this.App_ExitFile = ko.observable("app_exit.lck"); + this.App_SupportsLiveSettingsChanges = ko.observable("False"); + this.App_LiveSettingChangeCommandFormat = ko.observable("set {0} \"{1}\""); + this.App_ApplicationIPBinding = ko.observable("0.0.0.0"); + this.App_AdminPortRef = ko.observable("RemoteAdminPort"); + this.App_UniversalSleepApplicationUDPPortRef = ko.observable("GamePort1"); + this.App_PrimaryApplicationPortRef = ko.observable("GamePort1"); + this.App_UniversalSleepSteamQueryPortRef = ko.observable("SteamQueryPort"); + this.App_MaxUsers = ko.observable("8"); + this.App_UseRandomAdminPassword = ko.observable("True"); + this.App_RemoteAdminPassword = ko.observable(""); + this.App_AdminLoginTransform = ko.observable("None"); + this.App_RCONConnectDelaySeconds = ko.observable("30"); + this.App_RCONConnectRetrySeconds = ko.observable("15"); + this.App_RCONHeartbeatCommand = ko.observable("ping"); + this.App_RCONHeartbeatMinutes = ko.observable("0"); + this.App_TelnetLoginFormat = ko.observable("{0}"); + this.App_SteamUpdateAnonymousLogin = ko.observable("True"); + this.App_SteamForceLoginPrompt = ko.observable("False"); + this.App_SupportsUniversalSleep = ko.observable("False"); + this.App_WakeupMode = ko.observable("Any"); + this.App_TemplateMatchRegex = ko.observable("{{(\\$?[\\w]+)}}"); + this.App_MonitorChildProcess = ko.observable("False"); + this.App_MonitorChildProcessWaitMs = ko.observable("1000"); + this.App_MonitorChildProcessName = ko.observable(""); + this.App_Compatibility = ko.observable("None"); +// this.App_AppSettings = ko.observableArray(); + this._App_SteamWorkshopDownloadLocation = ko.observable(); + this.App_SteamWorkshopDownloadLocation = ko.computed(() => this._App_SteamWorkshopDownloadLocation() != '' ? "{{$FullBaseDir}}" + this._App_SteamWorkshopDownloadLocation() : ''); + + this.Console_FilterMatchRegex = ko.observable(""); + this.Console_FilterMatchReplacement = ko.observable(""); + this.Console_ThrowawayMessageRegex = ko.observable("(WARNING|ERROR): Shader.+"); + this._Console_AppReadyRegex = ko.observable(""); + this._Console_UserJoinRegex = ko.observable(""); + this._Console_UserLeaveRegex = ko.observable(""); + this._Console_UserChatRegex = ko.observable(""); + this.Console_UpdateAvailableRegex = ko.observable("^\\[\\d\\d:\\d\\d:\\d\\d\\] \\[INFO\\] A new server update is available! v[\\d\\.]+.$"); + //this.Console_MetricsRegex = ko.observable(""); + this.Console_SuppressLogAtStart = ko.observable("False"); + this.Console_ActivateLogRegex = ko.observable(""); + this.Console_UserActions = ko.observable("{}"); + this.Console_SleepMode = ko.observable("False"); + this.Console_SleepOnStart = ko.observable("False"); + this.Console_SleepDelayMinutes = ko.observable("5"); + this.Console_DozeDelay = ko.observable("2"); + this.Console_AutoRetryCount = ko.observable("5"); + this.Console_SleepStartThresholdSeconds = ko.observable("25"); this._PortMappings = ko.observableArray(); //of portMappingViewModel this.__NewPort = ko.observable("7777"); + this.__NewName = ko.observable(""); + this.__NewDescription = ko.observable(""); this.__NewPortType = ko.observable("0"); + this.__NewProtocol = ko.observable("0"); + + this._ConfigFileMappings = ko.observableArray(); //of configFileMappingViewModel + this.__NewConfigFile = ko.observable(""); + this.__NewAutoMap = ko.observable(true); + this.__NewConfigType = ko.observable(""); - this._UpdateSourceType = ko.observable("4"); this._UpdateSourceURL = ko.observable(""); this._UpdateSourceGitRepo = ko.observable(""); this._UpdateSourceUnzip = ko.observable(false); this._DisplayImageSource = ko.observable(""); this._SteamServerAppID = ko.observable(""); - this._SteamClientAppID = ko.observable(""); this._WinExecutableName = ko.observable(""); this._LinuxExecutableName = ko.observable(""); @@ -72,37 +141,67 @@ class generatorViewModel { this.__AddEditSetting = ko.observable(null); //of appSettingViewModel this.__IsEditingSetting = ko.observable(false); + this._UpdateStages = ko.observableArray(); //of updateStageViewModel + this.__AddEditStage = ko.observable(null); //of updateStageViewModel + this.__IsEditingStage = ko.observable(false); + //Computed values + this.Console_AppReadyRegex = ko.computed(() => WildcardToRegex(self._Console_AppReadyRegex())); + this.Console_UserJoinRegex = ko.computed(() => WildcardToRegex(self._Console_UserJoinRegex())); + this.Console_UserLeaveRegex = ko.computed(() => WildcardToRegex(self._Console_UserLeaveRegex())); + this.Console_UserChatRegex = ko.computed(() => WildcardToRegex(self._Console_UserChatRegex())); this.__SanitizedName = ko.computed(() => self.Meta_DisplayName().replace(/\s+/g, "-").replace(/[^a-z\d-_]/ig, "").toLowerCase()); this.Meta_OS = ko.computed(() => (self._SupportsWindows() ? 1 : 0) | (self._SupportsLinux() ? 2 : 0)); this.Meta_ConfigManifest = ko.computed(() => self.__SanitizedName() + "config.json"); + this.Meta_MetaConfigManifest = ko.computed(() => self.__SanitizedName() + "metaconfig.json"); + this._Meta_PortsManifest = ko.computed(() => self.__SanitizedName() + "ports.json"); + this._Meta_StagesManifest = ko.computed(() => self.__SanitizedName() + "updates.json"); this.Meta_ConfigRoot = ko.computed(() => self.__SanitizedName() + ".kvp"); - this.Meta_DisplayImageSource = ko.computed(() => self._UpdateSourceType() == "4" ? "steam:" + self._SteamClientAppID() : "url:" + self._DisplayImageSource()); - this.App_RootDir = ko.computed(() => `./${self.__SanitizedName()}/`); - this.App_BaseDirectory = ko.computed(() => self._UpdateSourceType() == "4" ? `./${self.__SanitizedName()}/${self._SteamServerAppID()}/` : `./${self.__SanitizedName()}/`); - this.App_WorkingDir = ko.computed(() => self._UpdateSourceType() == "4" ? self._SteamServerAppID() : ""); - - this.App_ExecutableWin = ko.computed(() => self.App_WorkingDir() == "" ? self._WinExecutableName() : `${self.App_WorkingDir()}\\${self._WinExecutableName()}`); - this.App_ExecutableLinux = ko.computed(() => self.App_WorkingDir() == "" ? self._LinuxExecutableName() : `${self.App_WorkingDir()}/${self._LinuxExecutableName()}`); - this.__QueryPortName = ko.observable(""); - this.Meta_EndpointURIFormat = ko.computed(() => self.__QueryPortName() != "" ? `steam://connect/{ip}/{GenericModule.App.${self.__QueryPortName()}}` : ""); + this._SteamCheck = ko.computed(() => { + if (self._UpdateStages().length != 0) { + var appIDCheck = "0"; + for (let i = 0; i < self._UpdateStages().length; i++) { + if (self._UpdateStages()[i]._UpdateSource() == 8 && appIDCheck == 0) { + appIDCheck = self._UpdateStages()[i].UpdateSourceArgs(); + } + } + if (appIDCheck != 0) { + return appIDCheck; + } else { + return '0'; + } + } else { + return '0'; + } + }); + this.Meta_DisplayImageSource = ko.computed(() => self._SteamCheck() == 0 ? 'url:' + self._DisplayImageSource() : 'steam:' + self._SteamCheck()); + this.App_BaseDirectory = ko.computed(() => self._SteamCheck() == 0 ? self.App_RootDir() + 'serverfiles/' : self.App_RootDir() + self._SteamCheck() + '/'); + this.App_WorkingDir = ko.computed(() => self._SteamCheck() == 0 ? 'serverfiles' : self._SteamCheck()); + this._SteamClientAppID = ko.computed(() => self._SteamCheck() != 0 ? self._SteamCheck() : ''); + this.App_ExecutableWin = ko.computed(() => self.App_WorkingDir() == "" ? self._WinExecutableName() : `${self.App_WorkingDir()}\\${self._WinExecutableName()}`); + this.App_ExecutableLinux = ko.computed(() => self._compatibility() == "None" ? (self.App_WorkingDir() == "" ? self._LinuxExecutableName() : `${self.App_WorkingDir()}/${self._LinuxExecutableName()}`) : (self._compatibility().substring(self._compatibility().length - 4) == "Xvfb" ? '/usr/bin/xvfb-run' : (self._compatibility() == "Wine" ? '/usr/bin/wine' : '1580130/proton'))); + this._App_LinuxCommandLineArgsCompat = ko.computed(() => self._compatibility() == "None" ? '' : (self._compatibility() == "WineXvfb" ? '-a wine \"./' + self._WinExecutableName() + '\"' : (self._compatibility() == "ProtonXvfb" ? '-a \"{{$FullRootDir}}1580130/proton\" run \"./' + self._WinExecutableName() + '\"' : (self._compatibility() == "Proton" ? 'run \"./' + self._WinExecutableName() + '\"' : '\"./' + self._WinExecutableName() + '\"')))); + this._App_LinuxCommandLineArgsInput = ko.observable(""); + this.App_LinuxCommandLineArgs = ko.computed(() => self._App_LinuxCommandLineArgsCompat() != '' ? self._App_LinuxCommandLineArgsCompat() + ' ' + self._App_LinuxCommandLineArgsInput() : self._App_LinuxCommandLineArgsInput()); + + this.App_Ports = ko.computed(() => `@IncludeJson[` + self._Meta_PortsManifest() + `]`); + this.App_UpdateSources = ko.computed(() => `@IncludeJson[` + self._Meta_StagesManifest() + `]`); +/* this.__BuildPortMappings = ko.computed(() => { var data = {}; var allPorts = self._PortMappings(); var appPortNum = 1; self.__QueryPortName(""); - for (var i = 0; i < allPorts.length; i++) - { + for (var i = 0; i < allPorts.length; i++) { var portEntry = allPorts[i]; if (portEntry.PortType() == "2") //RCON { data["RemoteAdminPort"] = portEntry.Port(); } - else - { + else { if (appPortNum > 3) { continue; } var portName = "ApplicationPort" + appPortNum; data[portName] = portEntry.Port(); @@ -115,12 +214,12 @@ class generatorViewModel { } return data; }); - - this.__SampleFormattedArgs = ko.computed(function(){ +*/ + this.__SampleFormattedArgs = ko.computed(function () { return self._AppSettings().filter(s => s.IncludeInCommandLine()).map(s => s.IsFlagArgument() ? s._CheckedValue() : self.App_CommandLineParameterFormat().format(s.ParamFieldName(), s.DefaultValue())).join(self.App_CommandLineParameterDelimiter()); }); - - this.__SampleCommandLineFlags = ko.computed(function(){ +/* + this.__SampleCommandLineFlags = ko.computed(function () { var replacements = ko.toJS(self.__BuildPortMappings()); replacements["ApplicationIPBinding"] = "0.0.0.0"; replacements["FormattedArgs"] = self.__SampleFormattedArgs(); @@ -128,21 +227,29 @@ class generatorViewModel { replacements["RemoteAdminPassword"] = "r4nd0m-pa55w0rd-g0e5_h3r3"; return self.App_CommandLineArgs().template(replacements); }); - +*/ this.__GenData = ko.computed(function () { var data = [ { "key": "Generated Name", - "value": self.__SanitizedName(), + "value": self.__SanitizedName() }, { "key": "Config Root", "value": self.Meta_ConfigRoot() }, { - "key": "Manifest Filename", + "key": "Settings Manifest", "value": self.Meta_ConfigManifest() }, + { + "key": "Ports Manifest", + "value": self._Meta_PortsManifest() + }, + { + "key": "Config Files Manifest", + "value": self.Meta_MetaConfigManifest() + }, { "key": "Image Source", "value": self.Meta_DisplayImageSource(), @@ -161,20 +268,24 @@ class generatorViewModel { "value": self.App_WorkingDir() }, { - "key": "Endpoint URI Format", - "value": self.Meta_EndpointURIFormat(), + "key": "Docker Image", + "value": self.Meta_SpecificDockerImage(), "longValue": true + }, + { + "key": "Compatibility", + "value": self._compatibility() } ]; - if (self._SupportsWindows()){ + if (self._SupportsWindows()) { data.push({ "key": "Windows Executable", "value": self.App_ExecutableWin() }); } - if (self._SupportsLinux()){ + if (self._SupportsLinux()) { data.push({ "key": "Linux Executable", "value": self.App_ExecutableLinux() @@ -185,67 +296,122 @@ class generatorViewModel { }); //Action methods (add/remove/update) - this.__RemovePort = function(toRemove){ + this.__RemovePort = function (toRemove) { + if (toRemove._PortType() != 'Custom Port') { + this._availablePortOptions.push(toRemove._PortType()); + } self._PortMappings.remove(toRemove); }; - this.__AddPort = function(){ - self._PortMappings.push(new portMappingViewModel(self.__NewPort(), self.__NewPortType(), self)); + this.__AddPort = function () { + self._PortMappings.push(new portMappingViewModel(self.__NewPort(), self.__NewName(), self.__NewDescription(), self.__NewPortType(), self.__NewProtocol(), self)); + if (self.__NewPortType() != 'Custom Port'){ + this._availablePortOptions.remove(self.__NewPortType()); + } + }; + + this.__RemoveConfigFile = function (toRemove) { + self._ConfigFileMappings.remove(toRemove); + }; + + this.__AddConfigFile = function () { + self._ConfigFileMappings.push(new configFileMappingViewModel(self.__NewConfigFile(), self.__NewAutoMap(), self.__NewConfigType(), self)); }; - this.__RemoveSetting = function(toRemove){ + this.__RemoveSetting = function (toRemove) { self._AppSettings.remove(toRemove); }; - this.__EditSetting = function(toEdit){ + this.__EditSetting = function (toEdit) { self.__IsEditingSetting(true); self.__AddEditSetting(toEdit); $("#addEditSettingModal").modal('show'); }; - this.__AddSetting = function(){ + this.__AddSetting = function () { self.__IsEditingSetting(false); self.__AddEditSetting(new appSettingViewModel(self)); $("#addEditSettingModal").modal('show'); }; - this.__DoAddSetting = function (){ + this.__DoAddSetting = function () { self._AppSettings.push(self.__AddEditSetting()); $("#addEditSettingModal").modal('hide'); }; - this.__CloseSetting = function() { + this.__CloseSetting = function () { $("#addEditSettingModal").modal('hide'); }; - this.__Serialize = function() { + this.__RemoveStage = function (toRemove) { + self._UpdateStages.remove(toRemove); + }; + + this.__EditStage = function (toEdit) { + self.__IsEditingStage(true); + self.__AddEditStage(toEdit); + $("#addEditStageModal").modal('show'); + }; + + this.__AddStage = function () { + self.__IsEditingStage(false); + self.__AddEditStage(new updateStageViewModel(self)); + $("#addEditStageModal").modal('show'); + }; + this.__Errors = ko.validation.group(self); + this.__isValid = ko.computed(function () { + return self.__Errors().length == 0; + }); + + this.__DoAddStage = function () { + self._UpdateStages.push(self.__AddEditStage()); + $("#addEditStageModal").modal('hide'); + }; + + this.__CloseStage = function () { + $("#addEditStageModal").modal('hide'); + }; + + this.__Serialize = function () { var asJS = ko.toJS(self); var result = JSON.stringify(asJS, omitPrivateMembers); return result; }; - this.__Deserialize = function(inputData) { + this.__Deserialize = function (inputData) { var asJS = JSON.parse(inputData); var ports = asJS._PortMappings; + var configFiles = asJS._ConfigFileMappings; var settings = asJS._AppSettings; + var stages = asJS._UpdateStages; delete asJS._PortMappings; + delete asJS._ConfigFileMappings; delete asJS._AppSettings; + delete asJS._UpdateStages; ko.quickmap.map(self, asJS); - + self._PortMappings.removeAll(); - var mappedPorts = ko.quickmap.to(portMappingViewModel, ports, false, {__vm: self}); + var mappedPorts = ko.quickmap.to(portMappingViewModel, ports, false, { __vm: self }); self._PortMappings.push.apply(self._PortMappings, mappedPorts); + self._ConfigFileMappings.removeAll(); + var mappedConfigFiles = ko.quickmap.to(configFileMappingViewModel, configFiles, false, { __vm: self }); + self._ConfigFileMappings.push.apply(self._ConfigFileMappings, mappedConfigFiles); + self._AppSettings.removeAll(); - var mappedPorts = ko.quickmap.to(appSettingViewModel, settings, false, {__vm: self}); - self._AppSettings.push.apply(self._AppSettings, mappedPorts); + var mappedSettings = ko.quickmap.to(appSettingViewModel, settings, false, { __vm: self }); + self._AppSettings.push.apply(self._AppSettings, mappedSettings); + + self._UpdateStages.removeAll(); + var mappedStages = ko.quickmap.to(updateStageViewModel, stages, false, { __vm: self }); + self._UpdateStages.push.apply(self._UpdateStages, mappedStages); }; this.__IsExporting = ko.observable(false); - this.__Export = function() { + this.__Export = function () { self.__IsExporting(true); $("#importexporttextarea").val(self.__Serialize()); $("#importexporttextarea").attr("readonly", true); @@ -253,92 +419,116 @@ class generatorViewModel { autoSave(); }; - this.__CopyExportToClipboard = function(data, element) { + this.__CopyExportToClipboard = function (data, element) { navigator.clipboard.writeText($("#importexporttextarea").val()); setTimeout(() => $(element.target).tooltip('hide'), 2000); }; - this.__CloseImportExport = function() { + this.__CloseImportExport = function () { $("#importExportDialog").modal("hide"); }; - this.__Import = function() { + this.__Import = function () { self.__IsExporting(false); $("#importexporttextarea").val(""); $("#importexporttextarea").prop("readonly", false); $("#importExportDialog").modal("show"); }; - this.__DoImport = function() { + this.__DoImport = function () { self.__Deserialize($("#importexporttextarea").val()); $("#importExportDialog").modal("hide"); autoSave(); }; - this.__Share = function(data, element) { + this.__Share = function (data, element) { var data = encodeURIComponent(self.__Serialize()); var url = `${document.location.protocol}//${document.location.hostname}${document.location.pathname}#cdata=${data}`; navigator.clipboard.writeText(url); setTimeout(() => $(element.target).tooltip('hide'), 2000); }; - this.__Clear = function(){ + this.__Clear = function () { localStorage.configgenautosave = ""; document.location.reload(); } - this.__DownloadConfig = function(){ + this.__GithubManifest = function () { + function guid() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); + } + var githubManifest = JSON.stringify({ id: guid(), authors: [self.Meta_Author()], origin: self._Meta_GithubOrigin(), url: self._Meta_GithubURL(), imagefile: "", prefix: self.Meta_Author() }, null, 4); + return githubManifest; + } + + this.__DownloadConfig = function () { if (this.__ValidationResult() < 2) { return; } var lines = []; - for (const key of Object.keys(self).filter(k => !k.startsWith("_"))) - { + for (const key of Object.keys(self).filter(k => !k.startsWith("_"))) { lines.push(`${key.replace("_", ".")}=${self[key]()}`); } - switch (self._UpdateSourceType()) - { - case "1": //URL - lines.push(`App.UpdateSources=[{\"UpdateStageName\": \"Server Download\",\"UpdateSourcePlatform\": \"All\", \"UpdateSource\": \"FetchURL\", \"UpdateSourceData\": \"${self._UpdateSourceURL()}\", \"UnzipUpdateSource\": ${self._UpdateSourceUnzip()}}]`); - break; - case "4": //Steam - lines.push(`App.UpdateSources=[{\"UpdateStageName\": \"SteamCMD Download\",\"UpdateSourcePlatform\": \"All\", \"UpdateSource\": \"SteamCMD\", \"UpdateSourceData\": \"${self._SteamServerAppID()}\"}]`); - break; - case "16": //Github - lines.push(`App.UpdateSources=[{\"UpdateStageName\": \"GitHub Release Download\",\"UpdateSourcePlatform\": \"All\", \"UpdateSource\": \"GithubRelease\", \"UpdateSourceData\": \"${self._UpdateSourceGitRepo()}\"}]`); - break; + if ((self._compatibility() == "Proton" || self._compatibility() == "ProtonXvfb") && self._SteamCheck() != 0) { + lines.push(`App.EnvironmentVariables={\"LD_LIBRARY_PATH\": \"{{$FullBaseDir}}linux64:{{$FullRootDir}}linux64:%LD_LIBRARY_PATH%\", \"SteamAppId\": \"${self._SteamClientAppID()}\", \"STEAM_COMPAT_DATA_PATH\": \"{{$FullRootDir}}1580130\", \"STEAM_COMPAT_CLIENT_INSTALL_PATH\": \"{{$FullRootDir}}1580130\"}`); + } else if ((self._compatibility() == "Proton" || self._compatibility() == "ProtonXvfb") && self._SteamCheck() == 0) { + lines.push(`App.EnvironmentVariables={\"LD_LIBRARY_PATH\": \"{{$FullBaseDir}}linux64:{{$FullRootDir}}linux64:%LD_LIBRARY_PATH%\"}`); + } else if ((self._compatibility() == "Wine" || self._compatibility() == "WineXvfb") && self._SteamCheck() != 0) { + lines.push(`App.EnvironmentVariables={\"LD_LIBRARY_PATH\": \"{{$FullBaseDir}}linux64:{{$FullRootDir}}linux64:%LD_LIBRARY_PATH%\", \"SteamAppId\": \"${self._SteamClientAppID()}\", \"WINEPREFIX\": \"{{$FullRootDir}}.wine\", \"WINEARCH\": \"win64\", \"WINEDEBUG\": \"-all\"}`); + } else { + lines.push(`App.EnvironmentVariables={\"LD_LIBRARY_PATH\": \"{{$FullBaseDir}}linux64:{{$FullRootDir}}linux64:%LD_LIBRARY_PATH%\", \"WINEPREFIX\": \"{{$FullRootDir}}.wine\", \"WINEARCH\": \"win64\", \"WINEDEBUG\": \"-all\"}`); } - if (self._UpdateSourceType() == "4") //SteamCMD - { - lines.push(`App.EnvironmentVariables={\"LD_LIBRARY_PATH\": \"./linux64:%LD_LIBRARY_PATH%\", \"SteamAppId\": \"${self._SteamServerAppID()}\"}`); - } - - var portMappings = self.__BuildPortMappings(); - for (const key of Object.keys(portMappings)) - { - lines.push(`App.${key}=${portMappings[key]}`); + var output = lines.join("\n"); + var asJSAppSettings = ko.toJS(self._AppSettings()); + var asJSUpdateStages = ko.toJS(self._UpdateStages()); + var asJSPortMappings = ko.toJS(self._PortMappings()); + var asJSConfigFileMappings = ko.toJS(self._ConfigFileMappings()); + var zip = new JSZip(); + zip.file(self.Meta_ConfigRoot(), output); + zip.file(self.Meta_ConfigManifest(), JSON.stringify(asJSAppSettings, omitNonPublicMembers, 4)); + for (const stage of asJSUpdateStages) { + if (stage.ForceDownloadPlatform == null) { + delete stage.ForceDownloadPlatform; + } + if (stage.UpdateSourceConditionSetting == null) { + delete stage.UpdateSourceConditionSetting; + } + if (stage.UpdateSourceConditionValue == null) { + delete stage.UpdateSourceConditionValue; + } + if (stage.UpdateSourceData == "") { + delete stage.UpdateSourceData; + } + if (stage.UpdateSourceArgs == "") { + delete stage.UpdateSourceArgs; + } + if (stage.UpdateSourceVersion == "") { + delete stage.UpdateSourceVersion; + } + if (stage.UpdateSourceTarget == "") { + delete stage.UpdateSourceTarget; + } } - - var output = lines.sort().join("\n"); - downloadString(output, self.Meta_ConfigRoot()); - }; - - this.__DownloadSettingsManifest = function(){ - if (this.__ValidationResult() < 2) { return; } - - var asJS = ko.toJS(self._AppSettings()); - downloadString(JSON.stringify(asJS, omitNonPublicMembers, 4), self.Meta_ConfigManifest()); + zip.file(self._Meta_StagesManifest(), JSON.stringify(asJSUpdateStages, omitNonPublicMembers, 4)); + zip.file(self._Meta_PortsManifest(), JSON.stringify(asJSPortMappings, omitNonPublicMembers, 4)); + zip.file(self.Meta_MetaConfigManifest(), JSON.stringify(asJSConfigFileMappings, omitNonPublicMembers, 4)); + zip.file("manifest.json", self.__GithubManifest()); + zip.generateAsync({ type: "blob" }) + .then(function (content) { + saveAs(content, "configs.zip"); + }); }; - this.__Invalidate = function(newValue){ + this.__Invalidate = function (newValue) { self.__ValidationResult(0); }; - for (const k of Object.keys(self)) - { - if (ko.isObservable(self[k])) - { + for (const k of Object.keys(self)) { + if (ko.isObservable(self[k])) { self[k].subscribe(self.__Invalidate); } } @@ -347,8 +537,12 @@ class generatorViewModel { this.__ValidationResults = ko.observableArray(); - this.__ValidateConfig = function(){ + this.__ValidateConfig = function () { autoSave(); + if (!self.__isValid()) { + self.__Errors.showAllMessages(); + return; + } self.__ValidationResults.removeAll(); var failure = (issue, recommendation) => self.__ValidationResults.push(new validationResult("Failure", issue, recommendation)); @@ -356,101 +550,67 @@ class generatorViewModel { var info = (issue, recommendation, impact) => self.__ValidationResults.push(new validationResult("Info", issue, recommendation, impact)); //Validation Begins - if (self.Meta_DisplayName() == ""){ + if (self.Meta_DisplayName() == "") { failure("Missing application name", "Specify an application name under 'Basic Configuration'"); } - if (!self._SupportsWindows() && !self._SupportsLinux()) - { + if (!self._SupportsWindows() && !self._SupportsLinux()) { failure("No platforms have been specified as supported.", "Specify at least one supported platform under 'Basic Information'"); } - if (self._SupportsWindows()) - { + if (self._SupportsWindows()) { if (self._WinExecutableName() == "") { failure("Windows is listed as a supported platform, but no executable for this platform was specified.", "Specify an executable for this platform under 'Startup and Shutdown'"); } else if (!self._WinExecutableName().toLowerCase().endsWith(".exe")) { failure("You can only start executables (.exe) files on Windows from AMP. Do not attempt to use batch files or other file types.", "Change your Windows Executable under Startup and Shutdown to be a .exe file."); } } - if (self._SupportsLinux()) - { - if (self._LinuxExecutableName() == "") { failure("Linux is listed as a supported platform, but no executable for this platform was specified.", "Specify an executable for this platform under 'Startup and Shutdown'"); } + if (self._SupportsLinux()) { + if (self._LinuxExecutableName() == "" && self._compatibility() == "None") { failure("Linux is listed as a supported platform, but no executable for this platform was specified.", "Specify an executable for this platform under 'Startup and Shutdown'"); } else if (self._LinuxExecutableName().toLowerCase().endsWith(".sh")) { failure("You can only start executables files from AMP. Do not attempt to use shell scripts or other file types.", "Change your Linux Executable under Startup and Shutdown to be an actual executable rather than a script."); } } - switch (self.App_AdminMethod()) - { - case "PinballWizard": + switch (self.App_AdminMethod()) { + case "PinballWizard": case "AMP_GSIO": break; case "STDIO": - if (!self.App_HasReadableConsole() && !self.App_HasWritableConsole()) - { + if (!self.App_HasReadableConsole() && !self.App_HasWritableConsole()) { failure("Standard IO was selected as the management type, but the console was set as neither readable nor writable - so AMP won't be able to do anything useful.", "Either enable Reading or Writing for the console (if the application supports it) - or change the management mode to 'None'"); } break; default: - if (!self.App_CommandLineArgs().contains("{{$RemoteAdminPassword}}")){ + if (!self.App_CommandLineArgs().contains("{{$RemoteAdminPassword}}")) { warning("A server management mode is specified that requires AMP to know the password, but {{$RemoteAdminPassword}} is not found within the command line arguments.", "If the application can have it's RCON password specified via the command line then you should add the {{$RemoteAdminPassword}} template item to your command line arguments", "Without the ability to control the RCON password, AMP will not be able to use the servers RCON to provide a console or run commands."); } - - if (!self.App_CommandLineArgs().contains(this.__QueryPortName())){ +/* + if (!self.App_CommandLineArgs().contains(this.__QueryPortName())) { warning("A server management mode that uses the network was specified, but the port being used is not found within the command line arguments.", "If the application can have it's RCON port specified via the command line then you should add the {{$" + this.__QueryPortName() + "}} template item to your command line arguments"); } - if (self._PortMappings().filter(p => p.PortType() == "2").length == 0) - { + if (self._PortMappings().filter(p => p.PortType() == "2").length == 0) { warning("A server management mode that uses the network was specified, but no RCON port has been added.", "Add the port used by this applications RCON under Networking."); } - break; - } - - switch (self._UpdateSourceType()) - { - case "1": //Fetch from URL - if (self._UpdateSourceURL() == "") { - failure("Update method is Fetch from URL, but no download URL was specified.", "Specify the 'Update source URL' under Update Sources."); - } - else if (self._UpdateSourceURL().toLowerCase().endsWith(".zip") && !self._UpdateSourceUnzip()) - { - info("Download URL is a zip file, but 'Unzip once downloaded' is not turned on.", "Turn on 'Unzip once downloaded' under 'Update Sources'", "Without this setting turned on, the archive will not be extracted. If this was intentional, you can ignore this message."); - } - break; - case "4": //SteamCMD - if (self._SteamServerAppID() == "") { - failure("Update method is SteamCMD, but no server App ID is set.", "Specify the 'Server Steam App ID' under Update Sources."); - } - if (self._SteamClientAppID() == "") { - warning("Update method is SteamCMD, but no client App ID is set.", "Specify the 'Server Client App ID' under Update Sources.", "The client app ID is used to source the background image for the resulting instance."); - } - break; +*/ break; } - if (self.Console_AppReadyRegex() != "" && !self.Console_AppReadyRegex().match(/\^.+\$/)) { failure("Server ready expression does not match the entire line. Regular expressions for AMP must match the entire line, starting with a ^ and ending with a $.", "Update the Server Ready expression under Server Events to match the entire line."); } - if (self.Console_UserJoinRegex() != "" && !self.Console_UserJoinRegex().match(/\^.+\$/)) { failure("User connected expression does not match the entire line. Regular expressions for AMP must match the entire line, starting with a ^ and ending with a $.", "Update the User connected expression under Server Events to match the entire line."); } - if (self.Console_UserLeaveRegex() != "" && !self.Console_UserLeaveRegex().match(/\^.+\$/)) { failure("User disconnected expression does not match the entire line. Regular expressions for AMP must match the entire line, starting with a ^ and ending with a $.", "Update the User disconnected expression under Server Events to match the entire line."); } - if (self.Console_UserChatRegex() != "" && !self.Console_UserChatRegex().match(/\^.+\$/)) { failure("User chat expression does not match the entire line. Regular expressions for AMP must match the entire line, starting with a ^ and ending with a $.", "Update the User chat expression under Server Events to match the entire line."); } + if ((self._compatibility() == "Wine" && !self._SupportsLinux()) || (self._compatibility() == "Proton" && !self._SupportsLinux())) { failure("A Linux compatibility layer was chosen, but Linux support is not checked.", "Please check both."); } //Validation Summary var failures = self.__ValidationResults().filter(r => r.grade == "Failure").length; var warnings = self.__ValidationResults().filter(r => r.grade == "Warning").length; - if (failures > 0) - { + if (failures > 0) { self.__ValidationResult(1); } - else if (warnings > 0) - { + else if (warnings > 0) { self.__ValidationResult(2); } - else - { + else { self.__ValidationResult(3); } }; } } - class validationResult { constructor(grade, issue, recommendation, impact) { this.grade = grade; @@ -458,8 +618,7 @@ class validationResult { this.recommendation = recommendation; this.impact = impact || ""; this.gradeClass = ""; - switch (grade) - { + switch (grade) { case "Failure": this.gradeClass = "table-danger"; break; case "Warning": this.gradeClass = "table-warning"; break; case "Info": this.gradeClass = "table-info"; break; @@ -468,40 +627,135 @@ class validationResult { } class portMappingViewModel { - constructor(port, portType, vm) { + constructor(port, portName, portDescription, portType, protocol, vm) { var self = this; this.__vm = vm; + this._Protocol = ko.observable(protocol); + this.Protocol = ko.computed(() => self._Protocol() == "0" ? `Both` : (self._Protocol() == "1" ? `TCP` : `UDP`)); this.Port = ko.observable(port); - this.PortType = ko.observable(portType); + this._PortType = ko.observable(portType); + this._Name = ko.observable(portName); + this.Name = ko.computed(() => self._PortType() == "Custom Port" ? self._Name() : (self._PortType() == "Steam Query Port" ? `Steam Query Port` : (self._PortType() == "RCON Port" ? `Remote Admin Port` : `Main Game Port`))); + this._Description = ko.observable(portDescription); + this.Description = ko.computed(() => self._Description() == "0" ? self._Description() : (self._PortType() == "1" ? `Port used for Steam queries and server list` : (self._PortType() == "2" ? `Port used for RCON administration` : `Port used for main game traffic`))); + this.Ref = ko.computed(() => self._PortType() == "Custom Port" ? self._Name().replace(/\s+/g, "").replace(/[^a-z\d-_]/ig, "") : (self._PortType() == "Steam Query Port" ? `SteamQueryPort` : (self._PortType() == "RCON Port" ? `RemoteAdminPort` : `MainGamePort`))); this.__RemovePort = () => self.__vm.__RemovePort(self); } } +class configFileMappingViewModel { + constructor(configFile, autoMap, configType, vm) { + var self = this; + this.__vm = vm; + this.ConfigFile = ko.observable(configFile); + this._ConfigType = ko.observable(configType); + this.ConfigType = ko.computed(() => self._ConfigType() == "0" ? `json` : (self._ConfigType() == "1" ? `ini` : (self._ConfigType() == "2" ? `xml` : (self._ConfigType() == "3" ? `kvp` : ``)))); + this._AutoMap = ko.observable(autoMap); + this.AutoMap = ko.computed(() => self._ConfigType() == "4" ? false : self._AutoMap()); + this.__RemoveConfigFile = () => self.__vm.__RemoveConfigFile(self); + } +} + class appSettingViewModel { constructor(vm) { var self = this; this.__vm = vm; this.DisplayName = ko.observable(""); - this.Category = ko.observable(""); + this.Category = ko.observable("Server Settings"); this.Description = ko.observable(""); - this.Keywords = ko.observable(""); + this.Keywords = ko.computed(() => self.DisplayName().toLowerCase().replaceAll(" ", ",")); this.FieldName = ko.observable(""); this.InputType = ko.observable("text") this.IsFlagArgument = ko.observable(false); this.ParamFieldName = ko.computed(() => self.FieldName()); - this.IncludeInCommandLine = ko.observable(true); + this.IncludeInCommandLine = ko.observable(false); this.DefaultValue = ko.observable(""); + this.Placeholder = ko.computed(() => self.DefaultValue()); + this.Suffix = ko.observable(""); + this.Hidden = ko.observable(false); + this.SkipIfEmpty = ko.observable(false); this._CheckedValue = ko.observable("true"); this._UncheckedValue = ko.observable("false"); - this.EnumValues = ko.computed(() => { - if (self.InputType() != "checkbox") { return {}; } - var result = {}; - result[self._CheckedValue()] = "True"; - result[self._UncheckedValue()] = "False"; - return result; - }); this.__RemoveSetting = () => self.__vm.__RemoveSetting(self); this.__EditSetting = () => self.__vm.__EditSetting(self); + + this._EnumMappings = ko.observableArray(); //of enumMappingViewModel + this.__NewEnumKey = ko.observable(""); + this.__NewEnumValue = ko.observable(""); + + this.__RemoveEnum = function (toRemove) { + self._EnumMappings.remove(toRemove); + }; + + this.__AddEnum = function () { + self._EnumMappings.push(new enumMappingViewModel(self.__NewEnumKey(), self.__NewEnumValue(), self)); + }; + + this.__Deserialize = function (inputData) { + var asJS = JSON.parse(inputData); + var enumSettings = asJS._EnumMappings; + + delete asJS._EnumMappings; + + ko.quickmap.map(self, asJS); + + self._EnumMappings.removeAll(); + var mappedEnums = ko.quickmap.to(enumMappingViewModel, enumSettings, false, { __vm: self }); + self._EnumMappings.push.apply(self._EnumMappings, mappedEnums); + }; + + this.EnumValues = ko.computed(() => { + if (self.InputType() == "checkbox") { + var result = {}; + result[self._CheckedValue()] = "True"; + result[self._UncheckedValue()] = "False"; + return result; + } else if (self.InputType() == "enum") { + var result = {}; + for (let i = 0; i < self._EnumMappings().length; i++) { + result[self._EnumMappings()[i]._enumKey()] = self._EnumMappings()[i]._enumValue(); + } + return result; + } else { + return {}; + } + }); + } +} + +class enumMappingViewModel { + constructor(enumKey, enumValue, vm) { + var self = this; + this.__vm = vm; + this._enumKey = ko.observable(enumKey); + this._enumValue = ko.observable(enumValue); + this.__RemoveEnum = () => self.__vm.__RemoveEnum(self); + } +} + +class updateStageViewModel { + constructor(vm) { + var self = this; + this.__vm = vm; + this.UpdateStageName = ko.observable(""); + this._UpdateSourcePlatform = ko.observable("0"); + this.UpdateSourcePlatform = ko.computed(() => self._UpdateSourcePlatform() == "0" ? `All` : (self._UpdateSourcePlatform() == "1" ? `Linux` : `Windows`)); + this._UpdateSource = ko.observable("8"); + this.UpdateSource = ko.computed(() => self._UpdateSource() == "0" ? `CopyFilePath` : (self._UpdateSource() == "1" ? `CreateSymlink` : (self._UpdateSource() == "2" ? `Executable` : (self._UpdateSource() == "3" ? `ExtractArchive` : (self._UpdateSource() == "4" ? `FetchURL` : (self._UpdateSource() == "5" ? `GithubRelease` : (self._UpdateSource() == "6" ? `SetExecutableFlag` : (self._UpdateSource() == "7" ? `StartApplication` : `SteamCMD`)))))))); + this.UpdateSourceData = ko.observable(""); + this.UpdateSourceArgs = ko.observable(""); + this.UpdateSourceVersion = ko.observable(""); + this.UpdateSourceTarget = ko.observable(""); + this.UnzipUpdateSource = ko.observable(false); + this.OverwriteExistingFiles = ko.observable(false); + this._ForceDownloadPlatform = ko.observable(null); + this.ForceDownloadPlatform = ko.computed(() => self._ForceDownloadPlatform() == "0" ? null : (self._ForceDownloadPlatform() == "1" ? `Linux` : `Windows`)); + this.UpdateSourceConditionSetting = ko.observable(null); + this.UpdateSourceConditionValue = ko.observable(null); + this.DeleteAfterExtract = ko.observable(true); + this.OneShot = ko.observable(false); + this.__RemoveStage = () => self.__vm.__RemoveStage(self); + this.__EditStage = () => self.__vm.__EditStage(self); } } @@ -511,13 +765,13 @@ function autoSave() { localStorage.configgenautosave = vm.__Serialize(); } -function autoLoad(){ - if (localStorage.configgenautosave != ""){ +function autoLoad() { + if (localStorage.configgenautosave != "") { vm.__Deserialize(localStorage.configgenautosave); } } -document.addEventListener('DOMContentLoaded',() => { +document.addEventListener('DOMContentLoaded', () => { ko.applyBindings(vm); setInterval(autoSave, 30000); $('body').scrollspy({ target: '#navbar', offset: 90 }); @@ -528,14 +782,12 @@ document.addEventListener('DOMContentLoaded',() => { placement: 'bottom' }); //Check if there is anything after the # and if it starts cdata=, then import it if it does. - if (document.location.hash.indexOf("#cdata=") == 0) - { - var data = decodeURIComponent(document.location.hash.substr(7)); + if (document.location.hash.indexOf("#cdata=") == 0) { + var data = decodeURIComponent(document.location.hash.substring(7)); vm.__Deserialize(data); document.location.hash = ""; } - else - { + else { autoLoad(); } }); diff --git a/index.html b/index.html new file mode 100644 index 0000000..b3a2972 --- /dev/null +++ b/index.html @@ -0,0 +1,1612 @@ + + + + + AMP Configuration Generator + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+

AMP Configuration Generator

+ Version 2.0 - Updated by IceOfWraith
©2023 CubeCoders Limited
+
+
+ + + +
+
+
+ +
+
+

You can find detailed instructions and explanations on the Generic Configurations Wiki.

+
+
+

Basic Information

+
+
+ +
This is what will show up within AMP as the name of the application.
+ +
+
+ +
Useful for describing different variants/configurations of the same application.
+ +
+
+
+
+ +
Who are you? Take some credit for your work! Please use your GitHub username.
+ +
+
+ +
A link to where you can learn more about the application, such as a store listing.
+ +
+
+
+ +
+ + +
+
+
+ +
+ + + + + +
+
+
+


+

Management and Console

+
+ +
+ + + + + + + + +
+
+
+
+ +
+ This is in addition to the applications management type if it accepts management over methods other than Standard IO +
+
+ + +
+
+ +


+

Networking

+
+ AMP will automatically generate firewall rules to allow the application ports through. You may add any number of ports. Maximum of 1 Main Game, Steam Query, and RCON Port. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NumberTypeNameDescriptionProtocol
+ + + + + + + + + +
No ports have been added.
+ + + + + + + + + + + +
+


+

Update Sources

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Stage NameSource Type
+ + +
No update sources added.
+ +
+


+

Configuration and Settings

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Display NameField NameDefault ValueCommand Line
+ + +
No settings have been added.
+ +
+
Configuration Files
+
+ Select the location of any game server configuration files AMP should manage. Location relative to Base Directory. +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Config FileConfig TypeAutoMap
+ + + + + + + +
No config files have been added.
+ + + + + + + +
+


+

Startup and Shutdown

+
Application and Parameters
+
+
+ + +
+
+ + +
+
+
+ +
+ Don't include any arguments that come from the Configuration and Settings section above. + +
+ +
+
+
+ +
+ Any Windows specific arguments to be used in the command line args in place of {{$PlatformArgs}}. +
+ +
+
+ +
+ Any Linux specific arguments to be used in the command line args in place of {{$PlatformArgs}}. +
+ +
+
+
+
+ +
+ The format to be used to add settings specified above to the command line in place of {{$FormattedArgs}}. {0} is the field name and {1} the value. +
+ +
+
+ +
+ The character(s) used to separate different arguments in the command line flags generated by settings. By default this is a single space. +
+ +
+
+
+
+ +
+ Where should AMP place Steam Workshop mods? This is relative to the Base Directory. +
+ +
+
+ +
+ A URL to an image that AMP can use to represent the application. This is pre-filled for Steam games. +
+ +
+
+ +
+ +
+ + + +
+
+
Shutdown
+
+
+ + +
+
+ + +
+
+


+

Server Events (Beta)

+

+ AMP uses the game server's output from either the console (standard output) or RCON to know how to handle certain events:
+ A successful startup, Users connecting/disconnecting, or Chat messages. +

+

+ The Config Generator will attempt to create regular expressions based on your input. + Paste a line from the console that uniquely represents the events. + Keep all static pieces of the line and replace sections that vary with the *{misc} variable. + Use as many of these variables in place of corresponding sections of the lines: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VariableDescription
*{username}The Username of the player
*{userid}The User ID of the player (Typically Steam64 ID or Epic ID #)
*{sessionid}Any unique number to identify a player's Session
*{message}The chat message
*{endpoint}The IP of the player
*{misc}Any section of the line that varies

+

+ Regex101 is an excellent resource to help validate expressions. AMP uses the 'ECMAScript (Javascript)' regex flavour. +

+
+ + +
+
+ + +
+
+ + +
+
+ + +
+


+

Validate and Review

+
+ +
+ This is generated assuming the default values and default port numbers, these will change based on user-specified values or assignments made by AMP. +
+
+
+

+ +

+

+ + + +   + You have not yet validated your configuration. You will not be able to download your configuration until you have done this. +

+

+ + + +   + Validation Failed - You must address the following failures before you may continue. +

+

+ + + +   + Validation Passed with Warnings - You should consider addressing the following warnings. +

+

+ + + +   + Validation Passed - Great stuff! You may now download the completed configuration below. +

+
+
+
Validation Issues:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CategoryIssueRecommentation
Impact:
No validation issues
+
+
+
+ +
+

+ + + +   + Make sure to keep a backup of your configuration by using the 'Export' option at the top of the page! You will need this to make further changes even after downloading the configuration and manifest. +

+

+
+
Using the generated configuration
+

You can find the steps to upload the configuration to GitHub and use them within AMP on the Generic Configurations Wiki.

+
+

 

+
+
+
+ +
+
+

Generated Data

+ Values that are calculated automatically based on your input. + + + + + + + + + + + + +
+
+ + + No Generated Value + +
+
+
+ + + No Generated Value + +
+
+
+
+
+ + + + + + + + + + + diff --git a/jszip.min.js b/jszip.min.js new file mode 100644 index 0000000..ff4cfd5 --- /dev/null +++ b/jszip.min.js @@ -0,0 +1,13 @@ +/*! + +JSZip v3.10.1 - A JavaScript class for generating and reading zip files + + +(c) 2009-2016 Stuart Knightley +Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown. + +JSZip uses the library pako released under the MIT license : +https://github.com/nodeca/pako/blob/main/LICENSE +*/ + +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).JSZip=e()}}(function(){return function s(a,o,h){function u(r,e){if(!o[r]){if(!a[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(l)return l(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return u(t||e)},i,i.exports,s,a,o,h)}return o[r].exports}for(var l="function"==typeof require&&require,e=0;e>2,s=(3&t)<<4|r>>4,a=1>6:64,o=2>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),l[h++]=t,64!==s&&(l[h++]=r),64!==a&&(l[h++]=n);return l}},{"./support":30,"./utils":32}],2:[function(e,t,r){"use strict";var n=e("./external"),i=e("./stream/DataWorker"),s=e("./stream/Crc32Probe"),a=e("./stream/DataLengthProbe");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")),t=this;return e.on("end",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a("uncompressedSize")).pipe(t.compressWorker(r)).pipe(new a("compressedSize")).withStreamInfo("compression",t)},t.exports=o},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(e,t,r){"use strict";var n=e("./stream/GenericWorker");r.STORE={magic:"\0\0",compressWorker:function(){return new n("STORE compression")},uncompressWorker:function(){return new n("STORE decompression")}},r.DEFLATE=e("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(e,t,r){"use strict";var n=e("./utils");var o=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t){return void 0!==e&&e.length?"string"!==n.getTypeOf(e)?function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}(0|t,e,e.length,0):function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t.charCodeAt(a))];return-1^e}(0|t,e,e.length,0):0}},{"./utils":32}],5:[function(e,t,r){"use strict";r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null},{}],6:[function(e,t,r){"use strict";var n=null;n="undefined"!=typeof Promise?Promise:e("lie"),t.exports={Promise:n}},{lie:37}],7:[function(e,t,r){"use strict";var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,i=e("pako"),s=e("./utils"),a=e("./stream/GenericWorker"),o=n?"uint8array":"array";function h(e,t){a.call(this,"FlateWorker/"+e),this._pako=null,this._pakoAction=e,this._pakoOptions=t,this.meta={}}r.magic="\b\0",s.inherits(h,a),h.prototype.processChunk=function(e){this.meta=e.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,e.data),!1)},h.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0)},h.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null},h.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var t=this;this._pako.onData=function(e){t.push({data:e,meta:t.meta})}},r.compressWorker=function(e){return new h("Deflate",e)},r.uncompressWorker=function(){return new h("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(e,t,r){"use strict";function A(e,t){var r,n="";for(r=0;r>>=8;return n}function n(e,t,r,n,i,s){var a,o,h=e.file,u=e.compression,l=s!==O.utf8encode,f=I.transformTo("string",s(h.name)),c=I.transformTo("string",O.utf8encode(h.name)),d=h.comment,p=I.transformTo("string",s(d)),m=I.transformTo("string",O.utf8encode(d)),_=c.length!==h.name.length,g=m.length!==d.length,b="",v="",y="",w=h.dir,k=h.date,x={crc32:0,compressedSize:0,uncompressedSize:0};t&&!r||(x.crc32=e.crc32,x.compressedSize=e.compressedSize,x.uncompressedSize=e.uncompressedSize);var S=0;t&&(S|=8),l||!_&&!g||(S|=2048);var z=0,C=0;w&&(z|=16),"UNIX"===i?(C=798,z|=function(e,t){var r=e;return e||(r=t?16893:33204),(65535&r)<<16}(h.unixPermissions,w)):(C=20,z|=function(e){return 63&(e||0)}(h.dosPermissions)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(v=A(1,1)+A(B(f),4)+c,b+="up"+A(v.length,2)+v),g&&(y=A(1,1)+A(B(p),4)+m,b+="uc"+A(y.length,2)+y);var E="";return E+="\n\0",E+=A(S,2),E+=u.magic,E+=A(a,2),E+=A(o,2),E+=A(x.crc32,4),E+=A(x.compressedSize,4),E+=A(x.uncompressedSize,4),E+=A(f.length,2),E+=A(b.length,2),{fileRecord:R.LOCAL_FILE_HEADER+E+f+b,dirRecord:R.CENTRAL_FILE_HEADER+A(C,2)+E+A(p.length,2)+"\0\0\0\0"+A(z,4)+A(n,4)+f+b+p}}var I=e("../utils"),i=e("../stream/GenericWorker"),O=e("../utf8"),B=e("../crc32"),R=e("../signature");function s(e,t,r,n){i.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=t,this.zipPlatform=r,this.encodeFileName=n,this.streamFiles=e,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}I.inherits(s,i),s.prototype.push=function(e){var t=e.meta.percent||0,r=this.entriesCount,n=this._sources.length;this.accumulate?this.contentBuffer.push(e):(this.bytesWritten+=e.data.length,i.prototype.push.call(this,{data:e.data,meta:{currentFile:this.currentFile,percent:r?(t+100*(r-n-1))/r:100}}))},s.prototype.openedSource=function(e){this.currentSourceOffset=this.bytesWritten,this.currentFile=e.file.name;var t=this.streamFiles&&!e.file.dir;if(t){var r=n(e,t,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}})}else this.accumulate=!0},s.prototype.closedSource=function(e){this.accumulate=!1;var t=this.streamFiles&&!e.file.dir,r=n(e,t,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(r.dirRecord),t)this.push({data:function(e){return R.DATA_DESCRIPTOR+A(e.crc32,4)+A(e.compressedSize,4)+A(e.uncompressedSize,4)}(e),meta:{percent:100}});else for(this.push({data:r.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},s.prototype.flush=function(){for(var e=this.bytesWritten,t=0;t=this.index;t--)r=(r<<8)+this.byteAt(t);return this.index+=e,r},readString:function(e){return n.transformTo("string",this.readData(e))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var e=this.readInt(4);return new Date(Date.UTC(1980+(e>>25&127),(e>>21&15)-1,e>>16&31,e>>11&31,e>>5&63,(31&e)<<1))}},t.exports=i},{"../utils":32}],19:[function(e,t,r){"use strict";var n=e("./Uint8ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(e,t,r){"use strict";var n=e("./DataReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.byteAt=function(e){return this.data.charCodeAt(this.zero+e)},i.prototype.lastIndexOfSignature=function(e){return this.data.lastIndexOf(e)-this.zero},i.prototype.readAndCheckSignature=function(e){return e===this.readData(4)},i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./DataReader":18}],21:[function(e,t,r){"use strict";var n=e("./ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return new Uint8Array(0);var t=this.data.subarray(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./ArrayReader":17}],22:[function(e,t,r){"use strict";var n=e("../utils"),i=e("../support"),s=e("./ArrayReader"),a=e("./StringReader"),o=e("./NodeBufferReader"),h=e("./Uint8ArrayReader");t.exports=function(e){var t=n.getTypeOf(e);return n.checkSupport(t),"string"!==t||i.uint8array?"nodebuffer"===t?new o(e):i.uint8array?new h(n.transformTo("uint8array",e)):new s(n.transformTo("array",e)):new a(e)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(e,t,r){"use strict";r.LOCAL_FILE_HEADER="PK",r.CENTRAL_FILE_HEADER="PK",r.CENTRAL_DIRECTORY_END="PK",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",r.ZIP64_CENTRAL_DIRECTORY_END="PK",r.DATA_DESCRIPTOR="PK\b"},{}],24:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../utils");function s(e){n.call(this,"ConvertWorker to "+e),this.destType=e}i.inherits(s,n),s.prototype.processChunk=function(e){this.push({data:i.transformTo(this.destType,e.data),meta:e.meta})},t.exports=s},{"../utils":32,"./GenericWorker":28}],25:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../crc32");function s(){n.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}e("../utils").inherits(s,n),s.prototype.processChunk=function(e){this.streamInfo.crc32=i(e.data,this.streamInfo.crc32||0),this.push(e)},t.exports=s},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataLengthProbe for "+e),this.propName=e,this.withStreamInfo(e,0)}n.inherits(s,i),s.prototype.processChunk=function(e){if(e){var t=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=t+e.data.length}i.prototype.processChunk.call(this,e)},t.exports=s},{"../utils":32,"./GenericWorker":28}],27:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataWorker");var t=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,e.then(function(e){t.dataIsReady=!0,t.data=e,t.max=e&&e.length||0,t.type=n.getTypeOf(e),t.isPaused||t._tickAndRepeat()},function(e){t.error(e)})}n.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null},s.prototype.resume=function(){return!!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,n.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(n.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var e=null,t=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":e=this.data.substring(this.index,t);break;case"uint8array":e=this.data.subarray(this.index,t);break;case"array":case"nodebuffer":e=this.data.slice(this.index,t)}return this.index=t,this.push({data:e,meta:{percent:this.max?this.index/this.max*100:0}})},t.exports=s},{"../utils":32,"./GenericWorker":28}],28:[function(e,t,r){"use strict";function n(e){this.name=e||"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}n.prototype={push:function(e){this.emit("data",e)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(e){this.emit("error",e)}return!0},error:function(e){return!this.isFinished&&(this.isPaused?this.generatedError=e:(this.isFinished=!0,this.emit("error",e),this.previous&&this.previous.error(e),this.cleanUp()),!0)},on:function(e,t){return this._listeners[e].push(t),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(e,t){if(this._listeners[e])for(var r=0;r "+e:e}},t.exports=n},{}],29:[function(e,t,r){"use strict";var h=e("../utils"),i=e("./ConvertWorker"),s=e("./GenericWorker"),u=e("../base64"),n=e("../support"),a=e("../external"),o=null;if(n.nodestream)try{o=e("../nodejs/NodejsStreamOutputAdapter")}catch(e){}function l(e,o){return new a.Promise(function(t,r){var n=[],i=e._internalType,s=e._outputType,a=e._mimeType;e.on("data",function(e,t){n.push(e),o&&o(t)}).on("error",function(e){n=[],r(e)}).on("end",function(){try{var e=function(e,t,r){switch(e){case"blob":return h.newBlob(h.transformTo("arraybuffer",t),r);case"base64":return u.encode(t);default:return h.transformTo(e,t)}}(s,function(e,t){var r,n=0,i=null,s=0;for(r=0;r>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t}(e)},s.utf8decode=function(e){return h.nodebuffer?o.transformTo("nodebuffer",e).toString("utf-8"):function(e){var t,r,n,i,s=e.length,a=new Array(2*s);for(t=r=0;t>10&1023,a[r++]=56320|1023&n)}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(e=o.transformTo(h.uint8array?"uint8array":"array",e))},o.inherits(a,n),a.prototype.processChunk=function(e){var t=o.transformTo(h.uint8array?"uint8array":"array",e.data);if(this.leftOver&&this.leftOver.length){if(h.uint8array){var r=t;(t=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),t.set(r,this.leftOver.length)}else t=this.leftOver.concat(t);this.leftOver=null}var n=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}(t),i=t;n!==t.length&&(h.uint8array?(i=t.subarray(0,n),this.leftOver=t.subarray(n,t.length)):(i=t.slice(0,n),this.leftOver=t.slice(n,t.length))),this.push({data:s.utf8decode(i),meta:e.meta})},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},s.Utf8DecodeWorker=a,o.inherits(l,n),l.prototype.processChunk=function(e){this.push({data:s.utf8encode(e.data),meta:e.meta})},s.Utf8EncodeWorker=l},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(e,t,a){"use strict";var o=e("./support"),h=e("./base64"),r=e("./nodejsUtils"),u=e("./external");function n(e){return e}function l(e,t){for(var r=0;r>8;this.dir=!!(16&this.externalFileAttributes),0==e&&(this.dosPermissions=63&this.externalFileAttributes),3==e&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var e=n(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=e.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=e.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=e.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=e.readInt(4))}},readExtraFields:function(e){var t,r,n,i=e.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});e.index+4>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t},r.buf2binstring=function(e){return l(e,e.length)},r.binstring2buf=function(e){for(var t=new h.Buf8(e.length),r=0,n=t.length;r>10&1023,o[n++]=56320|1023&i)}return l(o,n)},r.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}},{"./common":41}],43:[function(e,t,r){"use strict";t.exports=function(e,t,r,n){for(var i=65535&e|0,s=e>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}},{}],46:[function(e,t,r){"use strict";var h,c=e("../utils/common"),u=e("./trees"),d=e("./adler32"),p=e("./crc32"),n=e("./messages"),l=0,f=4,m=0,_=-2,g=-1,b=4,i=2,v=8,y=9,s=286,a=30,o=19,w=2*s+1,k=15,x=3,S=258,z=S+x+1,C=42,E=113,A=1,I=2,O=3,B=4;function R(e,t){return e.msg=n[t],t}function T(e){return(e<<1)-(4e.avail_out&&(r=e.avail_out),0!==r&&(c.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0))}function N(e,t){u._tr_flush_block(e,0<=e.block_start?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,F(e.strm)}function U(e,t){e.pending_buf[e.pending++]=t}function P(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t}function L(e,t){var r,n,i=e.max_chain_length,s=e.strstart,a=e.prev_length,o=e.nice_match,h=e.strstart>e.w_size-z?e.strstart-(e.w_size-z):0,u=e.window,l=e.w_mask,f=e.prev,c=e.strstart+S,d=u[s+a-1],p=u[s+a];e.prev_length>=e.good_match&&(i>>=2),o>e.lookahead&&(o=e.lookahead);do{if(u[(r=t)+a]===p&&u[r+a-1]===d&&u[r]===u[s]&&u[++r]===u[s+1]){s+=2,r++;do{}while(u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&sh&&0!=--i);return a<=e.lookahead?a:e.lookahead}function j(e){var t,r,n,i,s,a,o,h,u,l,f=e.w_size;do{if(i=e.window_size-e.lookahead-e.strstart,e.strstart>=f+(f-z)){for(c.arraySet(e.window,e.window,f,f,0),e.match_start-=f,e.strstart-=f,e.block_start-=f,t=r=e.hash_size;n=e.head[--t],e.head[t]=f<=n?n-f:0,--r;);for(t=r=f;n=e.prev[--t],e.prev[t]=f<=n?n-f:0,--r;);i+=f}if(0===e.strm.avail_in)break;if(a=e.strm,o=e.window,h=e.strstart+e.lookahead,u=i,l=void 0,l=a.avail_in,u=x)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x)if(n=u._tr_tally(e,e.strstart-e.match_start,e.match_length-x),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=x){for(e.match_length--;e.strstart++,e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x&&e.match_length<=e.prev_length){for(i=e.strstart+e.lookahead-x,n=u._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-x),e.lookahead-=e.prev_length-1,e.prev_length-=2;++e.strstart<=i&&(e.ins_h=(e.ins_h<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(j(e),0===e.lookahead&&t===l)return A;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,N(e,!1),0===e.strm.avail_out))return A;if(e.strstart-e.block_start>=e.w_size-z&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):(e.strstart>e.block_start&&(N(e,!1),e.strm.avail_out),A)}),new M(4,4,8,4,Z),new M(4,5,16,8,Z),new M(4,6,32,32,Z),new M(4,4,16,16,W),new M(8,16,32,32,W),new M(8,16,128,128,W),new M(8,32,128,256,W),new M(32,128,258,1024,W),new M(32,258,258,4096,W)],r.deflateInit=function(e,t){return Y(e,t,v,15,8,0)},r.deflateInit2=Y,r.deflateReset=K,r.deflateResetKeep=G,r.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?_:(e.state.gzhead=t,m):_},r.deflate=function(e,t){var r,n,i,s;if(!e||!e.state||5>8&255),U(n,n.gzhead.time>>16&255),U(n,n.gzhead.time>>24&255),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(U(n,255&n.gzhead.extra.length),U(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(e.adler=p(e.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(U(n,0),U(n,0),U(n,0),U(n,0),U(n,0),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,3),n.status=E);else{var a=v+(n.w_bits-8<<4)<<8;a|=(2<=n.strategy||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(a|=32),a+=31-a%31,n.status=E,P(n,a),0!==n.strstart&&(P(n,e.adler>>>16),P(n,65535&e.adler)),e.adler=1}if(69===n.status)if(n.gzhead.extra){for(i=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending!==n.pending_buf_size));)U(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.status=103)}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&F(e),n.pending+2<=n.pending_buf_size&&(U(n,255&e.adler),U(n,e.adler>>8&255),e.adler=0,n.status=E)):n.status=E),0!==n.pending){if(F(e),0===e.avail_out)return n.last_flush=-1,m}else if(0===e.avail_in&&T(t)<=T(r)&&t!==f)return R(e,-5);if(666===n.status&&0!==e.avail_in)return R(e,-5);if(0!==e.avail_in||0!==n.lookahead||t!==l&&666!==n.status){var o=2===n.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(j(e),0===e.lookahead)){if(t===l)return A;break}if(e.match_length=0,r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):3===n.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=S){if(j(e),e.lookahead<=S&&t===l)return A;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=x&&0e.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=x?(r=u._tr_tally(e,1,e.match_length-x),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):h[n.level].func(n,t);if(o!==O&&o!==B||(n.status=666),o===A||o===O)return 0===e.avail_out&&(n.last_flush=-1),m;if(o===I&&(1===t?u._tr_align(n):5!==t&&(u._tr_stored_block(n,0,0,!1),3===t&&(D(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),F(e),0===e.avail_out))return n.last_flush=-1,m}return t!==f?m:n.wrap<=0?1:(2===n.wrap?(U(n,255&e.adler),U(n,e.adler>>8&255),U(n,e.adler>>16&255),U(n,e.adler>>24&255),U(n,255&e.total_in),U(n,e.total_in>>8&255),U(n,e.total_in>>16&255),U(n,e.total_in>>24&255)):(P(n,e.adler>>>16),P(n,65535&e.adler)),F(e),0=r.w_size&&(0===s&&(D(r.head),r.strstart=0,r.block_start=0,r.insert=0),u=new c.Buf8(r.w_size),c.arraySet(u,t,l-r.w_size,r.w_size,0),t=u,l=r.w_size),a=e.avail_in,o=e.next_in,h=e.input,e.avail_in=l,e.next_in=0,e.input=t,j(r);r.lookahead>=x;){for(n=r.strstart,i=r.lookahead-(x-1);r.ins_h=(r.ins_h<>>=y=v>>>24,p-=y,0===(y=v>>>16&255))C[s++]=65535&v;else{if(!(16&y)){if(0==(64&y)){v=m[(65535&v)+(d&(1<>>=y,p-=y),p<15&&(d+=z[n++]<>>=y=v>>>24,p-=y,!(16&(y=v>>>16&255))){if(0==(64&y)){v=_[(65535&v)+(d&(1<>>=y,p-=y,(y=s-a)>3,d&=(1<<(p-=w<<3))-1,e.next_in=n,e.next_out=s,e.avail_in=n>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function s(){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 I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function a(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=P,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new I.Buf32(n),t.distcode=t.distdyn=new I.Buf32(i),t.sane=1,t.back=-1,N):U}function o(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,a(e)):U}function h(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15=s.wsize?(I.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(n<(i=s.wsize-s.wnext)&&(i=n),I.arraySet(s.window,t,r-n,i,s.wnext),(n-=i)?(I.arraySet(s.window,t,r-n,n,0),s.wnext=n,s.whave=s.wsize):(s.wnext+=i,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=B(r.check,E,2,0),l=u=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&u)<<8)+(u>>8))%31){e.msg="incorrect header check",r.mode=30;break}if(8!=(15&u)){e.msg="unknown compression method",r.mode=30;break}if(l-=4,k=8+(15&(u>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){e.msg="invalid window size",r.mode=30;break}r.dmax=1<>8&1),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=3;case 3:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>8&255,E[2]=u>>>16&255,E[3]=u>>>24&255,r.check=B(r.check,E,4,0)),l=u=0,r.mode=4;case 4:for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>8),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=5;case 5:if(1024&r.flags){for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>>8&255,r.check=B(r.check,E,2,0)),l=u=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(d=r.length)&&(d=o),d&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,n,s,d,k)),512&r.flags&&(r.check=B(r.check,n,d,s)),o-=d,s+=d,r.length-=d),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break e;for(d=0;k=n[s+d++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&d>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=12;break;case 10:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>=7&l,l-=7&l,r.mode=27;break}for(;l<3;){if(0===o)break e;o--,u+=n[s++]<>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==t)break;u>>>=2,l-=2;break e;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=30}u>>>=2,l-=2;break;case 14:for(u>>>=7&l,l-=7&l;l<32;){if(0===o)break e;o--,u+=n[s++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&u,l=u=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(d=r.length){if(o>>=5,l-=5,r.ndist=1+(31&u),u>>>=5,l-=5,r.ncode=4+(15&u),u>>>=4,l-=4,286>>=3,l-=3}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=T(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=_,l-=_,r.lens[r.have++]=b;else{if(16===b){for(z=_+2;l>>=_,l-=_,0===r.have){e.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],d=3+(3&u),u>>>=2,l-=2}else if(17===b){for(z=_+3;l>>=_)),u>>>=3,l-=3}else{for(z=_+7;l>>=_)),u>>>=7,l-=7}if(r.have+d>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=30;break}for(;d--;)r.lens[r.have++]=k}}if(30===r.mode)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=T(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=T(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){e.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(6<=o&&258<=h){e.next_out=a,e.avail_out=h,e.next_in=s,e.avail_in=o,r.hold=u,r.bits=l,R(e,c),a=e.next_out,i=e.output,h=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,u=r.hold,l=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(C=r.lencode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,r.length=b,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){e.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;g=(C=r.distcode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,64&g){e.msg="invalid distance code",r.mode=30;break}r.offset=b,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===h)break e;if(d=c-h,r.offset>d){if((d=r.offset-d)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=30;break}p=d>r.wnext?(d-=r.wnext,r.wsize-d):r.wnext-d,d>r.length&&(d=r.length),m=r.window}else m=i,p=a-r.offset,d=r.length;for(hd?(m=R[T+a[v]],A[I+a[v]]):(m=96,0),h=1<>S)+(u-=h)]=p<<24|m<<16|_|0,0!==u;);for(h=1<>=1;if(0!==h?(E&=h-1,E+=h):E=0,v++,0==--O[b]){if(b===w)break;b=t[r+a[v]]}if(k>>7)]}function U(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255}function P(e,t,r){e.bi_valid>d-r?(e.bi_buf|=t<>d-e.bi_valid,e.bi_valid+=r-d):(e.bi_buf|=t<>>=1,r<<=1,0<--t;);return r>>>1}function Z(e,t,r){var n,i,s=new Array(g+1),a=0;for(n=1;n<=g;n++)s[n]=a=a+r[n-1]<<1;for(i=0;i<=t;i++){var o=e[2*i+1];0!==o&&(e[2*i]=j(s[o]++,o))}}function W(e){var t;for(t=0;t>1;1<=r;r--)G(e,s,r);for(i=h;r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],G(e,s,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,s[2*i]=s[2*r]+s[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,s[2*r+1]=s[2*n+1]=i,e.heap[1]=i++,G(e,s,1),2<=e.heap_len;);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,s,a,o,h=t.dyn_tree,u=t.max_code,l=t.stat_desc.static_tree,f=t.stat_desc.has_stree,c=t.stat_desc.extra_bits,d=t.stat_desc.extra_base,p=t.stat_desc.max_length,m=0;for(s=0;s<=g;s++)e.bl_count[s]=0;for(h[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<_;r++)p<(s=h[2*h[2*(n=e.heap[r])+1]+1]+1)&&(s=p,m++),h[2*n+1]=s,u>=7;n>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return o;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return h;for(t=32;t>>3,(s=e.static_len+3+7>>>3)<=i&&(i=s)):i=s=r+5,r+4<=i&&-1!==t?J(e,t,r,n):4===e.strategy||s===i?(P(e,2+(n?1:0),3),K(e,z,C)):(P(e,4+(n?1:0),3),function(e,t,r,n){var i;for(P(e,t-257,5),P(e,r-1,5),P(e,n-4,4),i=0;i>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(A[r]+u+1)]++,e.dyn_dtree[2*N(t)]++),e.last_lit===e.lit_bufsize-1},r._tr_align=function(e){P(e,2,3),L(e,m,z),function(e){16===e.bi_valid?(U(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):8<=e.bi_valid&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)}(e)}},{"../utils/common":41}],53:[function(e,t,r){"use strict";t.exports=function(){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}},{}],54:[function(e,t,r){(function(e){!function(r,n){"use strict";if(!r.setImmediate){var i,s,t,a,o=1,h={},u=!1,l=r.document,e=Object.getPrototypeOf&&Object.getPrototypeOf(r);e=e&&e.setTimeout?e:r,i="[object process]"==={}.toString.call(r.process)?function(e){process.nextTick(function(){c(e)})}:function(){if(r.postMessage&&!r.importScripts){var e=!0,t=r.onmessage;return r.onmessage=function(){e=!1},r.postMessage("","*"),r.onmessage=t,e}}()?(a="setImmediate$"+Math.random()+"$",r.addEventListener?r.addEventListener("message",d,!1):r.attachEvent("onmessage",d),function(e){r.postMessage(a+e,"*")}):r.MessageChannel?((t=new MessageChannel).port1.onmessage=function(e){c(e.data)},function(e){t.port2.postMessage(e)}):l&&"onreadystatechange"in l.createElement("script")?(s=l.documentElement,function(e){var t=l.createElement("script");t.onreadystatechange=function(){c(e),t.onreadystatechange=null,s.removeChild(t),t=null},s.appendChild(t)}):function(e){setTimeout(c,0,e)},e.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),r=0;r