Эх сурвалжийг харах

d04 Обновление вендоринга

SVI 2 жил өмнө
parent
commit
bdcae9060f

+ 65 - 0
vendor/github.com/gofiber/fiber/v2/middleware/compress/compress.go

@@ -0,0 +1,65 @@
+package compress
+
+import (
+	"github.com/gofiber/fiber/v2"
+
+	"github.com/valyala/fasthttp"
+)
+
+// New creates a new middleware handler
+func New(config ...Config) fiber.Handler {
+	// Set default config
+	cfg := configDefault(config...)
+
+	// Setup request handlers
+	var (
+		fctx       = func(c *fasthttp.RequestCtx) {}
+		compressor fasthttp.RequestHandler
+	)
+
+	// Setup compression algorithm
+	switch cfg.Level {
+	case LevelDefault:
+		// LevelDefault
+		compressor = fasthttp.CompressHandlerBrotliLevel(fctx,
+			fasthttp.CompressBrotliDefaultCompression,
+			fasthttp.CompressDefaultCompression,
+		)
+	case LevelBestSpeed:
+		// LevelBestSpeed
+		compressor = fasthttp.CompressHandlerBrotliLevel(fctx,
+			fasthttp.CompressBrotliBestSpeed,
+			fasthttp.CompressBestSpeed,
+		)
+	case LevelBestCompression:
+		// LevelBestCompression
+		compressor = fasthttp.CompressHandlerBrotliLevel(fctx,
+			fasthttp.CompressBrotliBestCompression,
+			fasthttp.CompressBestCompression,
+		)
+	default:
+		// LevelDisabled
+		return func(c *fiber.Ctx) error {
+			return c.Next()
+		}
+	}
+
+	// Return new handler
+	return func(c *fiber.Ctx) error {
+		// Don't execute middleware if Next returns true
+		if cfg.Next != nil && cfg.Next(c) {
+			return c.Next()
+		}
+
+		// Continue stack
+		if err := c.Next(); err != nil {
+			return err
+		}
+
+		// Compress response
+		compressor(c.Context())
+
+		// Return from handler
+		return nil
+	}
+}

+ 56 - 0
vendor/github.com/gofiber/fiber/v2/middleware/compress/config.go

@@ -0,0 +1,56 @@
+package compress
+
+import (
+	"github.com/gofiber/fiber/v2"
+)
+
+// Config defines the config for middleware.
+type Config struct {
+	// Next defines a function to skip this middleware when returned true.
+	//
+	// Optional. Default: nil
+	Next func(c *fiber.Ctx) bool
+
+	// Level determines the compression algorithm
+	//
+	// Optional. Default: LevelDefault
+	// LevelDisabled:         -1
+	// LevelDefault:          0
+	// LevelBestSpeed:        1
+	// LevelBestCompression:  2
+	Level Level
+}
+
+// Level is numeric representation of compression level
+type Level int
+
+// Represents compression level that will be used in the middleware
+const (
+	LevelDisabled        Level = -1
+	LevelDefault         Level = 0
+	LevelBestSpeed       Level = 1
+	LevelBestCompression Level = 2
+)
+
+// ConfigDefault is the default config
+var ConfigDefault = Config{
+	Next:  nil,
+	Level: LevelDefault,
+}
+
+// Helper function to set default values
+func configDefault(config ...Config) Config {
+	// Return default config if nothing provided
+	if len(config) < 1 {
+		return ConfigDefault
+	}
+
+	// Override default config
+	cfg := config[0]
+
+	// Set default values
+	if cfg.Level < LevelDisabled || cfg.Level > LevelBestCompression {
+		cfg.Level = ConfigDefault.Level
+	}
+	return cfg
+}

+ 33 - 0
vendor/github.com/gofiber/template/.gitignore

@@ -0,0 +1,33 @@
+# Binaries for programs and plugins
+*.exe
+*.exe~
+*.dll
+*.so
+*.dylib
+
+# Test binary, built with `go test -c`
+*.test
+*.tmp
+
+# Output of the go coverage tool, specifically when used with LiteIDE
+*.out
+
+# IDE files
+.vscode
+.DS_Store
+.idea
+
+# Misc
+*.fiber.gz
+*.fasthttp.gz
+*.pprof
+*.workspace
+
+# Dependencies
+/vendor/
+vendor/
+vendor
+/Godeps/
+
+# test files
+*/views/ShouldReload.*

+ 284 - 0
vendor/github.com/gofiber/template/.golangci.yml

