├── .gitignore ├── front ├── img_avatar2.png ├── home.html ├── index.html ├── js │ ├── app.js │ └── home.js └── style.css ├── .idea ├── cinema.iml ├── vcs.xml ├── .gitignore └── modules.xml ├── .github ├── labeler.yml └── workflows │ ├── go.yml │ ├── greetings.yml │ ├── integrate.yaml │ ├── label.yml │ └── codacy.yml ├── README.md ├── go.mod ├── main.go ├── cinema └── handler.go └── go.sum /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | *.yaml 3 | *.DS_Store 4 | !.github/workflows -------------------------------------------------------------------------------- /front/img_avatar2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zograf/cinema/HEAD/front/img_avatar2.png -------------------------------------------------------------------------------- /.idea/cinema.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | main: 2 | - '*' 3 | 4 | zograf: 5 | - packages/zograf/* 6 | 7 | upocek: 8 | - packages/upocek/* 9 | 10 | shared: 11 | - packages/shared/* -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /front/home.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Cinema 5 | 6 | 7 | 8 | 9 |
10 |
11 |
12 |
13 | 14 |
15 |
16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cinema app 2 | 3 | [![Codacy Badge](https://api.codacy.com/project/badge/Grade/73c27f96875747c5822715903985c8a3)](https://app.codacy.com/gh/zograf/cinema?utm_source=github.com&utm_medium=referral&utm_content=zograf/cinema&utm_campaign=Badge_Grade_Settings) 4 | 5 | ### Technologies: 6 | 7 | - MongoDB 8 | - Golang 9 | - VanilaJS 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | 16 | - name: Set up Go 17 | uses: actions/setup-go@v3 18 | with: 19 | go-version: 1.18 20 | 21 | - name: Build 22 | run: go build -v ./... 23 | 24 | - name: Test 25 | run: go test -v ./... 26 | -------------------------------------------------------------------------------- /.github/workflows/greetings.yml: -------------------------------------------------------------------------------- 1 | name: Greetings 2 | 3 | on: [pull_request_target, issues] 4 | 5 | jobs: 6 | greeting: 7 | runs-on: ubuntu-latest 8 | permissions: 9 | issues: write 10 | pull-requests: write 11 | steps: 12 | - uses: actions/first-interaction@v1 13 | with: 14 | repo-token: ${{ secrets.GITHUB_TOKEN }} 15 | issue-message: "Hi there, welcome to cinema. We appreciate your issue." 16 | pr-message: "Hi there, welcome to cinema. We appreciate your pr." 17 | -------------------------------------------------------------------------------- /.github/workflows/integrate.yaml: -------------------------------------------------------------------------------- 1 | name: Go Continuous Integration 2 | 3 | on: 4 | pull_request: 5 | branches: [master] 6 | push: 7 | branches: [master] 8 | 9 | jobs: 10 | test_pull_request: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: actions/setup-go@v3 15 | with: 16 | go-version-file: './go.mod' 17 | - run: go version 18 | - run: go mod tidy 19 | - run: go run . -url=${{ secrets.URL }} 20 | -------------------------------------------------------------------------------- /.github/workflows/label.yml: -------------------------------------------------------------------------------- 1 | # This workflow will triage pull requests and apply a label based on the 2 | # paths that are modified in the pull request. 3 | # 4 | # To use this workflow, you will need to set up a .github/labeler.yml 5 | # file with configuration. For more information, see: 6 | # https://github.com/actions/labeler 7 | 8 | name: Labeler 9 | on: [pull_request] 10 | 11 | jobs: 12 | label: 13 | 14 | runs-on: ubuntu-latest 15 | permissions: 16 | contents: read 17 | pull-requests: write 18 | 19 | steps: 20 | - uses: actions/labeler@v4 21 | with: 22 | repo-token: "${{ secrets.GITHUB_TOKEN }}" 23 | -------------------------------------------------------------------------------- /front/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Cinema 4 | 5 | 6 | 7 |
8 |
9 |
10 |

Login

11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 |
23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /front/js/app.js: -------------------------------------------------------------------------------- 1 | const url = "http://localhost"; 2 | const port = "8080"; 3 | const endPoint = url + ":" + port 4 | 5 | function get() { 6 | req = new XMLHttpRequest() ; 7 | 8 | req.onreadystatechange = function() { 9 | if (this.readyState==4 && this.status == 200) { 10 | console.log(req.responseText) 11 | } 12 | } 13 | 14 | req.open("GET", url + ":" + port); 15 | req.send(); 16 | } 17 | 18 | var form = document.getElementById("submit-form"); 19 | form.addEventListener("submit", (e) => { 20 | e.preventDefault(); 21 | login(); 22 | }); 23 | 24 | function login() { 25 | 26 | let username = document.getElementById("username").value; 27 | let password = document.getElementById("password").value; 28 | fetch(endPoint + `/login/${username}/${password}`).then( 29 | response => response.json() 30 | ).then( 31 | data => { 32 | if (Object.keys(data).length === 0) { 33 | alert("Login failed") 34 | } else { 35 | window.location.replace("home.html?id=" + data.id) 36 | } 37 | } 38 | ) 39 | } 40 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/zograf/cinema 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/gin-contrib/cors v1.3.1 7 | github.com/gin-gonic/gin v1.7.7 8 | go.mongodb.org/mongo-driver v1.8.4 9 | gopkg.in/yaml.v2 v2.2.8 10 | ) 11 | 12 | require ( 13 | github.com/gin-contrib/sse v0.1.0 // indirect 14 | github.com/go-playground/locales v0.13.0 // indirect 15 | github.com/go-playground/universal-translator v0.17.0 // indirect 16 | github.com/go-playground/validator/v10 v10.4.1 // indirect 17 | github.com/go-stack/stack v1.8.0 // indirect 18 | github.com/golang/protobuf v1.3.3 // indirect 19 | github.com/golang/snappy v0.0.1 // indirect 20 | github.com/json-iterator/go v1.1.9 // indirect 21 | github.com/klauspost/compress v1.13.6 // indirect 22 | github.com/leodido/go-urn v1.2.0 // indirect 23 | github.com/mattn/go-isatty v0.0.12 // indirect 24 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect 25 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect 26 | github.com/pkg/errors v0.9.1 // indirect 27 | github.com/ugorji/go/codec v1.1.7 // indirect 28 | github.com/xdg-go/pbkdf2 v1.0.0 // indirect 29 | github.com/xdg-go/scram v1.0.2 // indirect 30 | github.com/xdg-go/stringprep v1.0.2 // indirect 31 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect 32 | golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f // indirect 33 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect 34 | golang.org/x/sys v0.0.0-20220329152356-43be30ef3008 // indirect 35 | golang.org/x/text v0.3.5 // indirect 36 | ) 37 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "net/http" 6 | "strconv" 7 | 8 | "github.com/gin-contrib/cors" 9 | "github.com/gin-gonic/gin" 10 | "github.com/zograf/cinema/cinema" 11 | ) 12 | 13 | var app *cinema.App 14 | var url string 15 | 16 | func getMovies(c *gin.Context) { 17 | c.Header("Access-Control-Allow-Origin", "*") 18 | result := app.GetMovies() 19 | c.JSON(http.StatusOK, result) 20 | } 21 | 22 | func login(c *gin.Context) { 23 | c.Header("Access-Control-Allow-Origin", "*") 24 | username := c.Param("username") 25 | password := c.Param("password") 26 | result := app.Login(username, password) 27 | c.JSON(http.StatusOK, result) 28 | } 29 | 30 | func getUserData(c *gin.Context) { 31 | c.Header("Access-Control-Allow-Origin", "*") 32 | idParameter := c.Param("id") 33 | id, err := strconv.Atoi(idParameter) 34 | check(err) 35 | result := app.GetUserData(id) 36 | c.JSON(http.StatusOK, result) 37 | } 38 | 39 | func put(c *gin.Context) { 40 | c.Header("Access-Control-Allow-Origin", "*") 41 | c.JSON(http.StatusOK, gin.H{"data": "DUMMY"}) 42 | } 43 | 44 | func del(c *gin.Context) { 45 | c.Header("Access-Control-Allow-Origin", "*") 46 | c.JSON(http.StatusOK, gin.H{"data": "DUMMY"}) 47 | } 48 | 49 | func main() { 50 | flag.StringVar(&url, "url", "", "mongodb connection string") 51 | flag.Parse() 52 | 53 | router := gin.Default() 54 | app = cinema.CreateApp("Cinema", url) 55 | 56 | router.GET("/login/:username/:password", login) 57 | router.GET("/user/:id", getUserData) 58 | router.GET("/movies", getMovies) 59 | router.POST("/", put) 60 | router.DELETE("/", del) 61 | 62 | router.Use(cors.Default()) 63 | router.Run() 64 | } 65 | 66 | func check(err error) { 67 | if err != nil { 68 | panic(err) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /front/style.css: -------------------------------------------------------------------------------- 1 | @import url(http://weloveiconfonts.com/api/?family=entypo); 2 | @import url(https://fonts.googleapis.com/css?family=Roboto); 3 | 4 | /* zocial */ 5 | [class*="entypo-"]:before { 6 | font-family: 'entypo', sans-serif; 7 | } 8 | 9 | *, 10 | *:before, 11 | *:after { 12 | -moz-box-sizing: border-box; 13 | -webkit-box-sizing: border-box; 14 | box-sizing: border-box; 15 | } 16 | 17 | 18 | .container h2 { 19 | color: rgba(255, 255, 255, .8); 20 | margin-left: 12px; 21 | } 22 | 23 | body { 24 | background: #272125; 25 | font-family: 'Roboto', sans-serif; 26 | 27 | } 28 | 29 | .container { 30 | position: relative; 31 | width: 380px; 32 | height: auto; 33 | top: 40vh; 34 | transform: translate(-50%, -50%); 35 | left: 50vw; 36 | text-align: center; 37 | } 38 | 39 | input { 40 | padding: 16px; 41 | border-radius: 7px; 42 | border: 0px; 43 | background: rgba(255, 255, 255, .2); 44 | display: block; 45 | margin: 15px; 46 | width: 300px; 47 | color: white; 48 | font-size: 18px; 49 | height: 54px; 50 | } 51 | 52 | input:focus { 53 | outline-color: rgba(0, 0, 0, 0); 54 | background: rgba(255, 255, 255, .95); 55 | color: #e74c3c; 56 | } 57 | 58 | button { 59 | float: right; 60 | height: 121px; 61 | width: 50px; 62 | border: 0px; 63 | background: #e74c3c; 64 | border-radius: 7px; 65 | padding: 10px; 66 | color: white; 67 | font-size: 22px; 68 | } 69 | 70 | .inputUserIcon { 71 | position: absolute; 72 | top: 68px; 73 | right: 80px; 74 | color: white; 75 | } 76 | 77 | .inputPassIcon { 78 | position: absolute; 79 | top: 136px; 80 | right: 80px; 81 | color: white; 82 | } 83 | 84 | input::-webkit-input-placeholder { 85 | color: white; 86 | } 87 | 88 | input:focus::-webkit-input-placeholder { 89 | color: #e74c3c; 90 | } 91 | 92 | .movieCard { 93 | display: flex; 94 | flex-direction: row; 95 | justify-content: center; 96 | align-items: center; 97 | padding: 40px; 98 | border: 2px solid #e74c3c; 99 | box-shadow: 0px 10px 15px -3px rgba(0, 0, 0, 0.1); 100 | border-radius: 10px; 101 | transition-duration: 250ms; 102 | } 103 | 104 | .movieCard img { 105 | width: 200px; 106 | } 107 | 108 | .movieCard:hover { 109 | box-shadow: 0px 10px 15px 24px rgba(0, 0, 0, 0.1); 110 | } 111 | -------------------------------------------------------------------------------- /front/js/home.js: -------------------------------------------------------------------------------- 1 | const url = "http://localhost"; 2 | const port = "8080"; 3 | const endPoint = url + ":" + port 4 | 5 | var user 6 | 7 | function getParamValue(name) { 8 | let location = decodeURI(window.location.toString()); 9 | let index = location.indexOf('?') + 1; 10 | let subs = location.substring(index, location.length); 11 | let splitted = subs.split('&'); 12 | 13 | for (let item of splitted) { 14 | let s = item.split('='); 15 | let pName = s[0]; 16 | let pValue = s[1]; 17 | if (pName == name) 18 | return pValue; 19 | } 20 | } 21 | 22 | async function onLoad() { 23 | let id = getParamValue("id"); 24 | 25 | await fetch(endPoint + `/user/${id}`).then( 26 | response => { 27 | return response.json() 28 | } 29 | ).then( 30 | data => { 31 | user = data 32 | } 33 | ) 34 | } 35 | 36 | async function getMovies(){ 37 | return await fetch(endPoint + `/movies`).then( 38 | response => response.json() 39 | ) 40 | } 41 | 42 | async function showMovies(){ 43 | let moviesContainer = document.getElementById('all-movies'); 44 | let movies = await getMovies(); 45 | console.log(movies) 46 | for(let movie of movies){ 47 | let newCard = document.createElement('div'); 48 | newCard.classList.add('movieCard'); 49 | let movieImage = document.createElement('img'); 50 | movieImage.setAttribute('src', movie.thumbnail); 51 | let movieName = document.createElement('h2'); 52 | movieName.innerText = movie.name; 53 | let movieGenre = document.createElement('p'); 54 | movieGenre.innerText = movie.genre; 55 | let movieMore = document.createElement('button'); 56 | movieMore.innerText = 'See more'; 57 | movieMore.setAttribute("key", movie.name); 58 | movieMore.addEventListener('click', function() { 59 | window.location.replace(`movie.html/${this.getAttribute('key')}`); 60 | }) 61 | 62 | newCard.appendChild(movieImage); 63 | newCard.appendChild(movieName); 64 | newCard.appendChild(movieGenre); 65 | newCard.appendChild(movieMore); 66 | moviesContainer.appendChild(newCard); 67 | } 68 | } 69 | 70 | document.addEventListener("DOMContentLoaded", () => { 71 | onLoad(); 72 | showMovies(); 73 | }) 74 | -------------------------------------------------------------------------------- /.github/workflows/codacy.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | # This workflow checks out code, performs a Codacy security scan 7 | # and integrates the results with the 8 | # GitHub Advanced Security code scanning feature. For more information on 9 | # the Codacy security scan action usage and parameters, see 10 | # https://github.com/codacy/codacy-analysis-cli-action. 11 | # For more information on Codacy Analysis CLI in general, see 12 | # https://github.com/codacy/codacy-analysis-cli. 13 | 14 | name: Codacy Security Scan 15 | 16 | on: 17 | push: 18 | branches: [ "master" ] 19 | pull_request: 20 | # The branches below must be a subset of the branches above 21 | branches: [ "master" ] 22 | schedule: 23 | - cron: '0 0 * * *' 24 | 25 | permissions: 26 | contents: read 27 | 28 | jobs: 29 | codacy-security-scan: 30 | permissions: 31 | contents: read # for actions/checkout to fetch code 32 | security-events: write # for github/codeql-action/upload-sarif to upload SARIF results 33 | name: Codacy Security Scan 34 | runs-on: ubuntu-latest 35 | steps: 36 | # Checkout the repository to the GitHub Actions runner 37 | - name: Checkout code 38 | uses: actions/checkout@v3 39 | 40 | # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis 41 | - name: Run Codacy Analysis CLI 42 | uses: codacy/codacy-analysis-cli-action@d840f886c4bd4edc059706d09c6a1586111c540b 43 | with: 44 | # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository 45 | # You can also omit the token and run the tools that support default configurations 46 | project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} 47 | verbose: true 48 | output: results.sarif 49 | format: sarif 50 | # Adjust severity of non-security issues 51 | gh-code-scanning-compat: true 52 | # Force 0 exit code to allow SARIF file generation 53 | # This will handover control about PR rejection to the GitHub side 54 | max-allowed-issues: 2147483647 55 | 56 | # Upload the SARIF file generated in the previous step 57 | - name: Upload SARIF results file 58 | uses: github/codeql-action/upload-sarif@v2 59 | with: 60 | sarif_file: results.sarif 61 | -------------------------------------------------------------------------------- /cinema/handler.go: -------------------------------------------------------------------------------- 1 | package cinema 2 | 3 | import ( 4 | "context" 5 | "io/ioutil" 6 | "time" 7 | 8 | "go.mongodb.org/mongo-driver/bson" 9 | "go.mongodb.org/mongo-driver/mongo" 10 | "go.mongodb.org/mongo-driver/mongo/options" 11 | "gopkg.in/yaml.v2" 12 | ) 13 | 14 | type App struct { 15 | database string 16 | client *mongo.Client 17 | url string 18 | } 19 | 20 | func (app *App) Login(username, password string) map[string]interface{} { 21 | result := app.find("Users", bson.D{{Key: "username", Value: username}, {Key: "password", Value: password}}) 22 | if len(result) != 0 { 23 | return result[0] 24 | } 25 | return make(map[string]interface{}) 26 | } 27 | 28 | func (app *App) GetMovies() []map[string]interface{} { 29 | result := app.find("Repertoire", bson.D{}) 30 | return result 31 | } 32 | 33 | func (app *App) GetUserData(id int) map[string]interface{} { 34 | result := app.find("Users", bson.D{{Key: "id", Value: id}}) 35 | if len(result) != 0 { 36 | return result[0] 37 | } 38 | return make(map[string]interface{}) 39 | } 40 | 41 | func CreateApp(database, url string) *App { 42 | app := App{ 43 | database: database, 44 | } 45 | 46 | if url == "" { 47 | app.readConfig() 48 | } else { 49 | app.url = url 50 | } 51 | 52 | app.dbConnect() 53 | return &app 54 | } 55 | 56 | func (app *App) dbConnect() { 57 | serverAPIOptions := options.ServerAPI(options.ServerAPIVersion1) 58 | clientOptions := options.Client(). 59 | ApplyURI(app.url). 60 | SetServerAPIOptions(serverAPIOptions) 61 | ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 62 | defer cancel() 63 | client, err := mongo.Connect(ctx, clientOptions) 64 | check(err) 65 | app.client = client 66 | } 67 | 68 | func (app *App) find(collection string, filter bson.D) []map[string]interface{} { 69 | db := app.client.Database(app.database).Collection(collection) 70 | cursor, err := db.Find(context.TODO(), filter) 71 | check(err) 72 | var result []bson.M 73 | err = cursor.All(context.TODO(), &result) 74 | check(err) 75 | var responses []map[string]interface{} 76 | 77 | for index, el := range result { 78 | responses = append(responses, make(map[string]interface{})) 79 | for key, value := range el { 80 | responses[index][key] = value 81 | } 82 | } 83 | return responses 84 | } 85 | 86 | func (app *App) readConfig() { 87 | pathToConfig := "config.yaml" 88 | yamlFile, err := ioutil.ReadFile(pathToConfig) 89 | check(err) 90 | yamlContent := make(map[string]string, 1) 91 | err = yaml.Unmarshal(yamlFile, &yamlContent) 92 | check(err) 93 | app.url = yamlContent["url"] 94 | } 95 | 96 | func check(err error) { 97 | if err != nil { 98 | panic(err) 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 2 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 3 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 4 | github.com/gin-contrib/cors v1.3.1 h1:doAsuITavI4IOcd0Y19U4B+O0dNWihRyX//nn4sEmgA= 5 | github.com/gin-contrib/cors v1.3.1/go.mod h1:jjEJ4268OPZUcU7k9Pm653S7lXUGcqMADzFA61xsmDk= 6 | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= 7 | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= 8 | github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= 9 | github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= 10 | github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= 11 | github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= 12 | github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= 13 | github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= 14 | github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= 15 | github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= 16 | github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= 17 | github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= 18 | github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= 19 | github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= 20 | github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= 21 | github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= 22 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 23 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 24 | github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= 25 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 26 | github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= 27 | github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 28 | github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= 29 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 30 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 31 | github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 32 | github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= 33 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 34 | github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= 35 | github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= 36 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 37 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 38 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 39 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 40 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 41 | github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= 42 | github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= 43 | github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= 44 | github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= 45 | github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= 46 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 47 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= 48 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 49 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= 50 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 51 | github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= 52 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 53 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 54 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 55 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 56 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 57 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 58 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 59 | github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= 60 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 61 | github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= 62 | github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= 63 | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= 64 | github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= 65 | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= 66 | github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= 67 | github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= 68 | github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= 69 | github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= 70 | github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= 71 | github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= 72 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= 73 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= 74 | go.mongodb.org/mongo-driver v1.8.4 h1:NruvZPPL0PBcRJKmbswoWSrmHeUvzdxA3GCPfD/NEOA= 75 | go.mongodb.org/mongo-driver v1.8.4/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= 76 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 77 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 78 | golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f h1:aZp0e2vLN4MToVqnjNEYEtrEA8RH8U8FN1CU7JgqsPU= 79 | golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= 80 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 81 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 82 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 83 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= 84 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 85 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 86 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 87 | golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 88 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 89 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 90 | golang.org/x/sys v0.0.0-20220329152356-43be30ef3008 h1:pq9pwoi2rjLWvmiVser/lIOgiyA3fli4M+RfGVMA7nE= 91 | golang.org/x/sys v0.0.0-20220329152356-43be30ef3008/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 92 | golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 93 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 94 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 95 | golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= 96 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 97 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 98 | golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 99 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 100 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 101 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 102 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 103 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 104 | gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= 105 | gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= 106 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 107 | gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= 108 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 109 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 110 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 111 | --------------------------------------------------------------------------------