From 1009cd4284ac69d4f102b160571d2bc56dcba19d Mon Sep 17 00:00:00 2001 From: NI Date: Thu, 12 Mar 2020 21:18:08 +0800 Subject: [PATCH] Use a better method to reload command presets --- application/application.go | 14 +- application/command/commands.go | 40 +- application/command/handler_stream_test.go | 2 +- application/commands/commands.go | 4 +- application/commands/ssh.go | 26 +- application/commands/telnet.go | 28 +- application/configuration/loader.go | 9 +- application/configuration/loader_direct.go | 5 +- application/configuration/loader_enviro.go | 9 +- application/configuration/loader_file.go | 18 +- application/configuration/loader_redundant.go | 7 +- application/controller/static_pages.go | 410 ++++++------------ 12 files changed, 202 insertions(+), 370 deletions(-) diff --git a/application/application.go b/application/application.go index 0d75e4ff..31f48129 100644 --- a/application/application.go +++ b/application/application.go @@ -72,9 +72,7 @@ func (a Application) run( ) (bool, error) { var err error - loaderName, c, cErr := cLoader( - a.logger.Context("Configuration"), - commands.Reconfigure) + loaderName, c, cErr := cLoader(a.logger.Context("Configuration")) if cErr != nil { a.logger.Error("\"%s\" loader cannot load configuration: %s", @@ -83,6 +81,16 @@ func (a Application) run( return false, cErr } + // Allowing command to alter presets + c.Presets, err = commands.Reconfigure(c.Presets) + + if err != nil { + a.logger.Error("Unable to reconfigure presets: %s", err) + + return false, err + } + + // Verify all configuration err = c.Verify() if err != nil { diff --git a/application/command/commands.go b/application/command/commands.go index 48ac3903..eaf3f8d5 100644 --- a/application/command/commands.go +++ b/application/command/commands.go @@ -45,13 +45,15 @@ type Command func( // Builder builds a command type Builder struct { + name string command Command - configurator configuration.Reconfigurator + configurator configuration.PresetReloader } // Register builds a Builder for registration -func Register(c Command, p configuration.Reconfigurator) Builder { +func Register(name string, c Command, p configuration.PresetReloader) Builder { return Builder{ + name: name, command: c, configurator: p, } @@ -62,7 +64,11 @@ type Commands [MaxCommandID + 1]Builder // Register registers a new command func (c *Commands) Register( - id byte, cb Command, ps configuration.Reconfigurator) { + id byte, + name string, + cb Command, + ps configuration.PresetReloader, +) { if id > MaxCommandID { panic("Command ID must be not greater than MaxCommandID") } @@ -71,7 +77,7 @@ func (c *Commands) Register( panic(fmt.Sprintf("Command %d already been registered", id)) } - (*c)[id] = Register(cb, ps) + (*c)[id] = Register(name, cb, ps) } // Run creates command executer @@ -96,15 +102,27 @@ func (c Commands) Run( // Reconfigure lets commands reset configuration func (c Commands) Reconfigure( - p configuration.Configuration, -) configuration.Configuration { + p []configuration.Preset, +) ([]configuration.Preset, error) { + newP := make([]configuration.Preset, 0, len(p)) + for i := range c { - if c[i].configurator == nil { - continue - } + for pp := range p { + if c[i].name != p[pp].Type { + continue + } + + newPP, pErr := c[i].configurator(p[pp]) - p = c[i].configurator(p) + if pErr == nil { + newP = append(newP, newPP) + + continue + } + + return nil, pErr + } } - return p + return newP, nil } diff --git a/application/command/handler_stream_test.go b/application/command/handler_stream_test.go index 154afd86..0040c7c2 100644 --- a/application/command/handler_stream_test.go +++ b/application/command/handler_stream_test.go @@ -171,7 +171,7 @@ func (d *dummyStreamCommand) Release() error { func TestHandlerHandleStream(t *testing.T) { cmds := Commands{} - cmds.Register(0, newDummyStreamCommand, nil) + cmds.Register(0, "name", newDummyStreamCommand, nil) readerDataInput := make(chan []byte) diff --git a/application/commands/commands.go b/application/commands/commands.go index b2157f87..5d99b5e2 100644 --- a/application/commands/commands.go +++ b/application/commands/commands.go @@ -24,7 +24,7 @@ import ( // New creates a new commands group func New() command.Commands { return command.Commands{ - command.Register(newTelnet, parseTelnetConfig), - command.Register(newSSH, parseSSHConfig), + command.Register("Telnet", newTelnet, parseTelnetConfig), + command.Register("SSH", newSSH, parseSSHConfig), } } diff --git a/application/commands/ssh.go b/application/commands/ssh.go index af3b0cae..a4cf68b9 100644 --- a/application/commands/ssh.go +++ b/application/commands/ssh.go @@ -203,28 +203,20 @@ func newSSH( } } -func parseSSHConfig(p configuration.Configuration) configuration.Configuration { - for i := range p.Presets { - if p.Presets[i].Type != "SSH" { - continue - } - - oldHost := p.Presets[i].Host +func parseSSHConfig(p configuration.Preset) (configuration.Preset, error) { + oldHost := p.Host - _, _, sErr := net.SplitHostPort(p.Presets[i].Host) + _, _, sErr := net.SplitHostPort(p.Host) - if sErr != nil { - p.Presets[i].Host = net.JoinHostPort( - p.Presets[i].Host, - sshDefaultPortString) - } + if sErr != nil { + p.Host = net.JoinHostPort(p.Host, sshDefaultPortString) + } - if len(p.Presets[i].Host) <= 0 { - p.Presets[i].Host = oldHost - } + if len(p.Host) <= 0 { + p.Host = oldHost } - return p + return p, nil } func (d *sshClient) Bootup( diff --git a/application/commands/telnet.go b/application/commands/telnet.go index d295b2d6..48bd7d7c 100644 --- a/application/commands/telnet.go +++ b/application/commands/telnet.go @@ -76,30 +76,20 @@ func newTelnet( } } -func parseTelnetConfig( - p configuration.Configuration, -) configuration.Configuration { - for i := range p.Presets { - if p.Presets[i].Type != "Telnet" { - continue - } - - oldHost := p.Presets[i].Host +func parseTelnetConfig(p configuration.Preset) (configuration.Preset, error) { + oldHost := p.Host - _, _, sErr := net.SplitHostPort(p.Presets[i].Host) + _, _, sErr := net.SplitHostPort(p.Host) - if sErr != nil { - p.Presets[i].Host = net.JoinHostPort( - p.Presets[i].Host, - telnetDefaultPortString) - } + if sErr != nil { + p.Host = net.JoinHostPort(p.Host, telnetDefaultPortString) + } - if len(p.Presets[i].Host) <= 0 { - p.Presets[i].Host = oldHost - } + if len(p.Host) <= 0 { + p.Host = oldHost } - return p + return p, nil } func (d *telnetClient) Bootup( diff --git a/application/configuration/loader.go b/application/configuration/loader.go index 3b2a7735..366fa08c 100644 --- a/application/configuration/loader.go +++ b/application/configuration/loader.go @@ -21,11 +21,8 @@ import ( "github.com/niruix/sshwifty/application/log" ) -// Reconfigurator reloads configuration -type Reconfigurator func(p Configuration) Configuration +// PresetReloader reloads preset +type PresetReloader func(p Preset) (Preset, error) // Loader Configuration loader -type Loader func( - log log.Logger, - r Reconfigurator, -) (name string, cfg Configuration, err error) +type Loader func(log log.Logger) (name string, cfg Configuration, err error) diff --git a/application/configuration/loader_direct.go b/application/configuration/loader_direct.go index 948df768..796b0440 100644 --- a/application/configuration/loader_direct.go +++ b/application/configuration/loader_direct.go @@ -28,10 +28,7 @@ const ( // Direct creates a loader that return raw configuration data directly. // Good for integration. func Direct(cfg Configuration) Loader { - return func( - log log.Logger, - r Reconfigurator, - ) (string, Configuration, error) { + return func(log log.Logger) (string, Configuration, error) { return directTypeName, cfg, nil } } diff --git a/application/configuration/loader_enviro.go b/application/configuration/loader_enviro.go index b57ea6d6..b706012d 100644 --- a/application/configuration/loader_enviro.go +++ b/application/configuration/loader_enviro.go @@ -44,10 +44,7 @@ func parseEviro(name string) string { // Enviro creates an environment variable based configuration loader func Enviro() Loader { - return func( - log log.Logger, - r Reconfigurator, - ) (string, Configuration, error) { + return func(log log.Logger) (string, Configuration, error) { log.Info("Loading configuration from environment variables ...") dialTimeout, _ := strconv.ParseUint( @@ -123,7 +120,7 @@ func Enviro() Loader { } } - return enviroTypeName, r(Configuration{ + return enviroTypeName, Configuration{ HostName: cfg.HostName, SharedKey: cfg.SharedKey, DialTimeout: time.Duration(cfg.DialTimeout) * time.Second, @@ -133,6 +130,6 @@ func Enviro() Loader { Servers: []Server{cfgSer.build()}, Presets: presets, OnlyAllowPresetRemotes: cfg.OnlyAllowPresetRemotes, - }), nil + }, nil } } diff --git a/application/configuration/loader_file.go b/application/configuration/loader_file.go index 6fec632f..2717da93 100644 --- a/application/configuration/loader_file.go +++ b/application/configuration/loader_file.go @@ -135,10 +135,7 @@ func (f fileCfgCommon) build() (fileCfgCommon, error) { }, nil } -func loadFile( - filePath string, - r Reconfigurator, -) (string, Configuration, error) { +func loadFile(filePath string) (string, Configuration, error) { f, fErr := os.Open(filePath) if fErr != nil { @@ -174,7 +171,7 @@ func loadFile( presets[i] = finalCfg.Presets[i].build() } - return fileTypeName, r(Configuration{ + return fileTypeName, Configuration{ HostName: finalCfg.HostName, SharedKey: finalCfg.SharedKey, DialTimeout: time.Duration(finalCfg.DialTimeout) * @@ -185,19 +182,16 @@ func loadFile( Servers: servers, Presets: presets, OnlyAllowPresetRemotes: cfg.OnlyAllowPresetRemotes, - }), nil + }, nil } // File creates a configuration file loader func File(customPath string) Loader { - return func( - log log.Logger, - r Reconfigurator, - ) (string, Configuration, error) { + return func(log log.Logger) (string, Configuration, error) { if len(customPath) > 0 { log.Info("Loading configuration from: %s", customPath) - return loadFile(customPath, r) + return loadFile(customPath) } log.Info("Loading configuration from one of the default " + @@ -239,7 +233,7 @@ func File(customPath string) Loader { log.Info("Configuration file \"%s\" has been selected", fallbackFileSearchList[f]) - return loadFile(fallbackFileSearchList[f], r) + return loadFile(fallbackFileSearchList[f]) } return fileTypeName, Configuration{}, fmt.Errorf( diff --git a/application/configuration/loader_redundant.go b/application/configuration/loader_redundant.go index 44605ca8..b85c99cd 100644 --- a/application/configuration/loader_redundant.go +++ b/application/configuration/loader_redundant.go @@ -30,14 +30,11 @@ const ( // Redundant creates a group of loaders. They will be executed one by one until // one of it successfully returned a configuration func Redundant(loaders ...Loader) Loader { - return func( - log log.Logger, - r Reconfigurator, - ) (string, Configuration, error) { + return func(log log.Logger) (string, Configuration, error) { ll := log.Context("Redundant") for i := range loaders { - lLoaderName, lCfg, lErr := loaders[i](ll, r) + lLoaderName, lCfg, lErr := loaders[i](ll) if lErr != nil { ll.Warning("Unable to load configuration from \"%s\": %s", diff --git a/application/controller/static_pages.go b/application/controller/static_pages.go index 64e45cf8..8af228d7 100644 --- a/application/controller/static_pages.go +++ b/application/controller/static_pages.go @@ -20,296 +20,138 @@ package controller //go:generate go run ./static_page_generater ../../.tmp/dist ./static_pages.go //go:generate go fmt ./static_pages.go -// This file is generated by `go generate` at Mon, 12 Aug 2019 11:04:30 CST +// This file is generated by `go generate` at Thu, 12 Mar 2020 20:25:38 CST // DO NOT EDIT! -import "io/ioutil" -import "bytes" -import "fmt" -import "compress/gzip" -import "encoding/base64" -import "time" -import "crypto/sha256" - -// WARNING: THIS GENERATION IS FOR DEBUG / DEVELOPMENT ONLY, DO NOT -// USE IT IN PRODUCTION! - -func staticFileGen(filePath string) staticData { - content, readErr := ioutil.ReadFile(filePath) - - if readErr != nil { - panic(fmt.Sprintln("Cannot read file:", readErr)) - } - - compressed := bytes.NewBuffer(make([]byte, 0, 1024)) - - compresser, compresserBuildErr := gzip.NewWriterLevel( - compressed, gzip.BestCompression) - - if compresserBuildErr != nil { - panic(fmt.Sprintln("Cannot build data compresser:", compresserBuildErr)) - } - - contentLen := len(content) - - _, compressErr := compresser.Write(content) - - if compressErr != nil { - panic(fmt.Sprintln("Cannot write compressed data:", compressErr)) - } +import "github.com/niruix/sshwifty/application/controller/static_pages" - compressErr = compresser.Flush() - - if compressErr != nil { - panic(fmt.Sprintln("Cannot write compressed data:", compressErr)) - } - - content = append(content, compressed.Bytes()...) - - getHash := func(b []byte) []byte { - h := sha256.New() - h.Write(b) +import "time" - return h.Sum(nil) +var ( + staticPages = map[string]staticData{ + "0.2591207cde2357871355.js": parseStaticData(static_pages.Static0()), + "010c539b67fe9bacabc4ec5dbff1546b.svg": parseStaticData(static_pages.Static1()), + "0b3811d040152efecd499f74a840805b.woff2": parseStaticData(static_pages.Static2()), + "132527c8a67bf941ca84add5608a81a3.woff": parseStaticData(static_pages.Static3()), + "13ec0eb5bdb821ff4930237d7c9f943f.woff2": parseStaticData(static_pages.Static4()), + "13efe6cbc10b97144a28310ebdeda594.woff": parseStaticData(static_pages.Static5()), + "1d6594826615607f6dc860bb49258acb.woff": parseStaticData(static_pages.Static6()), + "2.2591207cde2357871355.js": parseStaticData(static_pages.Static7()), + "23d1ed95cedfe6dc88667aa59d91a620.woff2": parseStaticData(static_pages.Static8()), + "2591207cde2357871355.css": parseStaticData(static_pages.Static9()), + "2591207cde2357871355.css.map": parseStaticData(static_pages.Static10()), + "2591207cde2357871355.js": parseStaticData(static_pages.Static11()), + "3.2591207cde2357871355.js": parseStaticData(static_pages.Static12()), + "313a65630d341645c13e4f2a0364381d.woff": parseStaticData(static_pages.Static13()), + "35b07eb2f8711ae08d1f58c043880930.woff": parseStaticData(static_pages.Static14()), + "3aa797141ef00f0aa9fc.css": parseStaticData(static_pages.Static15()), + "3aa797141ef00f0aa9fc.css.map": parseStaticData(static_pages.Static16()), + "4.2591207cde2357871355.js": parseStaticData(static_pages.Static17()), + "4357beb823a5f8d65c260f045d9e019a.woff2": parseStaticData(static_pages.Static18()), + "4fe0f73cc919ba2b7a3c36e4540d725c.woff": parseStaticData(static_pages.Static19()), + "5.2591207cde2357871355.js": parseStaticData(static_pages.Static20()), + "50d75e48e0a3ddab1dd15d6bfb9d3700.woff": parseStaticData(static_pages.Static21()), + "59eb3601394dd87f30f82433fb39dd94.woff2": parseStaticData(static_pages.Static22()), + "5b4a33e176ff736a74f0ca2dd9e6b396.woff2": parseStaticData(static_pages.Static23()), + "6.2591207cde2357871355.js": parseStaticData(static_pages.Static24()), + "73f0a88bbca1bec19fb1303c689d04c6.woff2": parseStaticData(static_pages.Static25()), + "83e114c316fcc3f23f524ec3e1c65984.woff": parseStaticData(static_pages.Static26()), + "8a96edbbcd9a6991d79371aed0b0288e.woff": parseStaticData(static_pages.Static27()), + "8ec888af4672fe48c5560b5e7c0ecb78.woff": parseStaticData(static_pages.Static28()), + "90d1676003d9c28c04994c18bfd8b558.woff2": parseStaticData(static_pages.Static29()), + "94008e69aaf05da75c0bbf8f8bb0db41.woff2": parseStaticData(static_pages.Static30()), + "DEPENDENCIES.md": parseStaticData(static_pages.Static31()), + "LICENSE.md": parseStaticData(static_pages.Static32()), + "README.md": parseStaticData(static_pages.Static33()), + "ad538a69b0e8615ed0419c4529344ffc.woff2": parseStaticData(static_pages.Static34()), + "android-chrome-144x144.png": parseStaticData(static_pages.Static35()), + "android-chrome-192x192.png": parseStaticData(static_pages.Static36()), + "android-chrome-256x256.png": parseStaticData(static_pages.Static37()), + "android-chrome-36x36.png": parseStaticData(static_pages.Static38()), + "android-chrome-384x384.png": parseStaticData(static_pages.Static39()), + "android-chrome-48x48.png": parseStaticData(static_pages.Static40()), + "android-chrome-512x512.png": parseStaticData(static_pages.Static41()), + "android-chrome-72x72.png": parseStaticData(static_pages.Static42()), + "android-chrome-96x96.png": parseStaticData(static_pages.Static43()), + "apple-touch-icon-1024x1024.png": parseStaticData(static_pages.Static44()), + "apple-touch-icon-114x114.png": parseStaticData(static_pages.Static45()), + "apple-touch-icon-120x120.png": parseStaticData(static_pages.Static46()), + "apple-touch-icon-144x144.png": parseStaticData(static_pages.Static47()), + "apple-touch-icon-152x152.png": parseStaticData(static_pages.Static48()), + "apple-touch-icon-167x167.png": parseStaticData(static_pages.Static49()), + "apple-touch-icon-180x180.png": parseStaticData(static_pages.Static50()), + "apple-touch-icon-57x57.png": parseStaticData(static_pages.Static51()), + "apple-touch-icon-60x60.png": parseStaticData(static_pages.Static52()), + "apple-touch-icon-72x72.png": parseStaticData(static_pages.Static53()), + "apple-touch-icon-76x76.png": parseStaticData(static_pages.Static54()), + "apple-touch-icon-precomposed.png": parseStaticData(static_pages.Static55()), + "apple-touch-icon.png": parseStaticData(static_pages.Static56()), + "apple-touch-startup-image-1182x2208.png": parseStaticData(static_pages.Static57()), + "apple-touch-startup-image-1242x2148.png": parseStaticData(static_pages.Static58()), + "apple-touch-startup-image-1496x2048.png": parseStaticData(static_pages.Static59()), + "apple-touch-startup-image-1536x2008.png": parseStaticData(static_pages.Static60()), + "apple-touch-startup-image-320x460.png": parseStaticData(static_pages.Static61()), + "apple-touch-startup-image-640x1096.png": parseStaticData(static_pages.Static62()), + "apple-touch-startup-image-640x920.png": parseStaticData(static_pages.Static63()), + "apple-touch-startup-image-748x1024.png": parseStaticData(static_pages.Static64()), + "apple-touch-startup-image-750x1294.png": parseStaticData(static_pages.Static65()), + "apple-touch-startup-image-768x1004.png": parseStaticData(static_pages.Static66()), + "b52fac2bb93c5858f3f2675e4b52e1de.woff2": parseStaticData(static_pages.Static67()), + "browserconfig.xml": parseStaticData(static_pages.Static68()), + "c023bfb8571ccdf77bdd94a308ea3162.svg": parseStaticData(static_pages.Static69()), + "c6af87fef241bf953aa3.css": parseStaticData(static_pages.Static70()), + "c6af87fef241bf953aa3.css.map": parseStaticData(static_pages.Static71()), + "c73eb1ceba3321a80a0aff13ad373cb4.woff": parseStaticData(static_pages.Static72()), + "cc2fadc3928f2f223418887111947b40.woff": parseStaticData(static_pages.Static73()), + "d26871e8149b5759f814fd3c7a4f784b.woff2": parseStaticData(static_pages.Static74()), + "d3b47375afd904983d9be8d6e239a949.woff": parseStaticData(static_pages.Static75()), + "d4a48f0f981279da0e207e47516f4354.woff": parseStaticData(static_pages.Static76()), + "d569415005f26953bb9c3c52895355eb.woff2": parseStaticData(static_pages.Static77()), + "e72f2a56d5e5f8c8decc.css": parseStaticData(static_pages.Static78()), + "e72f2a56d5e5f8c8decc.css.map": parseStaticData(static_pages.Static79()), + "e8eaae902c3a4dacb9a5062667e10576.woff2": parseStaticData(static_pages.Static80()), + "error.html": parseStaticData(static_pages.Static81()), + "f5902d5ef961717ed263902fc429e6ae.woff": parseStaticData(static_pages.Static82()), + "f75569f8a5fab0893fa712d8c0d9c3fe.woff2": parseStaticData(static_pages.Static83()), + "f93c333e41413ed8548b714ad10a14fe.woff2": parseStaticData(static_pages.Static84()), + "favicon-16x16.png": parseStaticData(static_pages.Static85()), + "favicon-32x32.png": parseStaticData(static_pages.Static86()), + "favicon.ico": parseStaticData(static_pages.Static87()), + "fdea8596c4f9e3699f0cd51255a9e0f1.woff": parseStaticData(static_pages.Static88()), + "firefox_app_128x128.png": parseStaticData(static_pages.Static89()), + "firefox_app_512x512.png": parseStaticData(static_pages.Static90()), + "firefox_app_60x60.png": parseStaticData(static_pages.Static91()), + "index.html": parseStaticData(static_pages.Static92()), + "manifest.json": parseStaticData(static_pages.Static93()), + "manifest.webapp": parseStaticData(static_pages.Static94()), + "mstile-144x144.png": parseStaticData(static_pages.Static95()), + "mstile-150x150.png": parseStaticData(static_pages.Static96()), + "mstile-310x150.png": parseStaticData(static_pages.Static97()), + "mstile-310x310.png": parseStaticData(static_pages.Static98()), + "mstile-70x70.png": parseStaticData(static_pages.Static99()), + "robots.txt": parseStaticData(static_pages.Static100()), } +) +// parseStaticData parses result from a static file returner and generate +// a new `staticData` item +func parseStaticData( + fileStart int, + fileEnd int, + compressedStart int, + compressedEnd int, + contentHash string, + compressedHash string, + creation time.Time, + data []byte, + contentType string, +) staticData { return staticData{ - data: content[0:contentLen], - dataHash: base64.StdEncoding.EncodeToString( - getHash(content[0:contentLen])[:8]), - compressd: content[contentLen:], - compressdHash: base64.StdEncoding.EncodeToString( - getHash(content[contentLen:])[:8]), - created: time.Now(), + data: data[fileStart:fileEnd], + dataHash: contentHash, + compressd: data[compressedStart:compressedEnd], + compressdHash: compressedHash, + created: creation, + contentType: contentType, } } - -var ( - staticPages = map[string]staticData{ - "13ec0eb5bdb821ff4930237d7c9f943f.woff2": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/13ec0eb5bdb821ff4930237d7c9f943f.woff2", - ), - "13efe6cbc10b97144a28310ebdeda594.woff": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/13efe6cbc10b97144a28310ebdeda594.woff", - ), - "1d6594826615607f6dc860bb49258acb.woff": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/1d6594826615607f6dc860bb49258acb.woff", - ), - "313a65630d341645c13e4f2a0364381d.woff": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/313a65630d341645c13e4f2a0364381d.woff", - ), - "35b07eb2f8711ae08d1f58c043880930.woff": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/35b07eb2f8711ae08d1f58c043880930.woff", - ), - "4248c72df3d263be21b6d.css": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/4248c72df3d263be21b6d.css", - ), - "4248c72df3d263be21b6d.js": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/4248c72df3d263be21b6d.js", - ), - "4357beb823a5f8d65c260f045d9e019a.woff2": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/4357beb823a5f8d65c260f045d9e019a.woff2", - ), - "4fe0f73cc919ba2b7a3c36e4540d725c.woff": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/4fe0f73cc919ba2b7a3c36e4540d725c.woff", - ), - "50d75e48e0a3ddab1dd15d6bfb9d3700.woff": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/50d75e48e0a3ddab1dd15d6bfb9d3700.woff", - ), - "59eb3601394dd87f30f82433fb39dd94.woff2": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/59eb3601394dd87f30f82433fb39dd94.woff2", - ), - "5b4a33e176ff736a74f0ca2dd9e6b396.woff2": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/5b4a33e176ff736a74f0ca2dd9e6b396.woff2", - ), - "73f0a88bbca1bec19fb1303c689d04c6.woff2": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/73f0a88bbca1bec19fb1303c689d04c6.woff2", - ), - "83e114c316fcc3f23f524ec3e1c65984.woff": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/83e114c316fcc3f23f524ec3e1c65984.woff", - ), - "8a96edbbcd9a6991d79371aed0b0288e.woff": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/8a96edbbcd9a6991d79371aed0b0288e.woff", - ), - "90d1676003d9c28c04994c18bfd8b558.woff2": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/90d1676003d9c28c04994c18bfd8b558.woff2", - ), - "94008e69aaf05da75c0bbf8f8bb0db41.woff2": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/94008e69aaf05da75c0bbf8f8bb0db41.woff2", - ), - "ad538a69b0e8615ed0419c4529344ffc.woff2": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/ad538a69b0e8615ed0419c4529344ffc.woff2", - ), - "android-chrome-144x144.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/android-chrome-144x144.png", - ), - "android-chrome-192x192.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/android-chrome-192x192.png", - ), - "android-chrome-256x256.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/android-chrome-256x256.png", - ), - "android-chrome-36x36.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/android-chrome-36x36.png", - ), - "android-chrome-384x384.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/android-chrome-384x384.png", - ), - "android-chrome-48x48.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/android-chrome-48x48.png", - ), - "android-chrome-512x512.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/android-chrome-512x512.png", - ), - "android-chrome-72x72.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/android-chrome-72x72.png", - ), - "android-chrome-96x96.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/android-chrome-96x96.png", - ), - "apple-touch-icon-1024x1024.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon-1024x1024.png", - ), - "apple-touch-icon-114x114.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon-114x114.png", - ), - "apple-touch-icon-120x120.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon-120x120.png", - ), - "apple-touch-icon-144x144.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon-144x144.png", - ), - "apple-touch-icon-152x152.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon-152x152.png", - ), - "apple-touch-icon-167x167.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon-167x167.png", - ), - "apple-touch-icon-180x180.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon-180x180.png", - ), - "apple-touch-icon-57x57.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon-57x57.png", - ), - "apple-touch-icon-60x60.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon-60x60.png", - ), - "apple-touch-icon-72x72.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon-72x72.png", - ), - "apple-touch-icon-76x76.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon-76x76.png", - ), - "apple-touch-icon-precomposed.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon-precomposed.png", - ), - "apple-touch-icon.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-icon.png", - ), - "apple-touch-startup-image-1182x2208.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-startup-image-1182x2208.png", - ), - "apple-touch-startup-image-1242x2148.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-startup-image-1242x2148.png", - ), - "apple-touch-startup-image-1496x2048.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-startup-image-1496x2048.png", - ), - "apple-touch-startup-image-1536x2008.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-startup-image-1536x2008.png", - ), - "apple-touch-startup-image-320x460.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-startup-image-320x460.png", - ), - "apple-touch-startup-image-640x1096.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-startup-image-640x1096.png", - ), - "apple-touch-startup-image-640x920.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-startup-image-640x920.png", - ), - "apple-touch-startup-image-748x1024.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-startup-image-748x1024.png", - ), - "apple-touch-startup-image-750x1294.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-startup-image-750x1294.png", - ), - "apple-touch-startup-image-768x1004.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/apple-touch-startup-image-768x1004.png", - ), - "b52fac2bb93c5858f3f2675e4b52e1de.woff2": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/b52fac2bb93c5858f3f2675e4b52e1de.woff2", - ), - "browserconfig.xml": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/browserconfig.xml", - ), - "c599374e350aa7225ee3e8a114e8d8d7.svg": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/c599374e350aa7225ee3e8a114e8d8d7.svg", - ), - "c73eb1ceba3321a80a0aff13ad373cb4.woff": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/c73eb1ceba3321a80a0aff13ad373cb4.woff", - ), - "cc2fadc3928f2f223418887111947b40.woff": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/cc2fadc3928f2f223418887111947b40.woff", - ), - "d26871e8149b5759f814fd3c7a4f784b.woff2": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/d26871e8149b5759f814fd3c7a4f784b.woff2", - ), - "d3b47375afd904983d9be8d6e239a949.woff": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/d3b47375afd904983d9be8d6e239a949.woff", - ), - "e8eaae902c3a4dacb9a5062667e10576.woff2": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/e8eaae902c3a4dacb9a5062667e10576.woff2", - ), - "ea4853ff509fe5f353d52586fcb94e20.svg": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/ea4853ff509fe5f353d52586fcb94e20.svg", - ), - "f5902d5ef961717ed263902fc429e6ae.woff": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/f5902d5ef961717ed263902fc429e6ae.woff", - ), - "f75569f8a5fab0893fa712d8c0d9c3fe.woff2": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/f75569f8a5fab0893fa712d8c0d9c3fe.woff2", - ), - "favicon-16x16.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/favicon-16x16.png", - ), - "favicon-32x32.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/favicon-32x32.png", - ), - "favicon.ico": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/favicon.ico", - ), - "firefox_app_128x128.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/firefox_app_128x128.png", - ), - "firefox_app_512x512.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/firefox_app_512x512.png", - ), - "firefox_app_60x60.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/firefox_app_60x60.png", - ), - "index.html": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/index.html", - ), - "manifest.json": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/manifest.json", - ), - "manifest.webapp": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/manifest.webapp", - ), - "mstile-144x144.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/mstile-144x144.png", - ), - "mstile-150x150.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/mstile-150x150.png", - ), - "mstile-310x150.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/mstile-310x150.png", - ), - "mstile-310x310.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/mstile-310x310.png", - ), - "mstile-70x70.png": staticFileGen( - "/home/rany/Development/Projects/webssh/.tmp/dist/mstile-70x70.png", - ), - } -)