@@ -0,0 +1,284 @@
+# Created based on v1.52.2
+# NOTE: Keep this in sync with the version in .github/workflows/lint_golangci-lint.yml
+
+run:
+  timeout: 5m
+  modules-download-mode: readonly
+  skip-dirs-use-default: false
+  skip-dirs:
+    - internal
+
+output:
+  sort-results: true
+
+linters-settings:
+  depguard:
+    include-go-root: true
+    packages:
+      - flag
+      - io/ioutil
+      - reflect
+      - unsafe
+    packages-with-error-message:
+      - flag: '`flag` package is only allowed in main.go'
+      - io/ioutil: '`io/ioutil` package is deprecated, use the `io` and `os` package instead'
+      - reflect: '`reflect` package is dangerous to use'
+      - unsafe: '`unsafe` package is dangerous to use'
+
+  errcheck:
+    check-type-assertions: true
+    check-blank: true
+    disable-default-exclusions: true
+
+  errchkjson:
+    report-no-exported: true
+
+  exhaustive:
+    check-generated: true
+    default-signifies-exhaustive: true
+
+  forbidigo:
+    forbid:
+      - ^(fmt\.Print(|f|ln)|print|println)$
+      # - 'http\.Default(Client|Transport)'
+      # - 'time\.Sleep'
+      # - 'panic'
+
+  gci:
+    sections:
+      - standard
+      - prefix(github.com/gofiber/fiber)
+      - default
+      - blank
+      - dot
+    custom-order: true
+
+  goconst:
+    numbers: true
+
+  gocritic:
+    enabled-tags:
+      - diagnostic
+      - style
+      - performance
+      - experimental
+      - opinionated
+    disabled-checks:
+      - hugeParam
+      - rangeValCopy
+
+  gofumpt:
+    module-path: github.com/gofiber/template
+    extra-rules: true
+
+  gosec:
+    config:
+      global:
+        audit: true
+
+  govet:
+    enable-all: true
+    disable:
+      - fieldalignment
+      - shadow
+
+  grouper:
+    import-require-single-import: true
+    import-require-grouping: true
+
+  misspell:
+    locale: US
+
+  nolintlint:
+    require-explanation: true
+    require-specific: true
+
+  nonamedreturns:
+    report-error-in-defer: true
+
+  predeclared:
+    q: true
+
+  promlinter:
+    strict: true
+
+  reassign:
+    patterns:
+      - '.*'
+
+  revive:
+    enable-all-rules: true
+    rules:
+      # Provided by gomnd linter
+      - name: add-constant
+        disabled: true
+      - name: argument-limit
+        disabled: true
+      # Provided by bidichk
+      - name: banned-characters
+        disabled: true
+      - name: cognitive-complexity
+        disabled: true
+      - name: comment-spacings
+        arguments:
+          - nolint
+          - msgp
+      - name: cyclomatic
+        disabled: true
+      - name: exported
+        disabled: true
+      - name: file-header
+        disabled: true
+      - name: function-result-limit
+        arguments: [3]
+      - name: function-length
+        disabled: true
+      - name: line-length-limit
+        disabled: true
+      - name: nested-structs
+        disabled: true
+      - name: max-public-structs
+        disabled: true
+      - name: modifies-parameter
+        disabled: true
+      - name: package-comments
+        disabled: true
+      - name: use-any
+        disabled: true # some tests still use go 1.17
+
+  stylecheck:
+    checks:
+      - all
+      - -ST1000
+      - -ST1020
+      - -ST1021
+      - -ST1022
+
+  tagliatelle:
+    case:
+      rules:
+        json: snake
+
+  tenv:
+    all: true
+
+  #unparam:
+  #  check-exported: true
+
+  wrapcheck:
+    ignorePackageGlobs:
+      - github.com/gofiber/fiber/*
+      - github.com/valyala/fasthttp
+
+issues:
+  exclude-use-default: false
+  exclude-rules:
+    - linters:
+      - goerr113
+      text: 'do not define dynamic errors, use wrapped static errors instead*'
+
+linters:
+  enable:
+    - asasalint
+    - asciicheck
+    - bidichk
+    - bodyclose
+    - containedctx
+    - contextcheck
+    # - cyclop
+    - deadcode
+    # - decorder
+    - depguard
+    - dogsled
+    # - dupl
+    - dupword
+    - durationcheck
+    - errcheck
+    - errchkjson
+    - errname
+    - errorlint
+    - execinquery
+    - exhaustive
+    # - exhaustivestruct
+    # - exhaustruct
+    - exportloopref
+    - forbidigo
+    - forcetypeassert
+    # - funlen
+    - gci
+    - ginkgolinter
+    - gocheckcompilerdirectives
+    - gochecknoglobals # Enabled
+    - gochecknoinits # Enabled
+    # - gocognit
+    - goconst
+    - gocritic
+    # - gocyclo
+    # - godot
+    # - godox
+    - goerr113
+    - gofmt
+    - gofumpt
+    # - goheader
+    # - goimports
+    # - golint
+    - gomnd # Enabled
+    - gomoddirectives
+    # - gomodguard
+    - goprintffuncname
+    - gosec
+    - gosimple
+    - govet
+    - grouper
+    # - ifshort
+    # - importas
+    - ineffassign
+    # - interfacebloat
+    # - interfacer
+    # - ireturn
+    # - lll
+    - loggercheck
+    # - maintidx
+    # - makezero
+    # - maligned
+    - misspell
+    - musttag
+    - nakedret
+    # - nestif
+    - nilerr
+    - nilnil
+    # - nlreturn
+    - noctx
+    - nolintlint
+    - nonamedreturns
+    - nosnakecase
+    - nosprintfhostport
+    - paralleltest
+    # - prealloc
+    - predeclared
+    - promlinter
+    - reassign
+    - revive
+    - rowserrcheck
+    - scopelint
+    - sqlclosecheck
+    - staticcheck
+    - structcheck
+    - stylecheck
+    - tagliatelle
+    - tenv
+    - testableexamples
+    # - testpackage
+    - thelper
+    - tparallel
+    - typecheck
+    - unconvert
+    - unparam
+    - unused
+    - usestdlibvars
+    - varcheck
+    # - varnamelen
+    - wastedassign
+    - whitespace
+    # - wrapcheck # disabled
+    # - wsl

+ 21 - 0
vendor/github.com/gofiber/template/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Fiber
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 250 - 0
vendor/github.com/gofiber/template/README.md

@@ -0,0 +1,250 @@
+<p align="center">
+  <a href="https://gofiber.io">
+      <picture>
+        <source height="125" media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/gofiber/template/master/.github/logo-dark.svg">
+        <img height="125" alt="Fiber" src="https://raw.githubusercontent.com/gofiber/template/master/.github/logo.svg">
+      </picture>
+  </a>
+  <br>
+
+  <a href="https://pkg.go.dev/github.com/gofiber/template/html?tab=doc">
+    <img src="https://img.shields.io/badge/%F0%9F%93%9A%20godoc-pkg-00ACD7.svg?color=00ACD7&style=flat">
+  </a>
+  <a href="https://goreportcard.com/report/github.com/gofiber/template">
+    <img src="https://img.shields.io/badge/%F0%9F%93%9D%20goreport-A%2B-75C46B">
+  </a>
+  <a href="https://gofiber.io/discord">
+    <img src="https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7">
+  </a>
+</p>
+
+This package provides universal methods to use multiple template engines with the [Fiber web framework](https://github.com/gofiber/fiber) using the new [Views](https://godoc.org/github.com/gofiber/fiber#Views) interface that is available from `> v1.11.1`. Special thanks to @bdtomlin & @arsmn for helping!
+
+9 template engines are supported:
+- [html](https://github.com/gofiber/template/tree/master/html) <a href="https://github.com/gofiber/template/actions?query=workflow%3A%22Tests+Html%22">
+  <img src="https://img.shields.io/github/actions/workflow/status/gofiber/template/test-html.yml?branch=master&label=%F0%9F%A7%AA%20&style=flat&color=75C46B">
+  </a>
+- [ace](https://github.com/gofiber/template/tree/master/ace) <a href="https://github.com/gofiber/template/actions?query=workflow%3A%22Tests+Ace%22">
+  <img src="https://img.shields.io/github/actions/workflow/status/gofiber/template/test-ace.yml?branch=master&label=%F0%9F%A7%AA%20&style=flat&color=75C46B"></a>
+- [amber](https://github.com/gofiber/template/tree/master/amber) <a href="https://github.com/gofiber/template/actions?query=workflow%3A%22Tests+Amber%22">
+  <img src="https://img.shields.io/github/actions/workflow/status/gofiber/template/test-amber.yml?branch=master&label=%F0%9F%A7%AA%20&style=flat&color=75C46B"></a>
+- [django](https://github.com/gofiber/template/tree/master/django) <a href="https://github.com/gofiber/template/actions?query=workflow%3A%22Tests+Django%22">
+  <img src="https://img.shields.io/github/actions/workflow/status/gofiber/template/test-django.yml?branch=master&label=%F0%9F%A7%AA%20&style=flat&color=75C46B"></a>
+- [handlebars](https://github.com/gofiber/template/tree/master/handlebars) <a href="https://github.com/gofiber/template/actions?query=workflow%3A%22Tests+Handlebars%22">
+  <img src="https://img.shields.io/github/actions/workflow/status/gofiber/template/test-handlebars.yml?branch=master&label=%F0%9F%A7%AA%20&style=flat&color=75C46B"></a>
+- [jet](https://github.com/gofiber/template/tree/master/jet) <a href="https://github.com/gofiber/template/actions?query=workflow%3A%22Tests+Jet%22">
+  <img src="https://img.shields.io/github/actions/workflow/status/gofiber/template/test-jet.yml?branch=master&label=%F0%9F%A7%AA%20&style=flat&color=75C46B"></a>
+- [mustache](https://github.com/gofiber/template/tree/master/mustache) <a href="https://github.com/gofiber/template/actions?query=workflow%3A%22Tests+Mustache%22">
+  <img src="https://img.shields.io/github/actions/workflow/status/gofiber/template/test-mustache.yml?branch=master&label=%F0%9F%A7%AA%20&style=flat&color=75C46B"></a>
+- [pug](https://github.com/gofiber/template/tree/master/pug) <a href="https://github.com/gofiber/template/actions?query=workflow%3A%22Tests+Pug%22">
+  <img src="https://img.shields.io/github/actions/workflow/status/gofiber/template/test-pug.yml?branch=master&label=%F0%9F%A7%AA%20&style=flat&color=75C46B"></a>
+- [slim](https://github.com/gofiber/template/tree/master/slim) <a href="https://github.com/gofiber/template/actions?query=workflow%3A%22Tests+Slim%22">
+  <img src="https://img.shields.io/github/actions/workflow/status/gofiber/template/test-slim.yml?branch=master&label=%F0%9F%A7%AA%20&style=flat&color=75C46B"></a>
+
+### Installation
+> Go version `1.17` or higher is required.
+
+```
+go get -u github.com/gofiber/fiber/v2
+go get -u github.com/gofiber/template/any_template_engine/vX
+```
+
+### Example
+```go
+package main
+
+import (
+	"log"
+
+	"github.com/gofiber/fiber/v2"
+
+	// To use a specific template engine, import as shown below:
+	// "github.com/gofiber/template/pug"
+	// "github.com/gofiber/template/mustache"
+	// etc..
+
+	// In this example we use the html template engine
+	"github.com/gofiber/template/html/v2"
+)
+
+func main() {
+	// Create a new engine by passing the template folder
+	// and template extension using <engine>.New(dir, ext string)
+	engine := html.New("./views", ".html")
+
+  	// We also support the http.FileSystem interface
+	// See examples below to load templates from embedded files
+	engine := html.NewFileSystem(http.Dir("./views"), ".html")
+
+	// Reload the templates on each render, good for development
+	engine.Reload(true) // Optional. Default: false
+
+	// Debug will print each template that is parsed, good for debugging
+	engine.Debug(true) // Optional. Default: false
+
+	// Layout defines the variable name that is used to yield templates within layouts
+	engine.Layout("embed") // Optional. Default: "embed"
+
+	// Delims sets the action delimiters to the specified strings
+	engine.Delims("{{", "}}") // Optional. Default: engine delimiters
+
+	// AddFunc adds a function to the template's global function map.
+	engine.AddFunc("greet", func(name string) string {
+		return "Hello, " + name + "!"
+	})
+
+	// After you created your engine, you can pass it to Fiber's Views Engine
+	app := fiber.New(fiber.Config{
+		Views: engine,
+	})
+
+	// To render a template, you can call the ctx.Render function
+	// Render(tmpl string, values interface{}, layout ...string)
+	app.Get("/", func(c *fiber.Ctx) error {
+		return c.Render("index", fiber.Map{
+			"Title": "Hello, World!",
+		})
+	})
+
+	// Render with layout example
+	app.Get("/layout", func(c *fiber.Ctx) error {
+		return c.Render("index", fiber.Map{
+			"Title": "Hello, World!",
+		}, "layouts/main")
+	})
+
+	log.Fatal(app.Listen(":3000"))
+}
+
+```
+
+### More Examples
+
+To view more specific examples, you could visit each engine folder to learn more
+- [html](https://github.com/gofiber/template/tree/master/html)
+- [ace](https://github.com/gofiber/template/tree/master/ace)
+- [amber](https://github.com/gofiber/template/tree/master/amber)
+- [django](https://github.com/gofiber/template/tree/master/django)
+- [handlebars](https://github.com/gofiber/template/tree/master/handlebars)
+- [jet](https://github.com/gofiber/template/tree/master/jet)
+- [mustache](https://github.com/gofiber/template/tree/master/mustache)
+- [pug](https://github.com/gofiber/template/tree/master/pug)
+- [slim](https://github.com/gofiber/template/tree/master/slim)
+
+
+### embedded Systems
+
+We support the `http.FileSystem` interface, so you can use different libraries to load the templates from embedded binaries.
+
+#### pkger
+Read documentation: https://github.com/markbates/pkger
+
+```go
+package main
+
+import (
+	"log"
+
+	"github.com/gofiber/fiber/v2"
+	"github.com/gofiber/template/html"
+
+	"github.com/markbates/pkger"
+)
+
+func main() {
+	engine := html.NewFileSystem(pkger.Dir("/views"), ".html")
+
+	app := fiber.New(fiber.Config{
+		Views: engine,
+	})
+
+	// run pkger && go build
+}
+```
+#### packr
+Read documentation: https://github.com/gobuffalo/packr
+
+```go
+package main
+
+import (
+	"log"
+
+	"github.com/gofiber/fiber/v2"
+	"github.com/gofiber/template/html"
+
+	"github.com/gobuffalo/packr/v2"
+)
+
+func main() {
+	engine := html.NewFileSystem(packr.New("Templates", "/views"), ".html")
+
+	app := fiber.New(fiber.Config{
+		Views: engine,
+	})
+
+	// run packr && go build
+}
+```
+#### go.rice
+Read documentation: https://github.com/GeertJohan/go.rice
+
+```go
+package main
+
+import (
+	"log"
+
+	"github.com/gofiber/fiber/v2"
+	"github.com/gofiber/template/html"
+
+	"github.com/GeertJohan/go.rice"
+)
+
+func main() {
+	engine := html.NewFileSystem(rice.MustFindBox("views").HTTPBox(), ".html")
+
+	app := fiber.New(fiber.Config{
+		Views: engine,
+	})
+
+	// run rice embed-go && go build
+}
+
+```
+#### fileb0x
+Read documentation: https://github.com/UnnoTed/fileb0x
+
+```go
+package main
+
+import (
+	"log"
+
+	"github.com/gofiber/fiber/v2"
+	"github.com/gofiber/template/html"
+	// your generated package
+	"github.com/<user>/<repo>/static"
+)
+
+func main() {
+	engine := html.NewFileSystem(static.HTTP, ".html")
+
+	app := fiber.New(fiber.Config{
+		Views: engine,
+	})
+
+	// Read the documentation on how to use fileb0x
+}
+```
+
+
+### Benchmarks
+
+#### Simple
+![](.github/data/Simple-TimeperOperation.png)
+
+#### Extended
+![](.github/data/Extended-TimeperOperation.png)
+
+Benchmarks were ran on Apple Macbook M1. Each engine was benchmarked 20 times and the results averaged into a single xlsx file. Mustache was excluded from the extended benchmark

+ 21 - 0
vendor/github.com/gofiber/template/html/v2/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Fiber
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 203 - 0
vendor/github.com/gofiber/template/html/v2/README.md

@@ -0,0 +1,203 @@
+---
+id: html
+title: HTML
+---
+
+![Release](https://img.shields.io/github/v/tag/gofiber/template?filter=django*)
+[![Discord](https://img.shields.io/discord/704680098577514527?style=flat&label=%F0%9F%92%AC%20discord&color=00ACD7)](https://gofiber.io/discord)
+![Test](https://github.com/gofiber/template/workflows/Tests/badge.svg)
+![Security](https://github.com/gofiber/template/workflows/Security/badge.svg)
+![Linter](https://github.com/gofiber/template/workflows/Linter/badge.svg)
+
+HTML is the official Go template engine [html/template](https://golang.org/pkg/html/template/), to see the original syntax documentation please [click here](TEMPLATES_CHEATSHEET.md)
+
+**Info:**
+
+All templates within the specified view directory are analyzed and compiled at the beginning to increase the performance when using them.
+Thus it should be noted that no `definition` with the same name should exist, otherwise they will overwrite each other.
+For templating the `{{embed}}` tag should be used
+
+### Basic Example
+
+_**./views/index.html**_
+
+```html
+{{template "partials/header" .}}
+
+<h1>{{.Title}}</h1>
+
+{{template "partials/footer" .}}
+```
+
+_**./views/partials/header.html**_
+
+```html
+<h2>Header</h2>
+```
+
+_**./views/partials/footer.html**_
+
+```html
+<h2>Footer</h2>
+```
+
+_**./views/layouts/main.html**_
+
+```html
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Main</title>
+  </head>
+
+  <body>
+    {{embed}}
+  </body>
+</html>
+```
+
+```go
+package main
+
+import (
+	"log"
+
+	"github.com/gofiber/fiber/v2"
+	"github.com/gofiber/template/html/v2"
+)
+
+func main() {
+	// Create a new engine
+	engine := html.New("./views", ".html")
+
+	// Or from an embedded system
+	// See github.com/gofiber/embed for examples
+	// engine := html.NewFileSystem(http.Dir("./views", ".html"))
+
+	// Pass the engine to the Views
+	app := fiber.New(fiber.Config{
+		Views: engine,
+	})
+
+	app.Get("/", func(c *fiber.Ctx) error {
+		// Render index
+		return c.Render("index", fiber.Map{
+			"Title": "Hello, World!",
+		})
+	})
+
+	app.Get("/layout", func(c *fiber.Ctx) error {
+		// Render index within layouts/main
+		return c.Render("index", fiber.Map{
+			"Title": "Hello, World!",
+		}, "layouts/main")
+	})
+
+	log.Fatal(app.Listen(":3000"))
+}
+
+```
+
+### Example with embed.FS
+
+```go
+package main
+
+import (
+    "log"
+    "net/http"
+    "embed"
+
+    "github.com/gofiber/fiber/v2"
+    "github.com/gofiber/template/html"
+)
+
+//go:embed views/*
+var viewsfs embed.FS
+
+func main() {
+    engine := html.NewFileSystem(http.FS(viewsfs), ".html")
+
+    // Pass the engine to the Views
+    app := fiber.New(fiber.Config{
+        Views: engine,
+    })
+
+
+    app.Get("/", func(c *fiber.Ctx) error {
+        // Render index - start with views directory
+        return c.Render("views/index", fiber.Map{
+            "Title": "Hello, World!",
+        })
+    })
+
+    log.Fatal(app.Listen(":3000"))
+}
+```
+
+and change the starting point to the views directory
+
+_**./views/index.html**_
+
+```html
+{{template "views/partials/header" .}}
+
+<h1>{{.Title}}</h1>
+
+{{template "views/partials/footer" .}}
+```
+
+### Example with innerHTML
+
+```go
+package main
+
+import (
+    "embed"
+    "html/template"
+    "log"
+    "net/http"
+
+    "github.com/gofiber/fiber/v2"
+    "github.com/gofiber/template/html"
+)
+
+//go:embed views/*
+var viewsfs embed.FS
+
+func main() {
+    engine := html.NewFileSystem(http.FS(viewsfs), ".html")
+    engine.AddFunc(
+        // add unescape function
+        "unescape", func(s string) template.HTML {
+            return template.HTML(s)
+        },
+    )
+
+    // Pass the engine to the Views
+    app := fiber.New(fiber.Config{Views: engine})
+
+    app.Get("/", func(c *fiber.Ctx) error {
+        // Render index
+        return c.Render("views/index", fiber.Map{
+            "Title": "Hello, <b>World</b>!",
+        })
+    })
+
+    log.Fatal(app.Listen(":3000"))
+}
+```
+
+and change the starting point to the views directory
+
+_**./views/index.html**_
+
+```html
+<p>{{ unescape .Title}}</p>
+```
+
+**html output**
+
+```html
+<p>Hello, <b>World</b>!</p>
+```

+ 582 - 0
vendor/github.com/gofiber/template/html/v2/TEMPLATES_CHEATSHEET.md

@@ -0,0 +1,582 @@
+# Golang Templates Cheatsheet
+
+The Go standard library provides a set of packages to generate output. The [text/template](https://archive.is/o/2HksZ/https://golang.org/pkg/text/template/) package implements templates for generating text output, while the [html/template](https://archive.is/o/2HksZ/https://golang.org/pkg/html/template/) package implements templates for generating HTML output that is safe against certain attacks. Both packages use the same interface but the following examples of the core features are directed towards HTML applications.
+
+---
+
+## Table of Contents
+
+- [Parsing and Creating Templates](#parsing-and-creating-templates)
+- [Executing Templates](#executing-templates)
+- [Template Encoding and HTML](#template-encoding-and-html)
+- [Template Variables](#template-variables)
+- [Template Actions](#template-actions)
+- [Template Functions](#template-functions)
+- [Template Comparison Functions](#template-comparison-functions)
+- [Nested Templates and Layouts](#nested-templates-and-layouts)
+- [Templates Calling Functions](#templates-calling-functions)
+
+---
+
+## Parsing and Creating Templates
+
+#### Naming Templates
+
+There is no defined file extension for Go templates. One of the most popular is `.tmpl` supported by vim-go and [referenced in the text/template godocs](https://archive.is/o/2HksZ/golang.org/pkg/text/template/%23example_Template_helpers). The extension `.gohtml` supports syntax highlighting in both Atom and GoSublime editors. Finally analysis of large Go codebases finds that `.tpl` is often used by developers. While the extension is not important it is still good to be consistent within a project for clarity.
+
+---
+
+#### Creating a Template
+
+`tpl, err := template.Parse(filename)` will get the template at filename and store it in tpl. tpl can then be executed to show the template.
+
+---
+
+#### Parsing Multiple Templates
+
+`template.ParseFiles(filenames)` takes a list of filenames and stores all templates. `template.ParseGlob(pattern)` will find all templates matching the pattern and store the templates.
+
+---
+
+## Executing Templates
+
+#### Execute a Single Template
+
+Once a template has been parsed there are two options to execute them. A single template `tpl` can be executed using `tpl.Execute(io.Writer, data)`. The content of tpl will be written to the io.Writer. Data is an interface passed to the template that will be useable in the template.
+
+---
+
+#### Executing a Named Template
+
+`tpl.ExecuteTemplate(io.Writer, name, data)` works the same as execute but allows for a string name of the template the user wants to execute.
+
+---
+
+## Template Encoding and HTML
+
+#### Contextual Encoding
+
+Go’s html/template package does encoding based on the context of the code. As a result, html/template encodes any characters that need encoding to be rendered correctly.
+
+For example the < and > in `"<h1>A header!</h1>"` will be encoded as `&lt;h1&gt;A header!&lt;/h1&gt;` .
+
+Type `template.HTML` can be used to skip encoding by telling Go the string is safe. `template.HTML("<h1>A Safe header</h1>")` will then be `<h1>A Safe header</h1>` . Using this type with user input is dangerous and leaves the application vulnerable.
+
+The go `html/template` package is aware of attributes within the template and will encode values differently based on the attribute.
+
+Go templates can also be used with javascript. Structs and maps will be expanded into JSON objects and quotes will be added to strings for use in function parameters and as variable values.
+
+```go
+    // Go
+    type Cat struct {
+    	Name string
+    	Age int
+    }
+
+    kitten := Cat{"Sam", 12}
+```
+
+```html
+// Template
+<script>
+  var cat = {{.kitten}}
+</script>
+```
+
+```js
+    // Javascript
+    var cat = {"Name":"Sam", "Age" 12}
+```
+
+---
+
+#### Safe Strings and HTML Comments
+
+The `html/template` package will remove any comments from a template by default. This can cause issues when comments are necessary such as detecting internet explorer.
+
+```html
+<!--[if IE]>
+  Place content here to target all Internet Explorer users.
+<![endif]-->
+```
+
+We can use the Custom Functions method (Globally) to create a function that returns html preserving comments. Define a function `htmlSafe` in the FuncMap of the template.
+
+```go
+    testTemplate, err = template.New("hello.gohtml").Funcs(template.FuncMap{
+    	"htmlSafe": func(html string) template.HTML {
+    		return template.HTML(html)
+        },
+    }).ParseFiles("hello.gohtml")
+```
+
+This function takes a string and produces the unaltered HTML code. This function can be used in a template like so to preserve the comments `<!--[if IE 6]>` and `<![endif]-->` :
+
+```go
+    {{htmlSafe "<!--[if IE 6]>" }}
+    <meta http-equiv="Content-Type" content="text/html; charset=Unicode">
+    {{ htmlSafe "<![endif]-->" }}
+```
+
+---
+
+## Template Variables
+
+#### The dot character (.)
+
+A template variable can be a boolean, string, character, integer, floating-point, imaginary, or complex constant in Go syntax. Data passed to the template can be accessed using dot `{{ . }}`.
+
+If the data is a complex type then it’s fields can be accessed using the dot with the field name `{{ .FieldName }}`.
+
+Dots can be chained together if the data contains multiple complex structures. `{{ .Struct.StructTwo.Field }}`
+
+---
+
+#### Variables in Templates
+
+Data passed to the template can be saved in a variable and used throughout the template. `{{$number := .}}` We use the `$number` to create a variable then initialize it with the value passed to the template. To use the variable we call it in the template with `{{$number}}`.
+
+```go
+    {{$number := .}}
+    <h1> It is day number {{$number}} of the month </h1>
+```
+
+```go
+    var tpl *template.Template
+
+    tpl = template.Must(template.ParseFiles("templateName"))
+
+    err := tpl.ExecuteTemplate(os.Stdout, "templateName", 23)
+```
+
+In this example we pass 23 to the template and stored in the `$number` variable which can be used anywhere in the template
+
+---
+
+## Template Actions
+
+#### If/Else Statements
+
+Go templates support if/else statements like many programming languages. We can use the if statement to check for values, if it doesn’t exist we can use an else value. The empty values are false, 0, any nil pointer or interface value, and any array, slice, map, or string of length zero.
+
+```html
+<h1>Hello, {{if .Name}} {{.Name}} {{else}} Anonymous {{end}}!</h1>
+```
+
+If .Name exists then `Hello, Name` will be printed (replaced with the name value) otherwise it will print `Hello, Anonymous`.
+
+Templates also provide the else if statment `{{else if .Name2 }}` which can be used to evaluate other options after an if.
+
+---
+
+#### Removing Whitespace
+
+Adding different values to a template can add various amounts of whitespace. We can either change our template to better handle it, by ignoring or minimizing effects, or we can use the minus sign `-` within out template.
+
+`<h1>Hello, {{if .Name}} {{.Name}} {{- else}} Anonymous {{- end}}!</h1>`
+
+Here we are telling the template to remove all spaces between the `Name` variable and whatever comes after it. We are doing the same with the end keyword. This allows us to have whitespace within the template for easier reading but remove it in production.
+
+---
+
+#### Range Blocks
+
+Go templates have a `range` keyword to iterate over all objects in a structure. Suppose we had the Go structures:
+
+```go
+    type Item struct {
+    	Name  string
+    	Price int
+    }
+
+    type ViewData struct {
+    	Name  string
+    	Items []Item
+    }
+```
+
+We have an Item, with a name and price, then a ViewData which is the structure sent to the template. Consider the template containing the following:
+
+```html
+{{range .Items}}
+<div class="item">
+  <h3 class="name">{{.Name}}</h3>
+  <span class="price">${{.Price}}</span>
+</div>
+{{end}}
+```
+
+For each Item in the range of Items (in the ViewData structure) get the Name and Price of that item and create html for each Item automatically. Within a range each Item becomes the `{{.}}` and the item properties therefore become `{{.Name}}` or `{{.Price}}` in this example.
+
+---
+
+## Template Functions
+
+The template package provides a list of predefined global functions. Below are some of the most used.
+
+---
+
+#### Indexing structures in Templates
+
+If the data passed to the template is a map, slice, or array it can be indexed from the template. We use `{{index x number}}` where index is the keyword, x is the data and number is a integer for the index value. If we had `{{index names 2}}` it is equivalent to `names[2]`. We can add more integers to index deeper into data. `{{index names 2 3 4}}` is equivalent to `names[2][3][4]`.
+
+```html
+<body>
+  <h1>{{index .FavNums 2 }}</h1>
+</body>
+```
+
+```go
+    type person struct {
+    	Name    string
+    	FavNums []int
+    }
+
+    func main() {
+
+    	tpl := template.Must(template.ParseGlob("*.gohtml"))
+    	tpl.Execute(os.Stdout, &person{"Curtis", []int{7, 11, 94}})
+    }
+```
+
+This code example passes a person structure and gets the 3rd favourite number from the FavNums slice.
+
+---
+
+#### The `and` Function
+
+The and function returns the boolean AND of its arguments by returning the first empty argument or the last argument. `and x y` behaves logically as `if x then y else x` . Consider the following go code
+
+```go
+    type User struct {
+      Admin bool
+    }
+
+    type ViewData struct {
+      *User
+    }
+```
+
+Pass a ViewData with a User that has Admin set true to the following template
+
+```go
+
+    {{if and .User .User.Admin}}
+      You are an admin user!
+    {{else}}
+      Access denied!
+    {{end}}
+```
+
+The result will be `You are an admin user!`. However if the ViewData did not include a \*User object or Admin was set as false then the result will be `Access denied!`.
+
+---
+
+#### The `or` Function
+
+The or function operates similarly to the and function however will stop at the first true. `or x y` is equivalent to `if x then x else y` so y will never be evaluated if x is not empty.
+
+---
+
+#### The `not` Function
+
+The not function returns the boolean negation of the argument.
+
+```go
+    {{ if not .Authenticated}}
+      Access Denied!
+    {{ end }}
+```
+
+---
+
+## Template Comparison Functions
+
+#### Comparisons
+
+The `html/template` package provides a variety of functions to do comparisons between operators. The operators may only be basic types or named basic types such as `type Temp float32` Remember that template functions take the form `{{ function arg1 arg2 }}`.
+
+- `eq` Returns the result of arg1 == arg2
+- `ne` Returns the result of arg1 != arg2
+- `lt` Returns the result of arg1 < arg2
+- `le` Returns the result of arg1 <= arg2
+- `gt` Returns the result of arg1 > arg2
+- `ge` Returns the result of arg1 >= arg2
+
+Of special note `eq` can be used with two or more arguments by comparing all arguments to the first. `{{ eq arg1 arg2 arg3 arg4}}` will result in the following logical expression:
+
+`arg1==arg2 || arg1==arg3 || arg1==arg4`
+
+---
+
+## Nested Templates and Layouts
+
+#### Nesting Templates
+
+Nested templates can be used for parts of code frequently used across templates, a footer or header for example. Rather than updating each template separately we can use a nested template that all other templates can use. You can define a template as follows:
+
+```go
+    {{define "footer"}}
+    <footer>
+    	<p>Here is the footer</p>
+    </footer>
+    {{end}}
+```
+
+A template named “footer” is defined which can be used in other templates like so to add the footer template content into the other template:
+
+```go
+    {{template "footer"}}
+```
+
+---
+
+#### Passing Variables between Templates
+
+The `template` action used to include nested templates also allows a second parameter to pass data to the nested template.
+
+```html
+// Define a nested template called header 
+{{define "header"}}
+<h1>{{.}}</h1>
+{{end}}
+
+// Call template and pass a name parameter 
+{{range .Items}}
+<div class="item">
+  {{template "header" .Name}}
+  <span class="price">${{.Price}}</span>
+</div>
+{{end}}
+```
+
+We use the same range to loop through Items as before but we pass the name to the header template each time in this simple example.
+
+---
+
+#### Creating Layouts
+
+Glob patterns specify sets of filenames with wildcard characters. The `template.ParseGlob(pattern string)` function will parse all templates that match the string pattern. `template.ParseFiles(files...)` can also be used with a list of file names.
+
+The templates are named by default based on the base names of the argument files. This mean `views/layouts/hello.gohtml` will have the name `hello.gohtml` . If the template has a ``{{define “templateName”}}` within it then that name will be usable.
+
+A specific template can be executed using `t.ExecuteTemplate(w, "templateName", nil)` . `t` is an object of type Template, `w` is type io.Writer such as an `http.ResponseWriter`, Then there is the name of the template to execute, and finally passing any data to the template, in this case a nil value.
+
+Example main.go file
+
+```go
+    // Omitted imports & package
+
+    var LayoutDir string = "views/layouts"
+    var bootstrap *template.Template
+
+    func main() {
+    	var err error
+    	bootstrap, err = template.ParseGlob(LayoutDir + "/*.gohtml")
+    	if err != nil {
+    		panic(err)
+    	}
+
+    	http.HandleFunc("/", handler)
+    	http.ListenAndServe(":8080", nil)
+    }
+
+    func handler(w http.ResponseWriter, r *http.Request) {
+    	bootstrap.ExecuteTemplate(w, "bootstrap", nil)
+    }
+```
+
+All `.gohtml` files are parsed in main. When route `/` is reached the template defined as `bootstrap` is executed using the handler function.
+
+Example views/layouts/bootstrap.gohtml file
+
+```html
+    {{define "bootstrap"}}
+    <!DOCTYPE html>
+    <html lang="en">
+      <head>
+        <title>Go Templates</title>
+        <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
+    	rel="stylesheet">
+      </head>
+      <body>
+        <div class="container-fluid">
+          <h1>Filler header</h1>
+    	  <p>Filler paragraph</p>
+        </div>
+        <!-- jquery & Bootstrap JS -->
+        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"
+        </script>
+        <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">
+        </script>
+      </body>
+    </html>
+    {{end}}
+```
+
+## Templates Calling Functions
+
+#### Function Variables (calling struct methods)
+
+We can use templates to call the methods of objects in the template to return data. Consider the User struct with the following method.
+
+```go
+    type User struct {
+      ID    int
+      Email string
+    }
+
+    func (u User) HasPermission(feature string) bool {
+      if feature == "feature-a" {
+        return true
+      } else {
+        return false
+      }
+    }
+```
+
+When a type User has been passed to the template we can then call this method from the template.
+
+```html
+{{if .User.HasPermission "feature-a"}}
+<div class="feature">
+  <h3>Feature A</h3>
+  <p>Some other stuff here...</p>
+</div>
+{{else}}
+<div class="feature disabled">
+  <h3>Feature A</h3>
+  <p>To enable Feature A please upgrade your plan</p>
+</div>
+{{end}}
+```
+
+The template checks if the User HasPermission for the feature and renders depending on the result.
+
+---
+
+#### Function Variables (call)
+
+If the Method HasPermission has to change at times then the Function Variables (Methods) implementation may not fit the design. Instead a `HasPermission func(string) bool` attribute can be added on the `User` type. This can then have a function assigned to it at creation.
+
+```go
+    // Structs
+    type ViewData struct {
+      User User
+    }
+
+    type User struct {
+      ID            int
+      Email         string
+      HasPermission func(string) bool
+    }
+
+    // Example of creating a ViewData
+    vd := ViewData{
+    		User: User{
+    			ID:    1,
+    			Email: "curtis.vermeeren@gmail.com",
+    			// Create the HasPermission function
+    			HasPermission: func(feature string) bool {
+    				if feature == "feature-b" {
+    					return true
+    				}
+    				return false
+    			},
+    		},
+    	}
+
+    // Executing the ViewData with the template
+    err := testTemplate.Execute(w, vd)
+```
+
+We need to tell the Go template that we want to call this function so we must change the template from the Function Variables (Methods) implementation to do this. We use the `call` keyword supplied by the go `html/template` package. Changing the previous template to use `call` results in:
+
+```html
+{{if (call .User.HasPermission "feature-b")}}
+<div class="feature">
+  <h3>Feature B</h3>
+  <p>Some other stuff here...</p>
+</div>
+{{else}}
+<div class="feature disabled">
+  <h3>Feature B</h3>
+  <p>To enable Feature B please upgrade your plan</p>
+</div>
+{{end}}
+```
+
+---
+
+#### Custom Functions
+
+Another way to call functions is to create custom functions with `template.FuncMap` . This method creates global methods that can be used throughout the entire application. FuncMap has type `map[string]interface{}` mapping a string, the function name, to a function. The mapped functions must have either a single return value, or two return values where the second has type error.
+
+```go
+    // Creating a template with function hasPermission
+    testTemplate, err = template.New("hello.gohtml").Funcs(template.FuncMap{
+        "hasPermission": func(user User, feature string) bool {
+          if user.ID == 1 && feature == "feature-a" {
+            return true
+          }
+          return false
+        },
+      }).ParseFiles("hello.gohtml")
+```
+
+Here the function to check if a user has permission for a feature is mapped to the string `"hasPermission"` and stored in the FuncMap. Note that the custom functions must be created before calling `ParseFiles()`
+
+The function could be executed in the template as follows:
+
+```go
+    {{ if hasPermission .User "feature-a" }}
+```
+
+The `.User` and string `"feature-a"` are both passed to `hasPermission` as arguments.
+
+---
+
+#### Custom Functions (Globally)
+
+The previous two methods of custom functions rely on `.User` being passed to the template. This works in many cases but in a large application passing too many objects to a template can become difficult to maintain across many templates. We can change the implementation of the custom function to work without the .User being passed.
+
+Using a similar feature example as the other 2 sections first you would have to create a default `hasPermission` function and define it in the template’s function map.
+
+```go
+      testTemplate, err = template.New("hello.gohtml").Funcs(template.FuncMap{
+        "hasPermission": func(feature string) bool {
+          return false
+        },
+      }).ParseFiles("hello.gohtml")
+```
+
+This function could be placed in `main()` or somewhere that ensures the default `hasPermission` is created in the `hello.gohtml` function map. The default function just returns false but it defines the function and implementation that doesn’t require `User` .
+
+Next a closure could be used to redefine the `hasPermission` function. It would use the `User` data available when it is created in a handler rather than having `User` data passed to it. Within the handler for the template you can redefine any functions to use the information available.
+
+```go
+    func handler(w http.ResponseWriter, r *http.Request) {
+    	w.Header().Set("Content-Type", "text/html")
+
+    	user := User{
+    		ID:    1,
+    		Email: "Curtis.vermeeren@gmail.com",
+    	}
+    	vd := ViewData{}
+    	err := testTemplate.Funcs(template.FuncMap{
+    		"hasPermission": func(feature string) bool {
+    			if user.ID == 1 && feature == "feature-a" {
+    				return true
+    			}
+    			return false
+    		},
+    	}).Execute(w, vd)
+    	if err != nil {
+    		http.Error(w, err.Error(), http.StatusInternalServerError)
+    	}
+    }
+```
+
+In this handler a `User` is created with ID and Email, Then a `ViewData` is created without passing the user to it. The `hasPermission` function is redefined using `user.ID` which is available when the function is created. `{{if hasPermission "feature-a"}}` can be used in a template without having to pass a `User` to the template as the User object in the handler is used instead.
+
+---

+ 156 - 0
vendor/github.com/gofiber/template/html/v2/html.go

@@ -0,0 +1,156 @@
+package html
+
+import (
+	"fmt"
+	"html/template"
+	"io"
+	"log"
+	"net/http"
+	"os"
+	"path/filepath"
+	"strings"
+
+	core "github.com/gofiber/template"
+	"github.com/gofiber/utils"
+)
+
+// Engine struct
+type Engine struct {
+	core.Engine
+	// templates
+	Templates *template.Template
+}
+
+// New returns an HTML render engine for Fiber
+func New(directory, extension string) *Engine {
+	engine := &Engine{
+		Engine: core.Engine{
+			Left:       "{{",
+			Right:      "}}",
+			Directory:  directory,
+			Extension:  extension,
+			LayoutName: "embed",
+			Funcmap:    make(map[string]interface{}),
+		},
+	}
+	engine.AddFunc(engine.LayoutName, func() error {
+		return fmt.Errorf("layoutName called unexpectedly")
+	})
+	return engine
+}
+
+// NewFileSystem returns an HTML render engine for Fiber with file system
+func NewFileSystem(fs http.FileSystem, extension string) *Engine {
+	engine := &Engine{
+		Engine: core.Engine{
+			Left:       "{{",
+			Right:      "}}",
+			Directory:  "/",
+			FileSystem: fs,
+			Extension:  extension,
+			LayoutName: "embed",
+			Funcmap:    make(map[string]interface{}),
+		},
+	}
+	engine.AddFunc(engine.LayoutName, func() error {
+		return fmt.Errorf("layoutName called unexpectedly")
+	})
+	return engine
+}
+
+// Load parses the templates to the engine.
+func (e *Engine) Load() error {
+	if e.Loaded {
+		return nil
+	}
+	// race safe
+	e.Mutex.Lock()
+	defer e.Mutex.Unlock()
+	e.Templates = template.New(e.Directory)
+
+	// Set template settings
+	e.Templates.Delims(e.Left, e.Right)
+	e.Templates.Funcs(e.Funcmap)
+
+	walkFn := func(path string, info os.FileInfo, err error) error {
+		// Return error if exist
+		if err != nil {
+			return err
+		}
+		// Skip file if it's a directory or has no file info
+		if info == nil || info.IsDir() {
+			return nil
+		}
+		// Skip file if it does not equal the given template Extension
+		if len(e.Extension) >= len(path) || path[len(path)-len(e.Extension):] != e.Extension {
+			return nil
+		}
+		// Get the relative file path
+		// ./views/html/index.tmpl -> index.tmpl
+		rel, err := filepath.Rel(e.Directory, path)
+		if err != nil {
+			return err
+		}
+		// Reverse slashes '\' -> '/' and
+		// partials\footer.tmpl -> partials/footer.tmpl
+		name := filepath.ToSlash(rel)
+		// Remove ext from name 'index.tmpl' -> 'index'
+		name = strings.TrimSuffix(name, e.Extension)
+		// name = strings.Replace(name, e.Extension, "", -1)
+		// Read the file
+		// #gosec G304
+		buf, err := utils.ReadFile(path, e.FileSystem)
+		if err != nil {
+			return err
+		}
+		// Create new template associated with the current one
+		// This enable use to invoke other templates {{ template .. }}
+		_, err = e.Templates.New(name).Parse(string(buf))
+		if err != nil {
+			return err
+		}
+		// Debugging
+		if e.Verbose {
+			log.Printf("views: parsed template: %s\n", name)
+		}
+		return err
+	}
+	// notify engine that we parsed all templates
+	e.Loaded = true
+	if e.FileSystem != nil {
+		return utils.Walk(e.FileSystem, e.Directory, walkFn)
+	}
+	return filepath.Walk(e.Directory, walkFn)
+}
+
+// Render will execute the template name along with the given values.
+func (e *Engine) Render(out io.Writer, name string, binding interface{}, layout ...string) error {
+	if !e.Loaded || e.ShouldReload {
+		if e.ShouldReload {
+			e.Loaded = false
+		}
+		if err := e.Load(); err != nil {
+			return err
+		}
+	}
+
+	tmpl := e.Templates.Lookup(name)
+	if tmpl == nil {
+		return fmt.Errorf("render: template %s does not exist", name)
+	}
+	if len(layout) > 0 && layout[0] != "" {
+		lay := e.Templates.Lookup(layout[0])
+		if lay == nil {
+			return fmt.Errorf("render: LayoutName %s does not exist", layout[0])
+		}
+		e.Mutex.Lock()
+		defer e.Mutex.Unlock()
+		lay.Funcs(map[string]interface{}{
+			e.LayoutName: func() error {
+				return tmpl.Execute(out, binding)
+			},
+		})
+		return lay.Execute(out, binding)
+	}
+	return tmpl.Execute(out, binding)
+}

+ 104 - 0
vendor/github.com/gofiber/template/template.go

@@ -0,0 +1,104 @@
+package template
+
+import (
+	"io"
+	"net/http"
+	"sync"
+)
+
+// IEngine interface, to be implemented for any templating engine added to the repository
+type IEngine interface {
+	IEngineCore
+	Load() error
+	Render(out io.Writer, template string, binding interface{}, layout ...string) error
+}
+
+// IEngineCore interface
+type IEngineCore interface {
+	AddFunc(name string, fn interface{}) IEngineCore
+	AddFuncMap(m map[string]interface{}) IEngineCore
+	Debug(enabled bool) IEngineCore
+	Delims(left, right string) IEngineCore
+	FuncMap() map[string]interface{}
+	Layout(key string) IEngineCore
+	Reload(enabled bool) IEngineCore
+}
+
+// Engine engine struct
+type Engine struct {
+	IEngineCore
+	// delimiters
+	Left  string
+	Right string
+	// views folder
+	Directory string
+	// http.FileSystem supports embedded files
+	FileSystem http.FileSystem
+	// views extension
+	Extension string
+	// layout variable name that incapsulates the template
+	LayoutName string
+	// determines if the engine parsed all templates
+	Loaded bool
+	// reload on each render
+	ShouldReload bool
+	// debug prints the parsed templates
+	Verbose bool
+	// lock for funcmap and templates
+	Mutex sync.RWMutex
+	// template funcmap
+	Funcmap map[string]interface{}
+}
+
+// AddFunc adds the function to the template's function map.
+// It is legal to overwrite elements of the default actions
+func (e *Engine) AddFunc(name string, fn interface{}) *Engine {
+	e.Mutex.Lock()
+	e.Funcmap[name] = fn
+	e.Mutex.Unlock()
+	return e
+}
+
+// AddFuncMap adds the functions from a map to the template's function map.
+// It is legal to overwrite elements of the default actions
+func (e *Engine) AddFuncMap(m map[string]interface{}) *Engine {
+	e.Mutex.Lock()
+	for name, fn := range m {
+		e.Funcmap[name] = fn
+	}
+	e.Mutex.Unlock()
+	return e
+}
+
+// Debug will print the parsed templates when Load is triggered.
+func (e *Engine) Debug(enabled bool) *Engine {
+	e.Verbose = enabled
+	return e
+}
+
+// Delims sets the action delimiters to the specified strings, to be used in
+// templates. An empty delimiter stands for the
+// corresponding default: "{{" and "}}".
+func (e *Engine) Delims(left, right string) *Engine {
+	e.Left, e.Right = left, right
+	return e
+}
+
+// FuncMap returns the template's function map.
+func (e *Engine) FuncMap() map[string]interface{} {
+	return e.Funcmap
+}
+
+// Layout defines the variable name that will incapsulate the template
+func (e *Engine) Layout(key string) *Engine {
+	e.LayoutName = key
+	return e
+}
+
+// Reload if set to true the templates are reloading on each render,
+// use it when you're in development and you don't want to restart
+// the application when you edit a template file.
+func (e *Engine) Reload(enabled bool) *Engine {
+	e.ShouldReload = enabled
+	return e
+}

+ 21 - 0
vendor/github.com/gofiber/utils/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 Fiber
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 87 - 0
vendor/github.com/gofiber/utils/README.md

@@ -0,0 +1,87 @@
+A collection of common functions but with better performance, less allocations and no dependencies created for [Fiber](https://github.com/gofiber/fiber).
+
+```go
+// go test -benchmem -run=^$ -bench=Benchmark_ -count=2
+
+Benchmark_ToLowerBytes/fiber-16                 42847654                25.7 ns/op             0 B/op          0 allocs/op
+Benchmark_ToLowerBytes/fiber-16                 46143196                25.7 ns/op             0 B/op          0 allocs/op
+Benchmark_ToLowerBytes/default-16               17387322                67.4 ns/op            48 B/op          1 allocs/op
+Benchmark_ToLowerBytes/default-16               17906491                67.4 ns/op            48 B/op          1 allocs/op
+
+Benchmark_ToUpperBytes/fiber-16                 46143729                25.7 ns/op             0 B/op          0 allocs/op
+Benchmark_ToUpperBytes/fiber-16                 47989250                25.6 ns/op             0 B/op          0 allocs/op
+Benchmark_ToUpperBytes/default-16               15580854                76.7 ns/op            48 B/op          1 allocs/op
+Benchmark_ToUpperBytes/default-16               15381202                76.9 ns/op            48 B/op          1 allocs/op
+
+Benchmark_TrimRightBytes/fiber-16               70572459                16.3 ns/op             8 B/op          1 allocs/op
+Benchmark_TrimRightBytes/fiber-16               74983597                16.3 ns/op             8 B/op          1 allocs/op
+Benchmark_TrimRightBytes/default-16             16212578                74.1 ns/op            40 B/op          2 allocs/op
+Benchmark_TrimRightBytes/default-16             16434686                74.1 ns/op            40 B/op          2 allocs/op
+
+Benchmark_TrimLeftBytes/fiber-16                74983128                16.3 ns/op             8 B/op          1 allocs/op
+Benchmark_TrimLeftBytes/fiber-16                74985002                16.3 ns/op             8 B/op          1 allocs/op
+Benchmark_TrimLeftBytes/default-16              21047868                56.5 ns/op            40 B/op          2 allocs/op
+Benchmark_TrimLeftBytes/default-16              21048015                56.5 ns/op            40 B/op          2 allocs/op
+
+Benchmark_TrimBytes/fiber-16                    54533307                21.9 ns/op            16 B/op          1 allocs/op
+Benchmark_TrimBytes/fiber-16                    54532812                21.9 ns/op            16 B/op          1 allocs/op
+Benchmark_TrimBytes/default-16                  14282517                84.6 ns/op            48 B/op          2 allocs/op
+Benchmark_TrimBytes/default-16                  14114508                84.7 ns/op            48 B/op          2 allocs/op
+
+Benchmark_EqualFolds/fiber-16                   36355153                32.6 ns/op             0 B/op          0 allocs/op
+Benchmark_EqualFolds/fiber-16                   36355593                32.6 ns/op             0 B/op          0 allocs/op
+Benchmark_EqualFolds/default-16                 15186220                78.1 ns/op             0 B/op          0 allocs/op
+Benchmark_EqualFolds/default-16                 15186412                78.3 ns/op             0 B/op          0 allocs/op
+
+Benchmark_UUID/fiber-16                         23994625                49.8 ns/op            48 B/op          1 allocs/op
+Benchmark_UUID/fiber-16                         23994768                50.1 ns/op            48 B/op          1 allocs/op
+Benchmark_UUID/default-16                        3233772                 371 ns/op           208 B/op          6 allocs/op
+Benchmark_UUID/default-16                        3251295                 370 ns/op           208 B/op          6 allocs/op
+
+Benchmark_GetString/unsafe-16                 1000000000               0.709 ns/op             0 B/op          0 allocs/op
+Benchmark_GetString/unsafe-16                 1000000000               0.713 ns/op             0 B/op          0 allocs/op
+Benchmark_GetString/default-16                  59986202                19.0 ns/op            16 B/op          1 allocs/op
+Benchmark_GetString/default-16                  63142939                19.0 ns/op            16 B/op          1 allocs/op
+
+Benchmark_GetBytes/unsafe-16                   508360195                2.36 ns/op             0 B/op          0 allocs/op
+Benchmark_GetBytes/unsafe-16                   508359979                2.35 ns/op             0 B/op          0 allocs/op
+Benchmark_GetBytes/default-16                   46143019                25.7 ns/op            16 B/op          1 allocs/op
+Benchmark_GetBytes/default-16                   44434734                25.6 ns/op            16 B/op          1 allocs/op
+
+Benchmark_GetMIME/fiber-16                      21423750                56.3 ns/op             0 B/op          0 allocs/op
+Benchmark_GetMIME/fiber-16                      21423559                55.4 ns/op             0 B/op          0 allocs/op
+Benchmark_GetMIME/default-16                     6735282                 173 ns/op             0 B/op          0 allocs/op
+Benchmark_GetMIME/default-16                     6895002                 172 ns/op             0 B/op          0 allocs/op
+
+Benchmark_StatusMessage/fiber-16              1000000000               0.766 ns/op             0 B/op          0 allocs/op
+Benchmark_StatusMessage/fiber-16              1000000000               0.767 ns/op             0 B/op          0 allocs/op
+Benchmark_StatusMessage/default-16             159538528                7.50 ns/op             0 B/op          0 allocs/op
+Benchmark_StatusMessage/default-16             159750830                7.51 ns/op             0 B/op          0 allocs/op
+
+Benchmark_ToUpper/fiber-16                      22217408                53.3 ns/op            48 B/op          1 allocs/op
+Benchmark_ToUpper/fiber-16                      22636554                53.2 ns/op            48 B/op          1 allocs/op
+Benchmark_ToUpper/default-16                    11108600                 108 ns/op            48 B/op          1 allocs/op
+Benchmark_ToUpper/default-16                    11108580                 108 ns/op            48 B/op          1 allocs/op
+
+Benchmark_ToLower/fiber-16                      23994720                49.8 ns/op            48 B/op          1 allocs/op
+Benchmark_ToLower/fiber-16                      23994768                50.1 ns/op            48 B/op          1 allocs/op
+Benchmark_ToLower/default-16                    10808376                 110 ns/op            48 B/op          1 allocs/op
+Benchmark_ToLower/default-16                    10617034                 110 ns/op            48 B/op          1 allocs/op
+
+Benchmark_TrimRight/fiber-16                   413699521                2.94 ns/op             0 B/op          0 allocs/op
+Benchmark_TrimRight/fiber-16                   415131687                2.91 ns/op             0 B/op          0 allocs/op
+Benchmark_TrimRight/default-16                  23994577                49.1 ns/op            32 B/op          1 allocs/op
+Benchmark_TrimRight/default-16                  24484249                49.4 ns/op            32 B/op          1 allocs/op
+
+Benchmark_TrimLeft/fiber-16                    379661170                3.13 ns/op             0 B/op          0 allocs/op
+Benchmark_TrimLeft/fiber-16                    382079941                3.16 ns/op             0 B/op          0 allocs/op
+Benchmark_TrimLeft/default-16                   27900877                41.9 ns/op            32 B/op          1 allocs/op
+Benchmark_TrimLeft/default-16                   28564898                42.0 ns/op            32 B/op          1 allocs/op
+
+Benchmark_Trim/fiber-16                        236632856                 4.96 ns/op            0 B/op          0 allocs/op
+Benchmark_Trim/fiber-16                        237570085                 4.93 ns/op            0 B/op          0 allocs/op
+Benchmark_Trim/default-16                       18457221                 66.0 ns/op           32 B/op          1 allocs/op
+Benchmark_Trim/default-16                       18177328                 65.9 ns/op           32 B/op          1 allocs/op
+Benchmark_Trim/default.trimspace-16            188933770                 6.33 ns/op            0 B/op          0 allocs/op
+Benchmark_Trim/default.trimspace-16            184007649                 6.42 ns/op            0 B/op          0 allocs/op
+```

+ 62 - 0
vendor/github.com/gofiber/utils/assertions.go

@@ -0,0 +1,62 @@
+// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
+// 🤖 Github Repository: https://github.com/gofiber/fiber
+// 📌 API Documentation: https://docs.gofiber.io
+
+package utils
+
+import (
+	"bytes"
+	"fmt"
+	"log"
+	"path/filepath"
+	"reflect"
+	"runtime"
+	"testing"
+	"text/tabwriter"
+)
+
+// AssertEqual checks if values are equal
+func AssertEqual(t testing.TB, expected interface{}, actual interface{}, description ...string) {
+	if reflect.DeepEqual(expected, actual) {
+		return
+	}
+	var aType = "<nil>"
+	var bType = "<nil>"
+	if reflect.ValueOf(expected).IsValid() {
+		aType = reflect.TypeOf(expected).Name()
+	}
+	if reflect.ValueOf(actual).IsValid() {
+		bType = reflect.TypeOf(actual).Name()
+	}
+
+	testName := "AssertEqual"
+	if t != nil {
+		testName = t.Name()
+	}
+
+	_, file, line, _ := runtime.Caller(1)
+
+	var buf bytes.Buffer
+	w := tabwriter.NewWriter(&buf, 0, 0, 5, ' ', 0)
+	fmt.Fprintf(w, "\nTest:\t%s", testName)
+	fmt.Fprintf(w, "\nTrace:\t%s:%d", filepath.Base(file), line)
+	fmt.Fprintf(w, "\nError:\tNot equal")
+	fmt.Fprintf(w, "\nExpect:\t%v\t[%s]", expected, aType)
+	fmt.Fprintf(w, "\nResult:\t%v\t[%s]", actual, bType)
+
+	if len(description) > 0 {
+		fmt.Fprintf(w, "\nDescription:\t%s", description[0])
+	}
+
+	result := ""
+	if err := w.Flush(); err != nil {
+		result = err.Error()
+	} else {
+		result = buf.String()
+	}
+	if t != nil {
+		t.Fatal(result)
+	} else {
+		log.Fatal(result)
+	}
+}

+ 78 - 0
vendor/github.com/gofiber/utils/bytes.go

@@ -0,0 +1,78 @@
+// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
+// 🤖 Github Repository: https://github.com/gofiber/fiber
+// 📌 API Documentation: https://docs.gofiber.io
+
+package utils
+
+// ToLowerBytes is the equivalent of bytes.ToLower
+func ToLowerBytes(b []byte) []byte {
+	for i := 0; i < len(b); i++ {
+		b[i] = toLowerTable[b[i]]
+	}
+	return b
+}
+
+// ToUpperBytes is the equivalent of bytes.ToUpper
+func ToUpperBytes(b []byte) []byte {
+	for i := 0; i < len(b); i++ {
+		b[i] = toUpperTable[b[i]]
+	}
+	return b
+}
+
+// TrimRightBytes is the equivalent of bytes.TrimRight
+func TrimRightBytes(b []byte, cutset byte) []byte {
+	lenStr := len(b)
+	for lenStr > 0 && b[lenStr-1] == cutset {
+		lenStr--
+	}
+	return b[:lenStr]
+}
+
+// TrimLeftBytes is the equivalent of bytes.TrimLeft
+func TrimLeftBytes(b []byte, cutset byte) []byte {
+	lenStr, start := len(b), 0
+	for start < lenStr && b[start] == cutset {
+		start++
+	}
+	return b[start:]
+}
+
+// TrimBytes is the equivalent of bytes.Trim
+func TrimBytes(b []byte, cutset byte) []byte {
+	i, j := 0, len(b)-1
+	for ; i < j; i++ {
+		if b[i] != cutset {
+			break
+		}
+	}
+	for ; i < j; j-- {
+		if b[j] != cutset {
+			break
+		}
+	}
+
+	return b[i : j+1]
+}
+
+// EqualFold the equivalent of bytes.EqualFold
+func EqualsFold(b, s []byte) (equals bool) {
+	n := len(b)
+	equals = n == len(s)
+	if equals {
+		for i := 0; i < n; i++ {
+			if equals = b[i]|0x20 == s[i]|0x20; !equals {
+				break
+			}
+		}
+	}
+	return
+}
+
+// DefaultBytes returns the provided fallback value if []byte is empty
+func DefaultBytes(value []byte, defaultValue []byte) []byte {
+	if len(value) <= 0 {
+		return defaultValue
+	}
+	return value
+}

+ 83 - 0
vendor/github.com/gofiber/utils/common.go

@@ -0,0 +1,83 @@
+// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
+// 🤖 Github Repository: https://github.com/gofiber/fiber
+// 📌 API Documentation: https://docs.gofiber.io
+
+package utils
+
+import (
+	"crypto/rand"
+	"encoding/binary"
+	"encoding/hex"
+	"os"
+	"reflect"
+	"runtime"
+	"sync"
+	"sync/atomic"
+)
+
+const toLowerTable = "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@abcdefghijklmnopqrstuvwxyz[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u007f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+const toUpperTable = "\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\u007f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
+
+// Copyright © 2014, Roger Peppe
+// github.com/rogpeppe/fastuuid
+// All rights reserved.
+
+var uuidSeed [24]byte
+var uuidCounter uint64
+var uuidSetup sync.Once
+
+// UUID generates an universally unique identifier (UUID)
+func UUID() string {
+	// Setup seed & counter once
+	uuidSetup.Do(func() {
+		if _, err := rand.Read(uuidSeed[:]); err != nil {
+			return
+		}
+		uuidCounter = binary.LittleEndian.Uint64(uuidSeed[:8])
+	})
+	if atomic.LoadUint64(&uuidCounter) <= 0 {
+		return "00000000-0000-0000-0000-000000000000"
+	}
+	// first 8 bytes differ, taking a slice of the first 16 bytes
+	x := atomic.AddUint64(&uuidCounter, 1)
+	uuid := uuidSeed
+	binary.LittleEndian.PutUint64(uuid[:8], x)
+	uuid[6], uuid[9] = uuid[9], uuid[6]
+
+	// RFC4122 v4
+	uuid[6] = (uuid[6] & 0x0f) | 0x40
+	uuid[8] = uuid[8]&0x3f | 0x80
+
+	// create UUID representation of the first 128 bits
+	b := make([]byte, 36)
+	hex.Encode(b[0:8], uuid[0:4])
+	b[8] = '-'
+	hex.Encode(b[9:13], uuid[4:6])
+	b[13] = '-'
+	hex.Encode(b[14:18], uuid[6:8])
+	b[18] = '-'
+	hex.Encode(b[19:23], uuid[8:10])
+	b[23] = '-'
+	hex.Encode(b[24:], uuid[10:16])
+
+	return GetString(b)
+}
+
+// FunctionName returns function name
+func FunctionName(fn interface{}) string {
+	t := reflect.ValueOf(fn).Type()
+	if t.Kind() == reflect.Func {
+		return runtime.FuncForPC(reflect.ValueOf(fn).Pointer()).Name()
+	}
+	return t.String()
+}
+
+// GetArgument check if key is in arguments
+func GetArgument(arg string) bool {
+	for i := range os.Args[1:] {
+		if os.Args[1:][i] == arg {
+			return true
+		}
+	}
+	return false
+}

+ 104 - 0
vendor/github.com/gofiber/utils/convert.go

@@ -0,0 +1,104 @@
+// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
+// 🤖 Github Repository: https://github.com/gofiber/fiber
+// 📌 API Documentation: https://docs.gofiber.io
+
+package utils
+
+import (
+	"reflect"
+	"strconv"
+	"strings"
+	"unsafe"
+)
+
+// #nosec G103
+// GetString returns a string pointer without allocation
+func UnsafeString(b []byte) string {
+	return *(*string)(unsafe.Pointer(&b))
+}
+
+// #nosec G103
+// GetBytes returns a byte pointer without allocation
+func UnsafeBytes(s string) (bs []byte) {
+	sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
+	bh := (*reflect.SliceHeader)(unsafe.Pointer(&bs))
+	bh.Data = sh.Data
+	bh.Len = sh.Len
+	bh.Cap = sh.Len
+	return
+}
+
+// SafeString copies a string to make it immutable
+func SafeString(s string) string {
+	return string(UnsafeBytes(s))
+}
+
+// SafeBytes copies a slice to make it immutable
+func SafeBytes(b []byte) []byte {
+	tmp := make([]byte, len(b))
+	copy(tmp, b)
+	return tmp
+}
+
+const (
+	uByte = 1 << (10 * iota)
+	uKilobyte
+	uMegabyte
+	uGigabyte
+	uTerabyte
+	uPetabyte
+	uExabyte
+)
+
+// ByteSize returns a human-readable byte string of the form 10M, 12.5K, and so forth.
+// The unit that results in the smallest number greater than or equal to 1 is always chosen.
+func ByteSize(bytes uint64) string {
+	unit := ""
+	value := float64(bytes)
+	switch {
+	case bytes >= uExabyte:
+		unit = "EB"
+		value = value / uExabyte
+	case bytes >= uPetabyte:
+		unit = "PB"
+		value = value / uPetabyte
+	case bytes >= uTerabyte:
+		unit = "TB"
+		value = value / uTerabyte
+	case bytes >= uGigabyte:
+		unit = "GB"
+		value = value / uGigabyte
+	case bytes >= uMegabyte:
+		unit = "MB"
+		value = value / uMegabyte
+	case bytes >= uKilobyte:
+		unit = "KB"
+		value = value / uKilobyte
+	case bytes >= uByte:
+		unit = "B"
+	default:
+		return "0B"
+	}
+	result := strconv.FormatFloat(value, 'f', 1, 64)
+	result = strings.TrimSuffix(result, ".0")
+	return result + unit
+}
+
+// Deprecated fn's
+
+// #nosec G103
+// GetString returns a string pointer without allocation
+func GetString(b []byte) string {
+	return UnsafeString(b)
+}
+
+// #nosec G103
+// GetBytes returns a byte pointer without allocation
+func GetBytes(s string) []byte {
+	return UnsafeBytes(s)
+}
+
+// ImmutableString copies a string to make it immutable
+func ImmutableString(s string) string {
+	return SafeString(s)
+}

+ 110 - 0
vendor/github.com/gofiber/utils/file.go

@@ -0,0 +1,110 @@
+package utils
+
+import (
+	"io"
+	"net/http"
+	"os"
+	pathpkg "path"
+	"path/filepath"
+	"sort"
+)
+
+// Walk walks the filesystem rooted at root, calling walkFn for each file or
+// directory in the filesystem, including root. All errors that arise visiting files
+// and directories are filtered by walkFn. The files are walked in lexical
+// order.
+func Walk(fs http.FileSystem, root string, walkFn filepath.WalkFunc) error {
+	info, err := stat(fs, root)
+	if err != nil {
+		return walkFn(root, nil, err)
+	}
+	return walk(fs, root, info, walkFn)
+}
+
+// #nosec G304
+// ReadFile returns the raw content of a file
+func ReadFile(path string, fs http.FileSystem) ([]byte, error) {
+	if fs != nil {
+		file, err := fs.Open(path)
+		if err != nil {
+			return nil, err
+		}
+		defer file.Close()
+		return io.ReadAll(file)
+	}
+	return os.ReadFile(path)
+}
+
+// readDirNames reads the directory named by dirname and returns
+// a sorted list of directory entries.
+func readDirNames(fs http.FileSystem, dirname string) ([]string, error) {
+	fis, err := readDir(fs, dirname)
+	if err != nil {
+		return nil, err
+	}
+	names := make([]string, len(fis))
+	for i := range fis {
+		names[i] = fis[i].Name()
+	}
+	sort.Strings(names)
+	return names, nil
+}
+
+// walk recursively descends path, calling walkFn.
+func walk(fs http.FileSystem, path string, info os.FileInfo, walkFn filepath.WalkFunc) error {
+	err := walkFn(path, info, nil)
+	if err != nil {
+		if info.IsDir() && err == filepath.SkipDir {
+			return nil
+		}
+		return err
+	}
+
+	if !info.IsDir() {
+		return nil
+	}
+
+	names, err := readDirNames(fs, path)
+	if err != nil {
+		return walkFn(path, info, err)
+	}
+
+	for _, name := range names {
+		filename := pathpkg.Join(path, name)
+		fileInfo, err := stat(fs, filename)
+		if err != nil {
+			if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir {
+				return err
+			}
+		} else {
+			err = walk(fs, filename, fileInfo, walkFn)
+			if err != nil {
+				if !fileInfo.IsDir() || err != filepath.SkipDir {
+					return err
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// readDir reads the contents of the directory associated with file and
+// returns a slice of FileInfo values in directory order.
+func readDir(fs http.FileSystem, name string) ([]os.FileInfo, error) {
+	f, err := fs.Open(name)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	return f.Readdir(0)
+}
+
+// stat returns the FileInfo structure describing file.
+func stat(fs http.FileSystem, name string) (os.FileInfo, error) {
+	f, err := fs.Open(name)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	return f.Stat()
+}

+ 212 - 0
vendor/github.com/gofiber/utils/http.go

@@ -0,0 +1,212 @@
+// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
+// 🤖 Github Repository: https://github.com/gofiber/fiber
+// 📌 API Documentation: https://docs.gofiber.io
+
+package utils
+
+const MIMEOctetStream = "application/octet-stream"
+
+// GetMIME returns the content-type of a file extension
+func GetMIME(extension string) (mime string) {
+	if len(extension) == 0 {
+		return mime
+	}
+	if extension[0] == '.' {
+		mime = mimeExtensions[extension[1:]]
+	} else {
+		mime = mimeExtensions[extension]
+	}
+	if len(mime) == 0 {
+		return MIMEOctetStream
+	}
+	return mime
+}
+
+// limits for HTTP statuscodes
+const (
+	statusMessageMin = 100
+	statusMessageMax = 511
+)
+
+// StatusMessage returns the correct message for the provided HTTP statuscode
+func StatusMessage(status int) string {
+	if status < statusMessageMin || status > statusMessageMax {
+		return ""
+	}
+	return statusMessage[status]
+}
+
+// HTTP status codes were copied from net/http.
+var statusMessage = []string{
+	100: "Continue",
+	101: "Switching Protocols",
+	102: "Processing",
+	103: "Early Hints",
+	200: "OK",
+	201: "Created",
+	202: "Accepted",
+	203: "Non-Authoritative Information",
+	204: "No Content",
+	205: "Reset Content",
+	206: "Partial Content",
+	207: "Multi-Status",
+	208: "Already Reported",
+	226: "IM Used",
+	300: "Multiple Choices",
+	301: "Moved Permanently",
+	302: "Found",
+	303: "See Other",
+	304: "Not Modified",
+	305: "Use Proxy",
+	306: "Switch Proxy",
+	307: "Temporary Redirect",
+	308: "Permanent Redirect",
+	400: "Bad Request",
+	401: "Unauthorized",
+	402: "Payment Required",
+	403: "Forbidden",
+	404: "Not Found",
+	405: "Method Not Allowed",
+	406: "Not Acceptable",
+	407: "Proxy Authentication Required",
+	408: "Request Timeout",
+	409: "Conflict",
+	410: "Gone",
+	411: "Length Required",
+	412: "Precondition Failed",
+	413: "Request Entity Too Large",
+	414: "Request URI Too Long",
+	415: "Unsupported Media Type",
+	416: "Requested Range Not Satisfiable",
+	417: "Expectation Failed",
+	418: "I'm a teapot",
+	421: "Misdirected Request",
+	422: "Unprocessable Entity",
+	423: "Locked",
+	424: "Failed Dependency",
+	426: "Upgrade Required",
+	428: "Precondition Required",
+	429: "Too Many Requests",
+	431: "Request Header Fields Too Large",
+	451: "Unavailable For Legal Reasons",
+	500: "Internal Server Error",
+	501: "Not Implemented",
+	502: "Bad Gateway",
+	503: "Service Unavailable",
+	504: "Gateway Timeout",
+	505: "HTTP Version Not Supported",
+	506: "Variant Also Negotiates",
+	507: "Insufficient Storage",
+	508: "Loop Detected",
+	510: "Not Extended",
+	511: "Network Authentication Required",
+}
+
+// MIME types were copied from https://github.com/nginx/nginx/blob/master/conf/mime.types
+var mimeExtensions = map[string]string{
+	"html":    "text/html",
+	"htm":     "text/html",
+	"shtml":   "text/html",
+	"css":     "text/css",
+	"gif":     "image/gif",
+	"jpeg":    "image/jpeg",
+	"jpg":     "image/jpeg",
+	"xml":     "application/xml",
+	"js":      "application/javascript",
+	"atom":    "application/atom+xml",
+	"rss":     "application/rss+xml",
+	"mml":     "text/mathml",
+	"txt":     "text/plain",
+	"jad":     "text/vnd.sun.j2me.app-descriptor",
+	"wml":     "text/vnd.wap.wml",
+	"htc":     "text/x-component",
+	"png":     "image/png",
+	"svg":     "image/svg+xml",
+	"svgz":    "image/svg+xml",
+	"tif":     "image/tiff",
+	"tiff":    "image/tiff",
+	"wbmp":    "image/vnd.wap.wbmp",
+	"webp":    "image/webp",
+	"ico":     "image/x-icon",
+	"jng":     "image/x-jng",
+	"bmp":     "image/x-ms-bmp",
+	"woff":    "font/woff",
+	"woff2":   "font/woff2",
+	"jar":     "application/java-archive",
+	"war":     "application/java-archive",
+	"ear":     "application/java-archive",
+	"json":    "application/json",
+	"hqx":     "application/mac-binhex40",
+	"doc":     "application/msword",
+	"pdf":     "application/pdf",
+	"ps":      "application/postscript",
+	"eps":     "application/postscript",
+	"ai":      "application/postscript",
+	"rtf":     "application/rtf",
+	"m3u8":    "application/vnd.apple.mpegurl",
+	"kml":     "application/vnd.google-earth.kml+xml",
+	"kmz":     "application/vnd.google-earth.kmz",
+	"xls":     "application/vnd.ms-excel",
+	"eot":     "application/vnd.ms-fontobject",
+	"ppt":     "application/vnd.ms-powerpoint",
+	"odg":     "application/vnd.oasis.opendocument.graphics",
+	"odp":     "application/vnd.oasis.opendocument.presentation",
+	"ods":     "application/vnd.oasis.opendocument.spreadsheet",
+	"odt":     "application/vnd.oasis.opendocument.text",
+	"wmlc":    "application/vnd.wap.wmlc",
+	"7z":      "application/x-7z-compressed",
+	"cco":     "application/x-cocoa",
+	"jardiff": "application/x-java-archive-diff",
+	"jnlp":    "application/x-java-jnlp-file",
+	"run":     "application/x-makeself",
+	"pl":      "application/x-perl",
+	"pm":      "application/x-perl",
+	"prc":     "application/x-pilot",
+	"pdb":     "application/x-pilot",
+	"rar":     "application/x-rar-compressed",
+	"rpm":     "application/x-redhat-package-manager",
+	"sea":     "application/x-sea",
+	"swf":     "application/x-shockwave-flash",
+	"sit":     "application/x-stuffit",
+	"tcl":     "application/x-tcl",
+	"tk":      "application/x-tcl",
+	"der":     "application/x-x509-ca-cert",
+	"pem":     "application/x-x509-ca-cert",
+	"crt":     "application/x-x509-ca-cert",
+	"xpi":     "application/x-xpinstall",
+	"xhtml":   "application/xhtml+xml",
+	"xspf":    "application/xspf+xml",
+	"zip":     "application/zip",
+	"bin":     "application/octet-stream",
+	"exe":     "application/octet-stream",
+	"dll":     "application/octet-stream",
+	"deb":     "application/octet-stream",
+	"dmg":     "application/octet-stream",
+	"iso":     "application/octet-stream",
+	"img":     "application/octet-stream",
+	"msi":     "application/octet-stream",
+	"msp":     "application/octet-stream",
+	"msm":     "application/octet-stream",
+	"mid":     "audio/midi",
+	"midi":    "audio/midi",
+	"kar":     "audio/midi",
+	"mp3":     "audio/mpeg",
+	"ogg":     "audio/ogg",
+	"m4a":     "audio/x-m4a",
+	"ra":      "audio/x-realaudio",
+	"3gpp":    "video/3gpp",
+	"3gp":     "video/3gpp",
+	"ts":      "video/mp2t",
+	"mp4":     "video/mp4",
+	"mpeg":    "video/mpeg",
+	"mpg":     "video/mpeg",
+	"mov":     "video/quicktime",
+	"webm":    "video/webm",
+	"flv":     "video/x-flv",
+	"m4v":     "video/x-m4v",
+	"mng":     "video/x-mng",
+	"asx":     "video/x-ms-asf",
+	"asf":     "video/x-ms-asf",
+	"wmv":     "video/x-ms-wmv",
+	"avi":     "video/x-msvideo",
+}

+ 13 - 0
vendor/github.com/gofiber/utils/integer.go

@@ -0,0 +1,13 @@
+// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
+// 🤖 Github Repository: https://github.com/gofiber/fiber
+// 📌 API Documentation: https://docs.gofiber.io
+
+package utils
+
+// DefaultINT returns the provided fallback value if int is 0 or lower
+func DefaultINT(value int, defaultValue int) int {
+	if value <= 0 {
+		return defaultValue
+	}
+	return value
+}

+ 70 - 0
vendor/github.com/gofiber/utils/strings.go

@@ -0,0 +1,70 @@
+// ⚡️ Fiber is an Express inspired web framework written in Go with ☕️
+// 🤖 Github Repository: https://github.com/gofiber/fiber
+// 📌 API Documentation: https://docs.gofiber.io
+
+package utils
+
+// ToLower is the equivalent of strings.ToLower
+func ToLower(b string) string {
+	var res = make([]byte, len(b))
+	copy(res, b)
+	for i := 0; i < len(res); i++ {
+		res[i] = toLowerTable[res[i]]
+	}
+
+	return GetString(res)
+}
+
+// ToUpper is the equivalent of strings.ToUpper
+func ToUpper(b string) string {
+	var res = make([]byte, len(b))
+	copy(res, b)
+	for i := 0; i < len(res); i++ {
+		res[i] = toUpperTable[res[i]]
+	}
+
+	return GetString(res)
+}
+
+// TrimLeft is the equivalent of strings.TrimLeft
+func TrimLeft(s string, cutset byte) string {
+	lenStr, start := len(s), 0
+	for start < lenStr && s[start] == cutset {
+		start++
+	}
+	return s[start:]
+}
+
+// Trim is the equivalent of strings.Trim
+func Trim(s string, cutset byte) string {
+	i, j := 0, len(s)-1
+	for ; i < j; i++ {
+		if s[i] != cutset {
+			break
+		}
+	}
+	for ; i < j; j-- {
+		if s[j] != cutset {
+			break
+		}
+	}
+
+	return s[i : j+1]
+}
+
+// TrimRight is the equivalent of strings.TrimRight
+func TrimRight(s string, cutset byte) string {
+	lenStr := len(s)
+	for lenStr > 0 && s[lenStr-1] == cutset {
+		lenStr--
+	}
+	return s[:lenStr]
+}
+
+// DefaultString returns the provided fallback value if string is empty
+func DefaultString(value string, defaultValue string) string {
+	if len(value) <= 0 {
+		return defaultValue
+	}
+	return value
+}

+ 10 - 0
vendor/modules.txt

@@ -120,7 +120,17 @@ github.com/godbus/dbus/v5/prop
 github.com/gofiber/fiber/v2
 github.com/gofiber/fiber/v2/internal/schema
 github.com/gofiber/fiber/v2/log
+github.com/gofiber/fiber/v2/middleware/compress
 github.com/gofiber/fiber/v2/utils
+# github.com/gofiber/template v1.8.2
+## explicit; go 1.20
+github.com/gofiber/template
+# github.com/gofiber/template/html/v2 v2.0.5
+## explicit; go 1.20
+github.com/gofiber/template/html/v2
+# github.com/gofiber/utils v1.1.0
+## explicit; go 1.17
+github.com/gofiber/utils
 # github.com/golang/snappy v0.0.4
 ## explicit
 github.com/golang/snappy