├── .devcontainer └── devcontainer.json ├── .dockerignore ├── .gitignore ├── .vscode └── launch.json ├── Dockerfile ├── LICENSE ├── README.md ├── config.yaml ├── index.js ├── lib ├── OpenALPR.js ├── RandomString.js └── Server.js ├── package-lock.json └── package.json /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.205.2/containers/docker-existing-dockerfile 3 | { 4 | "name": "Existing Dockerfile", 5 | 6 | // Sets the run context to one level up instead of the .devcontainer folder. 7 | "context": "..", 8 | 9 | // Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename. 10 | "dockerFile": "../Dockerfile", 11 | 12 | // Set *default* container specific settings.json values on container create. 13 | "settings": {}, 14 | 15 | // Add the IDs of extensions you want installed when the container is created. 16 | "extensions": [], 17 | 18 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 19 | "forwardPorts": [3000], 20 | 21 | // Uncomment the next line to run commands after the container is created - for example installing curl. 22 | // "postCreateCommand": "apt-get update && apt-get install -y curl", 23 | 24 | // Uncomment when using a ptrace-based debugger like C++, Go, and Rust 25 | // "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ], 26 | 27 | // Uncomment to use the Docker CLI from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker. 28 | // "mounts": [ "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ], 29 | 30 | // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root. 31 | // "remoteUser": "vscode" 32 | } 33 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .devcontainer 2 | .vscode 3 | .examples 4 | Dockerfile -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "pwa-node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "skipFiles": [ 12 | "/**" 13 | ], 14 | "program": "${workspaceFolder}/index.js" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Compile alpr 2 | FROM ubuntu:20.04 3 | 4 | LABEL description="Open ALPR HTTP Wrapper" 5 | LABEL maintainer "seanclaflin@protonmail.com" 6 | 7 | # Workaround for devcontainer to use bash instead of sh 8 | ENV SHELL /bin/bash 9 | 10 | # Install prerequisites 11 | RUN apt update \ 12 | && apt upgrade -y \ 13 | && DEBIAN_FRONTEND="noninteractive" \ 14 | apt install -y \ 15 | # General 16 | git \ 17 | checkinstall \ 18 | # OpenALPR requirements 19 | build-essential \ 20 | cmake \ 21 | libcurl3-dev \ 22 | libleptonica-dev \ 23 | liblog4cplus-dev \ 24 | libopencv-dev \ 25 | libtesseract-dev \ 26 | && rm -rf /var/lib/apt/lists/* 27 | 28 | # Clone the latest code from GitHub 29 | WORKDIR /src 30 | RUN git clone https://github.com/openalpr/openalpr.git \ 31 | && mkdir -p openalpr/src/build 32 | 33 | # Build & install OpenALPR 34 | WORKDIR /src/openalpr/src/build 35 | RUN cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr -DCMAKE_INSTALL_SYSCONFDIR:PATH=/etc .. \ 36 | && make \ 37 | # && make install 38 | && checkinstall -y --install=no --addso=yes --pakdir=/src/openalpr --pkgversion=0 --pkgname=alpr 39 | 40 | # Build final image 41 | FROM ubuntu:20.04 42 | 43 | # Install prerequisites 44 | RUN apt update \ 45 | # && apt upgrade -y \ 46 | && DEBIAN_FRONTEND="noninteractive" \ 47 | apt install -y \ 48 | # General 49 | lsb-release \ 50 | gnupg \ 51 | # alpr requirements 52 | libopencv-videoio4.2 \ 53 | libopencv-video4.2 \ 54 | libopencv-highgui4.2 \ 55 | libopencv-objdetect4.2 \ 56 | libtesseract4 \ 57 | # Nodesource requirements 58 | apt-transport-https \ 59 | wget \ 60 | && rm -rf /var/lib/apt/lists/* 61 | 62 | # Copy over and install alpr 63 | COPY --from=0 /src/openalpr/alpr_0-1_amd64.deb /app/ 64 | RUN dpkg -i /app/alpr_0-1_amd64.deb 65 | 66 | # Set up nodesource repo & install nodejs 67 | RUN KEYRING=/usr/share/keyrings/nodesource.gpg \ 68 | && VERSION=node_16.x \ 69 | && DISTRO=$(lsb_release -s -c) \ 70 | && wget --quiet -O - https://deb.nodesource.com/gpgkey/nodesource.gpg.key | gpg --dearmor | tee "$KEYRING" >/dev/null \ 71 | && echo "deb [signed-by=$KEYRING] https://deb.nodesource.com/$VERSION $DISTRO main" | tee /etc/apt/sources.list.d/nodesource.list \ 72 | && echo "deb-src [signed-by=$KEYRING] https://deb.nodesource.com/$VERSION $DISTRO main" | tee -a /etc/apt/sources.list.d/nodesource.list \ 73 | && apt update \ 74 | && apt install -y nodejs \ 75 | && rm -rf /var/lib/apt/lists/* 76 | 77 | # Copy application files over 78 | COPY index.js /app/ 79 | COPY config.yaml /app/ 80 | COPY package*.json /app/ 81 | COPY lib /app/lib 82 | 83 | WORKDIR /app 84 | 85 | RUN npm ci 86 | 87 | # Create the application user 88 | RUN useradd -m app 89 | 90 | # Run as the new user 91 | USER app 92 | 93 | CMD ["/usr/bin/npm", "start"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright © 2021 Sean Claflin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Open ALPR HTTP Wrapper # 2 | 3 | Just a small wrapper around the Open ALPR cli binary. 4 | 5 | Simply send and HTTP Post of image data to `/detect` and get back JSON results from the attempted detection. 6 | 7 | ## Installation ## 8 | 9 | A docker image is available via: 10 | ```bash 11 | docker pull sclaflin/open-alpr-http-wrapper 12 | ``` 13 | 14 | Docker Compose: 15 | 16 | ```yaml 17 | version: "3.9" 18 | services: 19 | open-alpr-http-wrapper: 20 | container_name: open-alpr-http-wrapper 21 | restart: unless-stopped 22 | image: sclaflin/open-alpr-http-wrapper:latest 23 | ports: 24 | - "3000:3000" 25 | ``` 26 | 27 | ## Usage ## 28 | 29 | Post image data to the /detect endpoint: 30 | 31 | ```bash 32 | curl -F upload=@car0.png http://localhost:3000/detect 33 | ``` 34 | 35 | The following output is returned: 36 | 37 | ```json 38 | { 39 | "version": 2, 40 | "data_type": "alpr_results", 41 | "epoch_time": 1638566810336, 42 | "img_width": 1289, 43 | "img_height": 744, 44 | "processing_time_ms": 146.275497, 45 | "regions_of_interest": [], 46 | "results": [ 47 | { 48 | "plate": "YZ88658", 49 | "confidence": 85.818779, 50 | "matches_template": 0, 51 | "plate_index": 0, 52 | "region": "", 53 | "region_confidence": 0, 54 | "processing_time_ms": 12.290022, 55 | "requested_topn": 10, 56 | "coordinates": [ 57 | { 58 | "x": 682, 59 | "y": 342 60 | }, 61 | { 62 | "x": 805, 63 | "y": 346 64 | }, 65 | { 66 | "x": 801, 67 | "y": 400 68 | }, 69 | { 70 | "x": 680, 71 | "y": 396 72 | } 73 | ], 74 | "candidates": [ 75 | { 76 | "plate": "YZ88658", 77 | "confidence": 85.818779, 78 | "matches_template": 0 79 | }, 80 | { 81 | "plate": "Y288658", 82 | "confidence": 85.352005, 83 | "matches_template": 0 84 | }, 85 | { 86 | "plate": "YZ8B658", 87 | "confidence": 83.173759, 88 | "matches_template": 0 89 | }, 90 | { 91 | "plate": "Y28B658", 92 | "confidence": 82.706985, 93 | "matches_template": 0 94 | }, 95 | { 96 | "plate": "YZ8865B", 97 | "confidence": 78.087212, 98 | "matches_template": 0 99 | } 100 | ] 101 | } 102 | ] 103 | } 104 | ``` 105 | 106 | The root of the server also presents a form that you can use via web browser to upload and detect files. -------------------------------------------------------------------------------- /config.yaml: -------------------------------------------------------------------------------- 1 | port: 3000 -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import Server from "./lib/Server.js"; 2 | import fs from 'fs/promises'; 3 | import YAML from 'yaml'; 4 | 5 | (async () => { 6 | const { port } = YAML.parse( 7 | (await fs.readFile('config.yaml')) 8 | .toString() 9 | ); 10 | 11 | Server.fromObject({ 12 | port: port || 3000 13 | }); 14 | })() 15 | 16 | -------------------------------------------------------------------------------- /lib/OpenALPR.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs/promises'; 2 | import { Readable } from 'stream'; 3 | import { spawn } from 'child_process'; 4 | import randomString from './RandomString.js'; 5 | 6 | 7 | export const COUNTRY_CODE_AU = 'au'; 8 | export const COUNTRY_CODE_AUWIDE = 'auwide'; 9 | export const COUNTRY_CODE_BR = 'br'; 10 | export const COUNTRY_CODE_BR2 = 'br2'; 11 | export const COUNTRY_CODE_EU = 'eu'; 12 | export const COUNTRY_CODE_FR = 'fr'; 13 | export const COUNTRY_CODE_GB = 'gb'; 14 | export const COUNTRY_CODE_IN = 'in'; 15 | export const COUNTRY_CODE_KR = 'kr'; 16 | export const COUNTRY_CODE_KR2 = 'kr2'; 17 | export const COUNTRY_CODE_MX = 'mx'; 18 | export const COUNTRY_CODE_SG = 'sg'; 19 | export const COUNTRY_CODE_US = 'us'; 20 | export const COUNTRY_CODE_VN2 = 'vn2'; 21 | 22 | const COUNTRY_CODES = [ 23 | COUNTRY_CODE_AU, 24 | COUNTRY_CODE_AUWIDE, 25 | COUNTRY_CODE_BR, 26 | COUNTRY_CODE_BR2, 27 | COUNTRY_CODE_EU, 28 | COUNTRY_CODE_FR, 29 | COUNTRY_CODE_GB, 30 | COUNTRY_CODE_IN, 31 | COUNTRY_CODE_KR, 32 | COUNTRY_CODE_KR2, 33 | COUNTRY_CODE_MX, 34 | COUNTRY_CODE_SG, 35 | COUNTRY_CODE_US, 36 | COUNTRY_CODE_VN2 37 | ]; 38 | 39 | export class OpenALPR { 40 | static async detectBuffer(buff, countryCode = 'us', pattern = null) { 41 | if (!(buff instanceof Buffer)) 42 | throw new TypeError('buff must be an instance of Buffer.'); 43 | 44 | if(COUNTRY_CODES.indexOf(countryCode) === -1) 45 | throw new TypeError('invalid country code.'); 46 | 47 | if(pattern && typeof pattern !== 'string') 48 | throw new TypeError('pattern must be a string.'); 49 | 50 | // alpr only seems to care if the file extension is a known one 51 | // png, jpg, jpeg, bpm (others?) encoding works regardless 52 | const filePath = `/tmp/${randomString(32)}.jpeg`; 53 | await fs.writeFile(filePath, buff); 54 | 55 | const args = ['--country', countryCode, '--json', filePath]; 56 | if (pattern) args.push('--pattern', pattern); 57 | 58 | // alpr looks like it requires a file on disk to read. Cannot pipe. :'( 59 | const ls = spawn('/usr/bin/alpr', args); 60 | const out = []; 61 | const err = []; 62 | 63 | ls.stdout.on('data', (data) => out.push(data)); 64 | ls.stderr.on('data', (data) => err.push(data)); 65 | 66 | await new Promise((resolve, reject) => { 67 | ls.on('close', (code) => { 68 | if(code !== 0) 69 | return reject(new Error(Buffer.concat(err).toString('utf8'))); 70 | return resolve(); 71 | }); 72 | }); 73 | 74 | await fs.rm(filePath, { force: true }); 75 | 76 | return JSON.parse(Buffer.concat(out).toString('utf8')); 77 | } 78 | static async detectFile(path, countryCode = 'us') { 79 | if (typeof path !== 'string') 80 | throw new TypeError('path must be a string.'); 81 | return OpenALPR.detectBuffer(await fs.readFile(path), countryCode); 82 | } 83 | static async detectReadStream(rs, countryCode = 'us') { 84 | if(!(rs instanceof Readable)) 85 | throw new TypeError('rs must be an instance of Readable.'); 86 | 87 | const buffs = []; 88 | rs.on('data', buff => buffs.push(buff)); 89 | await new Promise((resolve) => { 90 | rs.on('close', () => resolve()); 91 | }); 92 | 93 | return OpenALPR.detectBuffer(Buffer.concat(buffs), countryCode); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /lib/RandomString.js: -------------------------------------------------------------------------------- 1 | import Crypto from 'crypto'; 2 | 3 | export default function randomString(size = 21) { 4 | return Crypto 5 | .randomBytes(size) 6 | .toString('hex') 7 | .slice(0, size) 8 | } 9 | -------------------------------------------------------------------------------- /lib/Server.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import multer from "multer"; 3 | import { OpenALPR } from './OpenALPR.js'; 4 | 5 | export default class Server { 6 | #app = null; 7 | #port = null; 8 | #server = null; 9 | 10 | constructor(port) { 11 | this.port = port; 12 | this.#app = express(); 13 | 14 | const upload = multer(); 15 | 16 | this.#app.get('/', (req, res) => this.home(req, res)); 17 | this.#app.post('/detect', upload.single('upload'), (req, res) => this.detect(req, res)); 18 | 19 | this.listen(); 20 | } 21 | get port() { 22 | return this.#port; 23 | } 24 | set port(v) { 25 | if(!Number.isInteger(v)) 26 | throw new TypeError('port must be an integer.'); 27 | this.#port = v; 28 | } 29 | listen() { 30 | if(this.#server) 31 | throw new Error('Server is already listening.'); 32 | this.#server = this.#app.listen(this.port); 33 | } 34 | close() { 35 | if(!this.#server) 36 | throw new Error('Server is not listening.'); 37 | this.#server.close(); 38 | this.#server = null; 39 | } 40 | home(req, res) { 41 | res.send(` 42 |

OpenALPR HTTP Wrapper

43 |

This project is a thin wrapper around the OpenALPR CLI binary.

44 |

HTTP Posts to /detect require an "upload" and an optional "country_code" value.

45 |

Upload an image for License Plate Recognition

46 |
47 | 63 | 64 | 65 | 66 | 67 |
68 | `); 69 | } 70 | async detect(req, res) { 71 | try { 72 | const data = await OpenALPR.detectBuffer(req.file.buffer, req.body.country_code, req.body.pattern); 73 | res.status(200).json(data); 74 | } 75 | catch(err) { 76 | res.status(500).json(err.message); 77 | } 78 | } 79 | 80 | static fromObject(obj) { 81 | if(obj === null || typeof obj !== 'object') 82 | throw new TypeError('obj must be an Object.'); 83 | 84 | return new this( 85 | obj.port 86 | ); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "open-alpr", 3 | "version": "0.2.1", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "open-alpr", 9 | "version": "0.2.1", 10 | "license": "MIT", 11 | "dependencies": { 12 | "express": "^4.17.1", 13 | "multer": "^1.4.3", 14 | "yaml": "^1.10.2" 15 | } 16 | }, 17 | "node_modules/accepts": { 18 | "version": "1.3.7", 19 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 20 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 21 | "dependencies": { 22 | "mime-types": "~2.1.24", 23 | "negotiator": "0.6.2" 24 | }, 25 | "engines": { 26 | "node": ">= 0.6" 27 | } 28 | }, 29 | "node_modules/append-field": { 30 | "version": "1.0.0", 31 | "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", 32 | "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" 33 | }, 34 | "node_modules/array-flatten": { 35 | "version": "1.1.1", 36 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 37 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 38 | }, 39 | "node_modules/body-parser": { 40 | "version": "1.19.0", 41 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 42 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 43 | "dependencies": { 44 | "bytes": "3.1.0", 45 | "content-type": "~1.0.4", 46 | "debug": "2.6.9", 47 | "depd": "~1.1.2", 48 | "http-errors": "1.7.2", 49 | "iconv-lite": "0.4.24", 50 | "on-finished": "~2.3.0", 51 | "qs": "6.7.0", 52 | "raw-body": "2.4.0", 53 | "type-is": "~1.6.17" 54 | }, 55 | "engines": { 56 | "node": ">= 0.8" 57 | } 58 | }, 59 | "node_modules/buffer-from": { 60 | "version": "1.1.2", 61 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 62 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" 63 | }, 64 | "node_modules/busboy": { 65 | "version": "0.2.14", 66 | "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", 67 | "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", 68 | "dependencies": { 69 | "dicer": "0.2.5", 70 | "readable-stream": "1.1.x" 71 | }, 72 | "engines": { 73 | "node": ">=0.8.0" 74 | } 75 | }, 76 | "node_modules/bytes": { 77 | "version": "3.1.0", 78 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 79 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", 80 | "engines": { 81 | "node": ">= 0.8" 82 | } 83 | }, 84 | "node_modules/concat-stream": { 85 | "version": "1.6.2", 86 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 87 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 88 | "engines": [ 89 | "node >= 0.8" 90 | ], 91 | "dependencies": { 92 | "buffer-from": "^1.0.0", 93 | "inherits": "^2.0.3", 94 | "readable-stream": "^2.2.2", 95 | "typedarray": "^0.0.6" 96 | } 97 | }, 98 | "node_modules/concat-stream/node_modules/isarray": { 99 | "version": "1.0.0", 100 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 101 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 102 | }, 103 | "node_modules/concat-stream/node_modules/readable-stream": { 104 | "version": "2.3.7", 105 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 106 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 107 | "dependencies": { 108 | "core-util-is": "~1.0.0", 109 | "inherits": "~2.0.3", 110 | "isarray": "~1.0.0", 111 | "process-nextick-args": "~2.0.0", 112 | "safe-buffer": "~5.1.1", 113 | "string_decoder": "~1.1.1", 114 | "util-deprecate": "~1.0.1" 115 | } 116 | }, 117 | "node_modules/concat-stream/node_modules/string_decoder": { 118 | "version": "1.1.1", 119 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 120 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 121 | "dependencies": { 122 | "safe-buffer": "~5.1.0" 123 | } 124 | }, 125 | "node_modules/content-disposition": { 126 | "version": "0.5.3", 127 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 128 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 129 | "dependencies": { 130 | "safe-buffer": "5.1.2" 131 | }, 132 | "engines": { 133 | "node": ">= 0.6" 134 | } 135 | }, 136 | "node_modules/content-type": { 137 | "version": "1.0.4", 138 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 139 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", 140 | "engines": { 141 | "node": ">= 0.6" 142 | } 143 | }, 144 | "node_modules/cookie": { 145 | "version": "0.4.0", 146 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 147 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", 148 | "engines": { 149 | "node": ">= 0.6" 150 | } 151 | }, 152 | "node_modules/cookie-signature": { 153 | "version": "1.0.6", 154 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 155 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 156 | }, 157 | "node_modules/core-util-is": { 158 | "version": "1.0.3", 159 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", 160 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" 161 | }, 162 | "node_modules/debug": { 163 | "version": "2.6.9", 164 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 165 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 166 | "dependencies": { 167 | "ms": "2.0.0" 168 | } 169 | }, 170 | "node_modules/depd": { 171 | "version": "1.1.2", 172 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 173 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", 174 | "engines": { 175 | "node": ">= 0.6" 176 | } 177 | }, 178 | "node_modules/destroy": { 179 | "version": "1.0.4", 180 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 181 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 182 | }, 183 | "node_modules/dicer": { 184 | "version": "0.2.5", 185 | "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", 186 | "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", 187 | "dependencies": { 188 | "readable-stream": "1.1.x", 189 | "streamsearch": "0.1.2" 190 | }, 191 | "engines": { 192 | "node": ">=0.8.0" 193 | } 194 | }, 195 | "node_modules/ee-first": { 196 | "version": "1.1.1", 197 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 198 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 199 | }, 200 | "node_modules/encodeurl": { 201 | "version": "1.0.2", 202 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 203 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 204 | "engines": { 205 | "node": ">= 0.8" 206 | } 207 | }, 208 | "node_modules/escape-html": { 209 | "version": "1.0.3", 210 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 211 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 212 | }, 213 | "node_modules/etag": { 214 | "version": "1.8.1", 215 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 216 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", 217 | "engines": { 218 | "node": ">= 0.6" 219 | } 220 | }, 221 | "node_modules/express": { 222 | "version": "4.17.1", 223 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 224 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 225 | "dependencies": { 226 | "accepts": "~1.3.7", 227 | "array-flatten": "1.1.1", 228 | "body-parser": "1.19.0", 229 | "content-disposition": "0.5.3", 230 | "content-type": "~1.0.4", 231 | "cookie": "0.4.0", 232 | "cookie-signature": "1.0.6", 233 | "debug": "2.6.9", 234 | "depd": "~1.1.2", 235 | "encodeurl": "~1.0.2", 236 | "escape-html": "~1.0.3", 237 | "etag": "~1.8.1", 238 | "finalhandler": "~1.1.2", 239 | "fresh": "0.5.2", 240 | "merge-descriptors": "1.0.1", 241 | "methods": "~1.1.2", 242 | "on-finished": "~2.3.0", 243 | "parseurl": "~1.3.3", 244 | "path-to-regexp": "0.1.7", 245 | "proxy-addr": "~2.0.5", 246 | "qs": "6.7.0", 247 | "range-parser": "~1.2.1", 248 | "safe-buffer": "5.1.2", 249 | "send": "0.17.1", 250 | "serve-static": "1.14.1", 251 | "setprototypeof": "1.1.1", 252 | "statuses": "~1.5.0", 253 | "type-is": "~1.6.18", 254 | "utils-merge": "1.0.1", 255 | "vary": "~1.1.2" 256 | }, 257 | "engines": { 258 | "node": ">= 0.10.0" 259 | } 260 | }, 261 | "node_modules/finalhandler": { 262 | "version": "1.1.2", 263 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 264 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 265 | "dependencies": { 266 | "debug": "2.6.9", 267 | "encodeurl": "~1.0.2", 268 | "escape-html": "~1.0.3", 269 | "on-finished": "~2.3.0", 270 | "parseurl": "~1.3.3", 271 | "statuses": "~1.5.0", 272 | "unpipe": "~1.0.0" 273 | }, 274 | "engines": { 275 | "node": ">= 0.8" 276 | } 277 | }, 278 | "node_modules/forwarded": { 279 | "version": "0.2.0", 280 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 281 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 282 | "engines": { 283 | "node": ">= 0.6" 284 | } 285 | }, 286 | "node_modules/fresh": { 287 | "version": "0.5.2", 288 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 289 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", 290 | "engines": { 291 | "node": ">= 0.6" 292 | } 293 | }, 294 | "node_modules/http-errors": { 295 | "version": "1.7.2", 296 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 297 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 298 | "dependencies": { 299 | "depd": "~1.1.2", 300 | "inherits": "2.0.3", 301 | "setprototypeof": "1.1.1", 302 | "statuses": ">= 1.5.0 < 2", 303 | "toidentifier": "1.0.0" 304 | }, 305 | "engines": { 306 | "node": ">= 0.6" 307 | } 308 | }, 309 | "node_modules/iconv-lite": { 310 | "version": "0.4.24", 311 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 312 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 313 | "dependencies": { 314 | "safer-buffer": ">= 2.1.2 < 3" 315 | }, 316 | "engines": { 317 | "node": ">=0.10.0" 318 | } 319 | }, 320 | "node_modules/inherits": { 321 | "version": "2.0.3", 322 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 323 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 324 | }, 325 | "node_modules/ipaddr.js": { 326 | "version": "1.9.1", 327 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 328 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 329 | "engines": { 330 | "node": ">= 0.10" 331 | } 332 | }, 333 | "node_modules/isarray": { 334 | "version": "0.0.1", 335 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 336 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 337 | }, 338 | "node_modules/media-typer": { 339 | "version": "0.3.0", 340 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 341 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", 342 | "engines": { 343 | "node": ">= 0.6" 344 | } 345 | }, 346 | "node_modules/merge-descriptors": { 347 | "version": "1.0.1", 348 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 349 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 350 | }, 351 | "node_modules/methods": { 352 | "version": "1.1.2", 353 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 354 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", 355 | "engines": { 356 | "node": ">= 0.6" 357 | } 358 | }, 359 | "node_modules/mime": { 360 | "version": "1.6.0", 361 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 362 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 363 | "bin": { 364 | "mime": "cli.js" 365 | }, 366 | "engines": { 367 | "node": ">=4" 368 | } 369 | }, 370 | "node_modules/mime-db": { 371 | "version": "1.51.0", 372 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", 373 | "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==", 374 | "engines": { 375 | "node": ">= 0.6" 376 | } 377 | }, 378 | "node_modules/mime-types": { 379 | "version": "2.1.34", 380 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", 381 | "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", 382 | "dependencies": { 383 | "mime-db": "1.51.0" 384 | }, 385 | "engines": { 386 | "node": ">= 0.6" 387 | } 388 | }, 389 | "node_modules/minimist": { 390 | "version": "1.2.5", 391 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 392 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" 393 | }, 394 | "node_modules/mkdirp": { 395 | "version": "0.5.5", 396 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 397 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 398 | "dependencies": { 399 | "minimist": "^1.2.5" 400 | }, 401 | "bin": { 402 | "mkdirp": "bin/cmd.js" 403 | } 404 | }, 405 | "node_modules/ms": { 406 | "version": "2.0.0", 407 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 408 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 409 | }, 410 | "node_modules/multer": { 411 | "version": "1.4.3", 412 | "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.3.tgz", 413 | "integrity": "sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg==", 414 | "dependencies": { 415 | "append-field": "^1.0.0", 416 | "busboy": "^0.2.11", 417 | "concat-stream": "^1.5.2", 418 | "mkdirp": "^0.5.4", 419 | "object-assign": "^4.1.1", 420 | "on-finished": "^2.3.0", 421 | "type-is": "^1.6.4", 422 | "xtend": "^4.0.0" 423 | }, 424 | "engines": { 425 | "node": ">= 0.10.0" 426 | } 427 | }, 428 | "node_modules/negotiator": { 429 | "version": "0.6.2", 430 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 431 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", 432 | "engines": { 433 | "node": ">= 0.6" 434 | } 435 | }, 436 | "node_modules/object-assign": { 437 | "version": "4.1.1", 438 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 439 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 440 | "engines": { 441 | "node": ">=0.10.0" 442 | } 443 | }, 444 | "node_modules/on-finished": { 445 | "version": "2.3.0", 446 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 447 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 448 | "dependencies": { 449 | "ee-first": "1.1.1" 450 | }, 451 | "engines": { 452 | "node": ">= 0.8" 453 | } 454 | }, 455 | "node_modules/parseurl": { 456 | "version": "1.3.3", 457 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 458 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 459 | "engines": { 460 | "node": ">= 0.8" 461 | } 462 | }, 463 | "node_modules/path-to-regexp": { 464 | "version": "0.1.7", 465 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 466 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 467 | }, 468 | "node_modules/process-nextick-args": { 469 | "version": "2.0.1", 470 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 471 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 472 | }, 473 | "node_modules/proxy-addr": { 474 | "version": "2.0.7", 475 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 476 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 477 | "dependencies": { 478 | "forwarded": "0.2.0", 479 | "ipaddr.js": "1.9.1" 480 | }, 481 | "engines": { 482 | "node": ">= 0.10" 483 | } 484 | }, 485 | "node_modules/qs": { 486 | "version": "6.7.0", 487 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 488 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", 489 | "engines": { 490 | "node": ">=0.6" 491 | } 492 | }, 493 | "node_modules/range-parser": { 494 | "version": "1.2.1", 495 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 496 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 497 | "engines": { 498 | "node": ">= 0.6" 499 | } 500 | }, 501 | "node_modules/raw-body": { 502 | "version": "2.4.0", 503 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 504 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 505 | "dependencies": { 506 | "bytes": "3.1.0", 507 | "http-errors": "1.7.2", 508 | "iconv-lite": "0.4.24", 509 | "unpipe": "1.0.0" 510 | }, 511 | "engines": { 512 | "node": ">= 0.8" 513 | } 514 | }, 515 | "node_modules/readable-stream": { 516 | "version": "1.1.14", 517 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 518 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 519 | "dependencies": { 520 | "core-util-is": "~1.0.0", 521 | "inherits": "~2.0.1", 522 | "isarray": "0.0.1", 523 | "string_decoder": "~0.10.x" 524 | } 525 | }, 526 | "node_modules/safe-buffer": { 527 | "version": "5.1.2", 528 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 529 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 530 | }, 531 | "node_modules/safer-buffer": { 532 | "version": "2.1.2", 533 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 534 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 535 | }, 536 | "node_modules/send": { 537 | "version": "0.17.1", 538 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 539 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 540 | "dependencies": { 541 | "debug": "2.6.9", 542 | "depd": "~1.1.2", 543 | "destroy": "~1.0.4", 544 | "encodeurl": "~1.0.2", 545 | "escape-html": "~1.0.3", 546 | "etag": "~1.8.1", 547 | "fresh": "0.5.2", 548 | "http-errors": "~1.7.2", 549 | "mime": "1.6.0", 550 | "ms": "2.1.1", 551 | "on-finished": "~2.3.0", 552 | "range-parser": "~1.2.1", 553 | "statuses": "~1.5.0" 554 | }, 555 | "engines": { 556 | "node": ">= 0.8.0" 557 | } 558 | }, 559 | "node_modules/send/node_modules/ms": { 560 | "version": "2.1.1", 561 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 562 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 563 | }, 564 | "node_modules/serve-static": { 565 | "version": "1.14.1", 566 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 567 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 568 | "dependencies": { 569 | "encodeurl": "~1.0.2", 570 | "escape-html": "~1.0.3", 571 | "parseurl": "~1.3.3", 572 | "send": "0.17.1" 573 | }, 574 | "engines": { 575 | "node": ">= 0.8.0" 576 | } 577 | }, 578 | "node_modules/setprototypeof": { 579 | "version": "1.1.1", 580 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 581 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 582 | }, 583 | "node_modules/statuses": { 584 | "version": "1.5.0", 585 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 586 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", 587 | "engines": { 588 | "node": ">= 0.6" 589 | } 590 | }, 591 | "node_modules/streamsearch": { 592 | "version": "0.1.2", 593 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", 594 | "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", 595 | "engines": { 596 | "node": ">=0.8.0" 597 | } 598 | }, 599 | "node_modules/string_decoder": { 600 | "version": "0.10.31", 601 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 602 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" 603 | }, 604 | "node_modules/toidentifier": { 605 | "version": "1.0.0", 606 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 607 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", 608 | "engines": { 609 | "node": ">=0.6" 610 | } 611 | }, 612 | "node_modules/type-is": { 613 | "version": "1.6.18", 614 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 615 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 616 | "dependencies": { 617 | "media-typer": "0.3.0", 618 | "mime-types": "~2.1.24" 619 | }, 620 | "engines": { 621 | "node": ">= 0.6" 622 | } 623 | }, 624 | "node_modules/typedarray": { 625 | "version": "0.0.6", 626 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 627 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" 628 | }, 629 | "node_modules/unpipe": { 630 | "version": "1.0.0", 631 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 632 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", 633 | "engines": { 634 | "node": ">= 0.8" 635 | } 636 | }, 637 | "node_modules/util-deprecate": { 638 | "version": "1.0.2", 639 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 640 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 641 | }, 642 | "node_modules/utils-merge": { 643 | "version": "1.0.1", 644 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 645 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", 646 | "engines": { 647 | "node": ">= 0.4.0" 648 | } 649 | }, 650 | "node_modules/vary": { 651 | "version": "1.1.2", 652 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 653 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", 654 | "engines": { 655 | "node": ">= 0.8" 656 | } 657 | }, 658 | "node_modules/xtend": { 659 | "version": "4.0.2", 660 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 661 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", 662 | "engines": { 663 | "node": ">=0.4" 664 | } 665 | }, 666 | "node_modules/yaml": { 667 | "version": "1.10.2", 668 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", 669 | "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", 670 | "engines": { 671 | "node": ">= 6" 672 | } 673 | } 674 | }, 675 | "dependencies": { 676 | "accepts": { 677 | "version": "1.3.7", 678 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 679 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 680 | "requires": { 681 | "mime-types": "~2.1.24", 682 | "negotiator": "0.6.2" 683 | } 684 | }, 685 | "append-field": { 686 | "version": "1.0.0", 687 | "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", 688 | "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" 689 | }, 690 | "array-flatten": { 691 | "version": "1.1.1", 692 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 693 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 694 | }, 695 | "body-parser": { 696 | "version": "1.19.0", 697 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 698 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 699 | "requires": { 700 | "bytes": "3.1.0", 701 | "content-type": "~1.0.4", 702 | "debug": "2.6.9", 703 | "depd": "~1.1.2", 704 | "http-errors": "1.7.2", 705 | "iconv-lite": "0.4.24", 706 | "on-finished": "~2.3.0", 707 | "qs": "6.7.0", 708 | "raw-body": "2.4.0", 709 | "type-is": "~1.6.17" 710 | } 711 | }, 712 | "buffer-from": { 713 | "version": "1.1.2", 714 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 715 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" 716 | }, 717 | "busboy": { 718 | "version": "0.2.14", 719 | "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", 720 | "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", 721 | "requires": { 722 | "dicer": "0.2.5", 723 | "readable-stream": "1.1.x" 724 | } 725 | }, 726 | "bytes": { 727 | "version": "3.1.0", 728 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 729 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 730 | }, 731 | "concat-stream": { 732 | "version": "1.6.2", 733 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 734 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 735 | "requires": { 736 | "buffer-from": "^1.0.0", 737 | "inherits": "^2.0.3", 738 | "readable-stream": "^2.2.2", 739 | "typedarray": "^0.0.6" 740 | }, 741 | "dependencies": { 742 | "isarray": { 743 | "version": "1.0.0", 744 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 745 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 746 | }, 747 | "readable-stream": { 748 | "version": "2.3.7", 749 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 750 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 751 | "requires": { 752 | "core-util-is": "~1.0.0", 753 | "inherits": "~2.0.3", 754 | "isarray": "~1.0.0", 755 | "process-nextick-args": "~2.0.0", 756 | "safe-buffer": "~5.1.1", 757 | "string_decoder": "~1.1.1", 758 | "util-deprecate": "~1.0.1" 759 | } 760 | }, 761 | "string_decoder": { 762 | "version": "1.1.1", 763 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 764 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 765 | "requires": { 766 | "safe-buffer": "~5.1.0" 767 | } 768 | } 769 | } 770 | }, 771 | "content-disposition": { 772 | "version": "0.5.3", 773 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 774 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 775 | "requires": { 776 | "safe-buffer": "5.1.2" 777 | } 778 | }, 779 | "content-type": { 780 | "version": "1.0.4", 781 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 782 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 783 | }, 784 | "cookie": { 785 | "version": "0.4.0", 786 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 787 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 788 | }, 789 | "cookie-signature": { 790 | "version": "1.0.6", 791 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 792 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 793 | }, 794 | "core-util-is": { 795 | "version": "1.0.3", 796 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", 797 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" 798 | }, 799 | "debug": { 800 | "version": "2.6.9", 801 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 802 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 803 | "requires": { 804 | "ms": "2.0.0" 805 | } 806 | }, 807 | "depd": { 808 | "version": "1.1.2", 809 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 810 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 811 | }, 812 | "destroy": { 813 | "version": "1.0.4", 814 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 815 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 816 | }, 817 | "dicer": { 818 | "version": "0.2.5", 819 | "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", 820 | "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", 821 | "requires": { 822 | "readable-stream": "1.1.x", 823 | "streamsearch": "0.1.2" 824 | } 825 | }, 826 | "ee-first": { 827 | "version": "1.1.1", 828 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 829 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 830 | }, 831 | "encodeurl": { 832 | "version": "1.0.2", 833 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 834 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 835 | }, 836 | "escape-html": { 837 | "version": "1.0.3", 838 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 839 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 840 | }, 841 | "etag": { 842 | "version": "1.8.1", 843 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 844 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 845 | }, 846 | "express": { 847 | "version": "4.17.1", 848 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 849 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 850 | "requires": { 851 | "accepts": "~1.3.7", 852 | "array-flatten": "1.1.1", 853 | "body-parser": "1.19.0", 854 | "content-disposition": "0.5.3", 855 | "content-type": "~1.0.4", 856 | "cookie": "0.4.0", 857 | "cookie-signature": "1.0.6", 858 | "debug": "2.6.9", 859 | "depd": "~1.1.2", 860 | "encodeurl": "~1.0.2", 861 | "escape-html": "~1.0.3", 862 | "etag": "~1.8.1", 863 | "finalhandler": "~1.1.2", 864 | "fresh": "0.5.2", 865 | "merge-descriptors": "1.0.1", 866 | "methods": "~1.1.2", 867 | "on-finished": "~2.3.0", 868 | "parseurl": "~1.3.3", 869 | "path-to-regexp": "0.1.7", 870 | "proxy-addr": "~2.0.5", 871 | "qs": "6.7.0", 872 | "range-parser": "~1.2.1", 873 | "safe-buffer": "5.1.2", 874 | "send": "0.17.1", 875 | "serve-static": "1.14.1", 876 | "setprototypeof": "1.1.1", 877 | "statuses": "~1.5.0", 878 | "type-is": "~1.6.18", 879 | "utils-merge": "1.0.1", 880 | "vary": "~1.1.2" 881 | } 882 | }, 883 | "finalhandler": { 884 | "version": "1.1.2", 885 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 886 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 887 | "requires": { 888 | "debug": "2.6.9", 889 | "encodeurl": "~1.0.2", 890 | "escape-html": "~1.0.3", 891 | "on-finished": "~2.3.0", 892 | "parseurl": "~1.3.3", 893 | "statuses": "~1.5.0", 894 | "unpipe": "~1.0.0" 895 | } 896 | }, 897 | "forwarded": { 898 | "version": "0.2.0", 899 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 900 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 901 | }, 902 | "fresh": { 903 | "version": "0.5.2", 904 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 905 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 906 | }, 907 | "http-errors": { 908 | "version": "1.7.2", 909 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 910 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 911 | "requires": { 912 | "depd": "~1.1.2", 913 | "inherits": "2.0.3", 914 | "setprototypeof": "1.1.1", 915 | "statuses": ">= 1.5.0 < 2", 916 | "toidentifier": "1.0.0" 917 | } 918 | }, 919 | "iconv-lite": { 920 | "version": "0.4.24", 921 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 922 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 923 | "requires": { 924 | "safer-buffer": ">= 2.1.2 < 3" 925 | } 926 | }, 927 | "inherits": { 928 | "version": "2.0.3", 929 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 930 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 931 | }, 932 | "ipaddr.js": { 933 | "version": "1.9.1", 934 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 935 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 936 | }, 937 | "isarray": { 938 | "version": "0.0.1", 939 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 940 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 941 | }, 942 | "media-typer": { 943 | "version": "0.3.0", 944 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 945 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 946 | }, 947 | "merge-descriptors": { 948 | "version": "1.0.1", 949 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 950 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 951 | }, 952 | "methods": { 953 | "version": "1.1.2", 954 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 955 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 956 | }, 957 | "mime": { 958 | "version": "1.6.0", 959 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 960 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 961 | }, 962 | "mime-db": { 963 | "version": "1.51.0", 964 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz", 965 | "integrity": "sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" 966 | }, 967 | "mime-types": { 968 | "version": "2.1.34", 969 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz", 970 | "integrity": "sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==", 971 | "requires": { 972 | "mime-db": "1.51.0" 973 | } 974 | }, 975 | "minimist": { 976 | "version": "1.2.5", 977 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 978 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" 979 | }, 980 | "mkdirp": { 981 | "version": "0.5.5", 982 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 983 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 984 | "requires": { 985 | "minimist": "^1.2.5" 986 | } 987 | }, 988 | "ms": { 989 | "version": "2.0.0", 990 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 991 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 992 | }, 993 | "multer": { 994 | "version": "1.4.3", 995 | "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.3.tgz", 996 | "integrity": "sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg==", 997 | "requires": { 998 | "append-field": "^1.0.0", 999 | "busboy": "^0.2.11", 1000 | "concat-stream": "^1.5.2", 1001 | "mkdirp": "^0.5.4", 1002 | "object-assign": "^4.1.1", 1003 | "on-finished": "^2.3.0", 1004 | "type-is": "^1.6.4", 1005 | "xtend": "^4.0.0" 1006 | } 1007 | }, 1008 | "negotiator": { 1009 | "version": "0.6.2", 1010 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 1011 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 1012 | }, 1013 | "object-assign": { 1014 | "version": "4.1.1", 1015 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1016 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 1017 | }, 1018 | "on-finished": { 1019 | "version": "2.3.0", 1020 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1021 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1022 | "requires": { 1023 | "ee-first": "1.1.1" 1024 | } 1025 | }, 1026 | "parseurl": { 1027 | "version": "1.3.3", 1028 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1029 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 1030 | }, 1031 | "path-to-regexp": { 1032 | "version": "0.1.7", 1033 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1034 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 1035 | }, 1036 | "process-nextick-args": { 1037 | "version": "2.0.1", 1038 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 1039 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 1040 | }, 1041 | "proxy-addr": { 1042 | "version": "2.0.7", 1043 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1044 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1045 | "requires": { 1046 | "forwarded": "0.2.0", 1047 | "ipaddr.js": "1.9.1" 1048 | } 1049 | }, 1050 | "qs": { 1051 | "version": "6.7.0", 1052 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 1053 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 1054 | }, 1055 | "range-parser": { 1056 | "version": "1.2.1", 1057 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1058 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 1059 | }, 1060 | "raw-body": { 1061 | "version": "2.4.0", 1062 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 1063 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 1064 | "requires": { 1065 | "bytes": "3.1.0", 1066 | "http-errors": "1.7.2", 1067 | "iconv-lite": "0.4.24", 1068 | "unpipe": "1.0.0" 1069 | } 1070 | }, 1071 | "readable-stream": { 1072 | "version": "1.1.14", 1073 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 1074 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 1075 | "requires": { 1076 | "core-util-is": "~1.0.0", 1077 | "inherits": "~2.0.1", 1078 | "isarray": "0.0.1", 1079 | "string_decoder": "~0.10.x" 1080 | } 1081 | }, 1082 | "safe-buffer": { 1083 | "version": "5.1.2", 1084 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1085 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1086 | }, 1087 | "safer-buffer": { 1088 | "version": "2.1.2", 1089 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1090 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1091 | }, 1092 | "send": { 1093 | "version": "0.17.1", 1094 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 1095 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 1096 | "requires": { 1097 | "debug": "2.6.9", 1098 | "depd": "~1.1.2", 1099 | "destroy": "~1.0.4", 1100 | "encodeurl": "~1.0.2", 1101 | "escape-html": "~1.0.3", 1102 | "etag": "~1.8.1", 1103 | "fresh": "0.5.2", 1104 | "http-errors": "~1.7.2", 1105 | "mime": "1.6.0", 1106 | "ms": "2.1.1", 1107 | "on-finished": "~2.3.0", 1108 | "range-parser": "~1.2.1", 1109 | "statuses": "~1.5.0" 1110 | }, 1111 | "dependencies": { 1112 | "ms": { 1113 | "version": "2.1.1", 1114 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 1115 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 1116 | } 1117 | } 1118 | }, 1119 | "serve-static": { 1120 | "version": "1.14.1", 1121 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 1122 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 1123 | "requires": { 1124 | "encodeurl": "~1.0.2", 1125 | "escape-html": "~1.0.3", 1126 | "parseurl": "~1.3.3", 1127 | "send": "0.17.1" 1128 | } 1129 | }, 1130 | "setprototypeof": { 1131 | "version": "1.1.1", 1132 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 1133 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 1134 | }, 1135 | "statuses": { 1136 | "version": "1.5.0", 1137 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 1138 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 1139 | }, 1140 | "streamsearch": { 1141 | "version": "0.1.2", 1142 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", 1143 | "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" 1144 | }, 1145 | "string_decoder": { 1146 | "version": "0.10.31", 1147 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 1148 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" 1149 | }, 1150 | "toidentifier": { 1151 | "version": "1.0.0", 1152 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 1153 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 1154 | }, 1155 | "type-is": { 1156 | "version": "1.6.18", 1157 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 1158 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 1159 | "requires": { 1160 | "media-typer": "0.3.0", 1161 | "mime-types": "~2.1.24" 1162 | } 1163 | }, 1164 | "typedarray": { 1165 | "version": "0.0.6", 1166 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 1167 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" 1168 | }, 1169 | "unpipe": { 1170 | "version": "1.0.0", 1171 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1172 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 1173 | }, 1174 | "util-deprecate": { 1175 | "version": "1.0.2", 1176 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1177 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 1178 | }, 1179 | "utils-merge": { 1180 | "version": "1.0.1", 1181 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1182 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 1183 | }, 1184 | "vary": { 1185 | "version": "1.1.2", 1186 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1187 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 1188 | }, 1189 | "xtend": { 1190 | "version": "4.0.2", 1191 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 1192 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" 1193 | }, 1194 | "yaml": { 1195 | "version": "1.10.2", 1196 | "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", 1197 | "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" 1198 | } 1199 | } 1200 | } 1201 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "open-alpr-http-wrapper", 3 | "version": "0.2.1", 4 | "main": "index.js", 5 | "type": "module", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "buildImage": "docker build -t sclaflin/open-alpr-http-wrapper:`npm pkg get version | sed 's/\"//g'` .", 9 | "start": "/usr/bin/node index.js" 10 | }, 11 | "author": "Sean Claflin", 12 | "license": "MIT", 13 | "description": "A thin wrapper arount the OpenALPR cli program", 14 | "dependencies": { 15 | "express": "^4.17.1", 16 | "multer": "^1.4.3", 17 | "yaml": "^1.10.2" 18 | }, 19 | "directories": { 20 | "example": "examples", 21 | "lib": "lib" 22 | }, 23 | "devDependencies": {}, 24 | "repository": { 25 | "type": "git", 26 | "url": "git+https://github.com/sclaflin/OpenALPR-HTTP-Wrapper.git" 27 | }, 28 | "bugs": { 29 | "url": "https://github.com/sclaflin/OpenALPR-HTTP-Wrapper/issues" 30 | }, 31 | "homepage": "https://github.com/sclaflin/OpenALPR-HTTP-Wrapper#readme" 32 | } 33 | --------------------------------------------------------------------------------