├── README.md ├── assets ├── NanumBarunGothic.otf └── work.pdf ├── doc └── example.png ├── index.js ├── package-lock.json ├── package.json └── public └── index.html /README.md: -------------------------------------------------------------------------------- 1 | # workDiary 2 | 3 | 재택근무 pdf form을 채워줍니다 4 | 5 | ## Install 6 | ``` 7 | npm install -g https://github.com/jen6/workDiary 8 | ``` 9 | 10 | ## Usage 11 | 12 | ### 기본 사용법 13 | [spread sheet](https://abit.ly/workdiary)로 들어가서 사본을 만든 다음 각 칸을 채워 줍니다. 14 | 날자는 반드시 월~금 사이 날자로 해주세요. 휴일이 끼었을 경우 그냥 휴일이라고 써놓읍시다. 15 | 16 | 다 작성 한 후 csv로 export 해서 저장해줍니다. 17 | ``` 18 | $ workDiary --csv csv.csv 19 | ``` 20 | 21 | ### custom template option 22 | 회사 내에서 써야하는 pdf template이 바뀌었는데 전체적으로 위치가 밀린경우 custom template기능을 사용하면 됩니다. 23 | `-template` 옵션으로 template pdf를 지정해주시고 `--dx`, `--dy` 옵션으로 좌표를 조정해줍니다. 24 | 전체적인 틀이 달라졌다면 사용할 수 없습니다. 안채우고 싶은 칸들은 csv상에서 비워주세요 25 | ``` 26 | $ workDiary --csv csv.csv --template template.pdf --dx 0 --dy 30 27 | ``` 28 | 29 | 30 | 위 커맨드를 쉘에서 실행하면 "이름_시작일_종료일.pdf" 의 형태로 결과물이 나옵니다. 31 | E.g. `손건_8_17_8_21.pdf` 32 | 33 | ![](doc/example.png) 34 | -------------------------------------------------------------------------------- /assets/NanumBarunGothic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jen6/workDiary/bb7852e2842fa1aaf392ad1a85469512424c763d/assets/NanumBarunGothic.otf -------------------------------------------------------------------------------- /assets/work.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jen6/workDiary/bb7852e2842fa1aaf392ad1a85469512424c763d/assets/work.pdf -------------------------------------------------------------------------------- /doc/example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jen6/workDiary/bb7852e2842fa1aaf392ad1a85469512424c763d/doc/example.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const { PDFDocument, StandardFonts} = require('pdf-lib'); 3 | const fontkit = require('@pdf-lib/fontkit'); 4 | const fs = require('fs'); 5 | const parse = require('csv-parse/lib/sync'); 6 | const open = require('open'); 7 | const yargs = require('yargs/yargs') 8 | const { hideBin } = require('yargs/helpers') 9 | var bodyParser = require('body-parser'); 10 | var multer = require('multer'); 11 | var upload = multer(); 12 | const express = require('express') 13 | var path = require('path'); 14 | 15 | var appDir = path.dirname(require.main.filename); 16 | 17 | 18 | class Point { 19 | constructor(x, y) { 20 | this.x = x; 21 | this.y = y; 22 | } 23 | } 24 | 25 | const namePoint = new Point(153, 720); 26 | const birthPoint = new Point(294, 720); 27 | const milStartPoint = new Point(440, 720); 28 | const companyPoint = new Point(230, 680); 29 | const reasonPoint = new Point(147, 643); 30 | const phonePoint = new Point(282, 643); 31 | const durationPoint = new Point(455, 643); 32 | const workPlacePoint = new Point(200, 603); 33 | const workStartDatePoint = new Point(101, 534); 34 | const workStartTimePoint = new Point(201, 542); 35 | const workEndTimePoint = new Point(201, 515); 36 | const workMemoPoint = new Point(316, 539); 37 | const chairmanPoint = new Point(327, 100); 38 | const writerPoint = new Point(327, 120); 39 | const signYearPoint = new Point(410, 155); 40 | const signMonthPoint = new Point(455, 155); 41 | const signDatePoint = new Point(489, 155); 42 | const signSignaturePoint = new Point(410, 95); 43 | 44 | class UserInfo { 45 | constructor(name, birth, milStartDate, phoneNumber, workPlace, companyName, chairmanName, reason) { 46 | this.name = name; 47 | this.birth = birth; 48 | this.milStartDate = milStartDate; 49 | this.phoneNumber = phoneNumber; 50 | this.workPlace = workPlace; 51 | this.companyName = companyName; 52 | this.chairmanName = chairmanName; 53 | this.reason = reason; 54 | } 55 | } 56 | 57 | class WorkInfo { 58 | constructor(date, workMemo, workStartTime = "10:00", workEndTime="19:00") { 59 | this.date = date; 60 | this.workMemo = workMemo; 61 | this.workStartTime = workStartTime; 62 | this.workEndTime = workEndTime; 63 | } 64 | } 65 | 66 | class WorkInfos { 67 | constructor(startDate, endDate, workInfoList) { 68 | this.startDate = startDate; 69 | this.endDate = endDate; 70 | this.workInfoList = workInfoList; 71 | } 72 | } 73 | 74 | const DefaultPdfTemplatePath = appDir + "/assets/work.pdf" 75 | const pdfTemplate = fs.readFileSync(appDir + "/assets/work.pdf") 76 | const fontFile = fs.readFileSync(appDir + "/assets/NanumBarunGothic.otf") 77 | 78 | async function drawUserSignature(page, signature, adjustX, adjustY) { 79 | const scale = signature.scale(0.2); 80 | page.drawImage(signature, { 81 | x: signSignaturePoint.x + adjustX, // firstPage.getWidth() / 2 - 150, 82 | y: signSignaturePoint.y + adjustY, // - pngDims.height, 83 | width: scale.width, 84 | height: scale.height, 85 | }) 86 | return page 87 | } 88 | 89 | async function drawUserInfo(page, userInfo, adjustX, adjustY) { 90 | var fontSize = 10 91 | page.drawText(userInfo.name, { 92 | x: namePoint.x + adjustX, 93 | y: namePoint.y - fontSize + adjustY, 94 | size: fontSize, 95 | }) 96 | page.drawText(userInfo.name, { 97 | x: writerPoint.x + adjustX, 98 | y: writerPoint.y - fontSize + adjustY, 99 | size: fontSize, 100 | }) 101 | page.drawText(userInfo.companyName, { 102 | x: companyPoint.x + adjustX, 103 | y: companyPoint.y - fontSize + adjustY, 104 | size: fontSize, 105 | }) 106 | page.drawText(userInfo.birth, { 107 | x: birthPoint.x + adjustX, 108 | y: birthPoint.y - fontSize + adjustY, 109 | size: fontSize, 110 | }) 111 | page.drawText(userInfo.milStartDate, { 112 | x: milStartPoint.x + adjustX, 113 | y: milStartPoint.y - fontSize + adjustY, 114 | size: fontSize, 115 | }) 116 | page.drawText(userInfo.phoneNumber, { 117 | x: phonePoint.x + adjustX, 118 | y: phonePoint.y - fontSize + adjustY, 119 | size: fontSize, 120 | }) 121 | page.drawText(userInfo.workPlace, { 122 | x: workPlacePoint.x + adjustX, 123 | y: workPlacePoint.y - fontSize + adjustY, 124 | size: fontSize, 125 | }) 126 | page.drawText(userInfo.chairmanName, { 127 | x: chairmanPoint.x + adjustX, 128 | y: chairmanPoint.y - fontSize + adjustY, 129 | size: fontSize, 130 | }) 131 | fontSize = 8 132 | page.drawText(userInfo.reason, { 133 | x: reasonPoint.x + adjustX, 134 | y: reasonPoint.y - fontSize + adjustY, 135 | size: fontSize, 136 | }) 137 | return page; 138 | } 139 | 140 | async function createSheet(pdfTemplatePath, fileName, userInfo, workInfos, year, imgData, adjustX, adjustY) { 141 | const pdfDoc = await PDFDocument.load(fs.readFileSync(pdfTemplatePath)) 142 | 143 | pdfDoc.registerFontkit(fontkit); 144 | const font = await pdfDoc.embedFont(fontFile) 145 | const signature = await pdfDoc.embedPng(imgData) 146 | 147 | var page = pdfDoc.getPage(0) 148 | page.setFont(font); 149 | 150 | page = await drawUserSignature(page, signature, adjustX, adjustY); 151 | page = await drawUserInfo(page, userInfo, adjustX, adjustY); 152 | 153 | const workInfoLen = workInfos.workInfoList.length 154 | const workDuration = workInfos.workInfoList[0].date + "~" + workInfos.workInfoList[workInfoLen-1].date 155 | console.log("Generating " + workDuration + " pdf result") 156 | 157 | var fontSize = 8 158 | page.drawText(workDuration, { 159 | x: durationPoint.x + adjustX, 160 | y: durationPoint.y - fontSize + adjustY, 161 | size: fontSize, 162 | }) 163 | 164 | const splited = workInfos.workInfoList[workInfoLen-1].date.split('/') 165 | page.drawText(year, { 166 | x: signYearPoint.x + adjustX, 167 | y: signYearPoint.y - fontSize + adjustY, 168 | size: fontSize, 169 | }) 170 | page.drawText(splited[0], { 171 | x: signMonthPoint.x + adjustX, 172 | y: signMonthPoint.y - fontSize + adjustY, 173 | size: fontSize, 174 | }) 175 | page.drawText(splited[1], { 176 | x: signDatePoint.x + adjustX, 177 | y: signDatePoint.y - fontSize + adjustY, 178 | size: fontSize, 179 | }) 180 | 181 | for (var i = 0; i < workInfos.workInfoList.length; i++) { 182 | fontSize = 8 183 | const height = 63 184 | var workInfo = workInfos.workInfoList[i] 185 | page.drawText(workInfo.date, { 186 | x: workStartDatePoint.x + adjustX, 187 | y: workStartDatePoint.y - fontSize - height*i + adjustY, 188 | size: fontSize, 189 | }) 190 | page.drawText(workInfo.workMemo, { 191 | x: workMemoPoint.x + adjustX, 192 | y: workMemoPoint.y - fontSize - height*i + adjustY, 193 | size: fontSize, 194 | }) 195 | 196 | fontSize = 6 197 | page.drawText(workInfo.workStartTime, { 198 | x: workStartTimePoint.x + adjustX, 199 | y: workStartTimePoint.y - fontSize - height*i + adjustY, 200 | size: fontSize, 201 | }) 202 | page.drawText(workInfo.workEndTime, { 203 | x: workEndTimePoint.x + adjustX, 204 | y: workEndTimePoint.y - fontSize - height*i + adjustY, 205 | size: fontSize, 206 | }) 207 | } 208 | fs.writeFileSync(fileName, await pdfDoc.save()); 209 | } 210 | 211 | async function parseCSV(csvFileName) { 212 | const file = fs.readFileSync(csvFileName) 213 | records = parse(file.toString(), {columns: false, skip_empty_lines:false}) 214 | const userInfo = new UserInfo( 215 | name=records[0][1], 216 | birth=records[1][1], 217 | milStartDate=records[2][1], 218 | phoneNumber=records[3][1], 219 | workPlace=records[4][1], 220 | companyName=records[5][1], 221 | chairmanName=records[6][1], 222 | reason=records[7][1], 223 | ) 224 | var i = 0; 225 | var workInfos = []; 226 | for(i = 8; i < records.length; i+=5) { 227 | const workWindow = records.slice(i, i+5) 228 | var works = [] 229 | for(var workIdx = 0; workIdx < workWindow.length; workIdx++) { 230 | var work = workWindow[workIdx] 231 | works.push(new WorkInfo(work[0], work[1])) 232 | } 233 | workInfos.push( 234 | new WorkInfos( 235 | startDate=workWindow[0][0], 236 | endDate=workWindow[workWindow.length-1][0], 237 | workInfoList=works 238 | )); 239 | } 240 | return [userInfo, workInfos] 241 | } 242 | 243 | const sleep = (ms) => { 244 | return new Promise(resolve=>{ 245 | setTimeout(resolve,ms) 246 | }) 247 | } 248 | 249 | async function getSignature() { 250 | const app = express() 251 | app.use(bodyParser.json()); // for parsing application/json 252 | app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded 253 | app.use(upload.array()); // for parsing multipart/form-data 254 | app.use(express.static(appDir+'/public')) 255 | 256 | var data = "" 257 | 258 | app.post('/', (req, res) =>{ 259 | res.send("Hello") 260 | data = req.body.imgData 261 | }) 262 | 263 | const server = app.listen(8080, () => { 264 | console.log(`http://localhost:8080 에 접속해 서명부를 위한 싸인을 해주세요`) 265 | }) 266 | open("http://127.0.0.1:8080/index.html") 267 | 268 | for(;;){ 269 | if (data !== "") { 270 | break; 271 | } 272 | await sleep(1000) 273 | } 274 | 275 | server.close() 276 | return data 277 | } 278 | 279 | function parseArgv() { 280 | const argv = yargs(hideBin(process.argv)) 281 | .option('csv', { 282 | alias: 'c', 283 | type: 'string', 284 | description: 'file path of csv file', 285 | default: undefined 286 | }) 287 | .option('year', { 288 | alias: 'y', 289 | type: 'string', 290 | description: 'change year in document (default is current year)', 291 | default: new Date().getFullYear().toString() 292 | }) 293 | .option('template', { 294 | alias: 't', 295 | type: 'string', 296 | description: 'set custom template of document', 297 | default: DefaultPdfTemplatePath 298 | }) 299 | .option('dx', { 300 | type: 'number', 301 | number: true, 302 | description: 'custom template option to adjust cordinate', 303 | default: 0 304 | }) 305 | .option('dy', { 306 | type: 'number', 307 | number: true, 308 | description: 'custom template option to adjust cordinate', 309 | default: 0 310 | }) 311 | 312 | return argv; 313 | } 314 | 315 | async function main(){ 316 | const signature = await getSignature() 317 | const myArgs = parseArgv() 318 | 319 | if (myArgs.argv.csv === undefined) { 320 | console.log("-c csv file path needed") 321 | myArgs.showHelp() 322 | process.exit(1) 323 | } 324 | 325 | const csvFileName = myArgs.argv.csv 326 | var year = myArgs.argv.year 327 | const [userInfo, workInfos] = await parseCSV(csvFileName); 328 | 329 | for (var i = 0; i < workInfos.length; i++) { 330 | var work = workInfos[i]; 331 | const startDate = work.startDate.replace('/', '_') 332 | const endDate = work.endDate.replace('/', '_') 333 | const fileName = [userInfo.name, startDate, endDate].join('_') + ".pdf" 334 | await createSheet(myArgs.argv.template,"./"+fileName, userInfo, work, year, signature, myArgs.argv.dx * 1, myArgs.argv.dy * 1) 335 | } 336 | } 337 | 338 | main().then(()=>{ 339 | console.log("success") 340 | process.exit(0) 341 | }) 342 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "workdiary", 3 | "version": "1.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@pdf-lib/fontkit": { 8 | "version": "1.0.0", 9 | "resolved": "https://registry.npmjs.org/@pdf-lib/fontkit/-/fontkit-1.0.0.tgz", 10 | "integrity": "sha512-C1Hn6wqRMAXZMW5vTa/oCvcTPq0FQsqKKP2mzzzMxUcx0BWZuJKeH4ZRS320y0LKvRBEs1ntFG2txstSsMGr2g==", 11 | "requires": { 12 | "pako": "^1.0.6" 13 | } 14 | }, 15 | "@pdf-lib/standard-fonts": { 16 | "version": "1.0.0", 17 | "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz", 18 | "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==", 19 | "requires": { 20 | "pako": "^1.0.6" 21 | } 22 | }, 23 | "@pdf-lib/upng": { 24 | "version": "1.0.1", 25 | "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz", 26 | "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==", 27 | "requires": { 28 | "pako": "^1.0.10" 29 | } 30 | }, 31 | "accepts": { 32 | "version": "1.3.7", 33 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 34 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 35 | "requires": { 36 | "mime-types": "~2.1.24", 37 | "negotiator": "0.6.2" 38 | } 39 | }, 40 | "ansi-regex": { 41 | "version": "5.0.0", 42 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 43 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" 44 | }, 45 | "ansi-styles": { 46 | "version": "4.3.0", 47 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 48 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 49 | "requires": { 50 | "color-convert": "^2.0.1" 51 | } 52 | }, 53 | "append-field": { 54 | "version": "1.0.0", 55 | "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", 56 | "integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=" 57 | }, 58 | "array-flatten": { 59 | "version": "1.1.1", 60 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 61 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 62 | }, 63 | "body-parser": { 64 | "version": "1.19.0", 65 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 66 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 67 | "requires": { 68 | "bytes": "3.1.0", 69 | "content-type": "~1.0.4", 70 | "debug": "2.6.9", 71 | "depd": "~1.1.2", 72 | "http-errors": "1.7.2", 73 | "iconv-lite": "0.4.24", 74 | "on-finished": "~2.3.0", 75 | "qs": "6.7.0", 76 | "raw-body": "2.4.0", 77 | "type-is": "~1.6.17" 78 | } 79 | }, 80 | "buffer-from": { 81 | "version": "1.1.1", 82 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 83 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 84 | }, 85 | "busboy": { 86 | "version": "0.2.14", 87 | "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", 88 | "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", 89 | "requires": { 90 | "dicer": "0.2.5", 91 | "readable-stream": "1.1.x" 92 | } 93 | }, 94 | "bytes": { 95 | "version": "3.1.0", 96 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 97 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 98 | }, 99 | "cliui": { 100 | "version": "7.0.4", 101 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", 102 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", 103 | "requires": { 104 | "string-width": "^4.2.0", 105 | "strip-ansi": "^6.0.0", 106 | "wrap-ansi": "^7.0.0" 107 | } 108 | }, 109 | "color-convert": { 110 | "version": "2.0.1", 111 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 112 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 113 | "requires": { 114 | "color-name": "~1.1.4" 115 | } 116 | }, 117 | "color-name": { 118 | "version": "1.1.4", 119 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 120 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" 121 | }, 122 | "concat-stream": { 123 | "version": "1.6.2", 124 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 125 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 126 | "requires": { 127 | "buffer-from": "^1.0.0", 128 | "inherits": "^2.0.3", 129 | "readable-stream": "^2.2.2", 130 | "typedarray": "^0.0.6" 131 | }, 132 | "dependencies": { 133 | "isarray": { 134 | "version": "1.0.0", 135 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 136 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 137 | }, 138 | "readable-stream": { 139 | "version": "2.3.7", 140 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 141 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 142 | "requires": { 143 | "core-util-is": "~1.0.0", 144 | "inherits": "~2.0.3", 145 | "isarray": "~1.0.0", 146 | "process-nextick-args": "~2.0.0", 147 | "safe-buffer": "~5.1.1", 148 | "string_decoder": "~1.1.1", 149 | "util-deprecate": "~1.0.1" 150 | } 151 | }, 152 | "string_decoder": { 153 | "version": "1.1.1", 154 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 155 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 156 | "requires": { 157 | "safe-buffer": "~5.1.0" 158 | } 159 | } 160 | } 161 | }, 162 | "content-disposition": { 163 | "version": "0.5.3", 164 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 165 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 166 | "requires": { 167 | "safe-buffer": "5.1.2" 168 | } 169 | }, 170 | "content-type": { 171 | "version": "1.0.4", 172 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 173 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 174 | }, 175 | "cookie": { 176 | "version": "0.4.0", 177 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 178 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 179 | }, 180 | "cookie-signature": { 181 | "version": "1.0.6", 182 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 183 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 184 | }, 185 | "core-util-is": { 186 | "version": "1.0.2", 187 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 188 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 189 | }, 190 | "csv-parse": { 191 | "version": "4.12.0", 192 | "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.12.0.tgz", 193 | "integrity": "sha512-wPQl3H79vWLPI8cgKFcQXl0NBgYYEqVnT1i6/So7OjMpsI540oD7p93r3w6fDSyPvwkTepG05F69/7AViX2lXg==" 194 | }, 195 | "debug": { 196 | "version": "2.6.9", 197 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 198 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 199 | "requires": { 200 | "ms": "2.0.0" 201 | } 202 | }, 203 | "depd": { 204 | "version": "1.1.2", 205 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 206 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 207 | }, 208 | "destroy": { 209 | "version": "1.0.4", 210 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 211 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 212 | }, 213 | "dicer": { 214 | "version": "0.2.5", 215 | "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", 216 | "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", 217 | "requires": { 218 | "readable-stream": "1.1.x", 219 | "streamsearch": "0.1.2" 220 | } 221 | }, 222 | "ee-first": { 223 | "version": "1.1.1", 224 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 225 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 226 | }, 227 | "emoji-regex": { 228 | "version": "8.0.0", 229 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 230 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" 231 | }, 232 | "encodeurl": { 233 | "version": "1.0.2", 234 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 235 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 236 | }, 237 | "escalade": { 238 | "version": "3.1.1", 239 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 240 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" 241 | }, 242 | "escape-html": { 243 | "version": "1.0.3", 244 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 245 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 246 | }, 247 | "etag": { 248 | "version": "1.8.1", 249 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 250 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 251 | }, 252 | "express": { 253 | "version": "4.17.1", 254 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 255 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 256 | "requires": { 257 | "accepts": "~1.3.7", 258 | "array-flatten": "1.1.1", 259 | "body-parser": "1.19.0", 260 | "content-disposition": "0.5.3", 261 | "content-type": "~1.0.4", 262 | "cookie": "0.4.0", 263 | "cookie-signature": "1.0.6", 264 | "debug": "2.6.9", 265 | "depd": "~1.1.2", 266 | "encodeurl": "~1.0.2", 267 | "escape-html": "~1.0.3", 268 | "etag": "~1.8.1", 269 | "finalhandler": "~1.1.2", 270 | "fresh": "0.5.2", 271 | "merge-descriptors": "1.0.1", 272 | "methods": "~1.1.2", 273 | "on-finished": "~2.3.0", 274 | "parseurl": "~1.3.3", 275 | "path-to-regexp": "0.1.7", 276 | "proxy-addr": "~2.0.5", 277 | "qs": "6.7.0", 278 | "range-parser": "~1.2.1", 279 | "safe-buffer": "5.1.2", 280 | "send": "0.17.1", 281 | "serve-static": "1.14.1", 282 | "setprototypeof": "1.1.1", 283 | "statuses": "~1.5.0", 284 | "type-is": "~1.6.18", 285 | "utils-merge": "1.0.1", 286 | "vary": "~1.1.2" 287 | } 288 | }, 289 | "finalhandler": { 290 | "version": "1.1.2", 291 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 292 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 293 | "requires": { 294 | "debug": "2.6.9", 295 | "encodeurl": "~1.0.2", 296 | "escape-html": "~1.0.3", 297 | "on-finished": "~2.3.0", 298 | "parseurl": "~1.3.3", 299 | "statuses": "~1.5.0", 300 | "unpipe": "~1.0.0" 301 | } 302 | }, 303 | "forwarded": { 304 | "version": "0.1.2", 305 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 306 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 307 | }, 308 | "fresh": { 309 | "version": "0.5.2", 310 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 311 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 312 | }, 313 | "get-caller-file": { 314 | "version": "2.0.5", 315 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 316 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" 317 | }, 318 | "http-errors": { 319 | "version": "1.7.2", 320 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 321 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 322 | "requires": { 323 | "depd": "~1.1.2", 324 | "inherits": "2.0.3", 325 | "setprototypeof": "1.1.1", 326 | "statuses": ">= 1.5.0 < 2", 327 | "toidentifier": "1.0.0" 328 | } 329 | }, 330 | "iconv-lite": { 331 | "version": "0.4.24", 332 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 333 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 334 | "requires": { 335 | "safer-buffer": ">= 2.1.2 < 3" 336 | } 337 | }, 338 | "inherits": { 339 | "version": "2.0.3", 340 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 341 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 342 | }, 343 | "ipaddr.js": { 344 | "version": "1.9.1", 345 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 346 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 347 | }, 348 | "is-docker": { 349 | "version": "2.1.1", 350 | "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", 351 | "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==" 352 | }, 353 | "is-fullwidth-code-point": { 354 | "version": "3.0.0", 355 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 356 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" 357 | }, 358 | "is-wsl": { 359 | "version": "2.2.0", 360 | "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", 361 | "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", 362 | "requires": { 363 | "is-docker": "^2.0.0" 364 | } 365 | }, 366 | "isarray": { 367 | "version": "0.0.1", 368 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 369 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 370 | }, 371 | "media-typer": { 372 | "version": "0.3.0", 373 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 374 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 375 | }, 376 | "merge-descriptors": { 377 | "version": "1.0.1", 378 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 379 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 380 | }, 381 | "methods": { 382 | "version": "1.1.2", 383 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 384 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 385 | }, 386 | "mime": { 387 | "version": "1.6.0", 388 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 389 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 390 | }, 391 | "mime-db": { 392 | "version": "1.44.0", 393 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", 394 | "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" 395 | }, 396 | "mime-types": { 397 | "version": "2.1.27", 398 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", 399 | "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", 400 | "requires": { 401 | "mime-db": "1.44.0" 402 | } 403 | }, 404 | "minimist": { 405 | "version": "1.2.5", 406 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 407 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" 408 | }, 409 | "mkdirp": { 410 | "version": "0.5.5", 411 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 412 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 413 | "requires": { 414 | "minimist": "^1.2.5" 415 | } 416 | }, 417 | "ms": { 418 | "version": "2.0.0", 419 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 420 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 421 | }, 422 | "multer": { 423 | "version": "1.4.2", 424 | "resolved": "https://registry.npmjs.org/multer/-/multer-1.4.2.tgz", 425 | "integrity": "sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==", 426 | "requires": { 427 | "append-field": "^1.0.0", 428 | "busboy": "^0.2.11", 429 | "concat-stream": "^1.5.2", 430 | "mkdirp": "^0.5.1", 431 | "object-assign": "^4.1.1", 432 | "on-finished": "^2.3.0", 433 | "type-is": "^1.6.4", 434 | "xtend": "^4.0.0" 435 | } 436 | }, 437 | "negotiator": { 438 | "version": "0.6.2", 439 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 440 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 441 | }, 442 | "object-assign": { 443 | "version": "4.1.1", 444 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 445 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 446 | }, 447 | "on-finished": { 448 | "version": "2.3.0", 449 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 450 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 451 | "requires": { 452 | "ee-first": "1.1.1" 453 | } 454 | }, 455 | "open": { 456 | "version": "7.3.0", 457 | "resolved": "https://registry.npmjs.org/open/-/open-7.3.0.tgz", 458 | "integrity": "sha512-mgLwQIx2F/ye9SmbrUkurZCnkoXyXyu9EbHtJZrICjVAJfyMArdHp3KkixGdZx1ZHFPNIwl0DDM1dFFqXbTLZw==", 459 | "requires": { 460 | "is-docker": "^2.0.0", 461 | "is-wsl": "^2.1.1" 462 | } 463 | }, 464 | "pako": { 465 | "version": "1.0.11", 466 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", 467 | "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" 468 | }, 469 | "parseurl": { 470 | "version": "1.3.3", 471 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 472 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 473 | }, 474 | "path-to-regexp": { 475 | "version": "0.1.7", 476 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 477 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 478 | }, 479 | "pdf-lib": { 480 | "version": "1.11.1", 481 | "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.11.1.tgz", 482 | "integrity": "sha512-gfMG3AKmKriMitbDZLBU2paVk3moAHtr03l79Y8bt+exSA4jBJyetLbzT8/S73suLWn37ZfWpp8vVWPHi7KNdA==", 483 | "requires": { 484 | "@pdf-lib/standard-fonts": "^1.0.0", 485 | "@pdf-lib/upng": "^1.0.1", 486 | "pako": "^1.0.11", 487 | "tslib": "^1.11.1" 488 | } 489 | }, 490 | "process-nextick-args": { 491 | "version": "2.0.1", 492 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 493 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 494 | }, 495 | "proxy-addr": { 496 | "version": "2.0.6", 497 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", 498 | "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", 499 | "requires": { 500 | "forwarded": "~0.1.2", 501 | "ipaddr.js": "1.9.1" 502 | } 503 | }, 504 | "qs": { 505 | "version": "6.7.0", 506 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 507 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 508 | }, 509 | "range-parser": { 510 | "version": "1.2.1", 511 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 512 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 513 | }, 514 | "raw-body": { 515 | "version": "2.4.0", 516 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 517 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 518 | "requires": { 519 | "bytes": "3.1.0", 520 | "http-errors": "1.7.2", 521 | "iconv-lite": "0.4.24", 522 | "unpipe": "1.0.0" 523 | } 524 | }, 525 | "readable-stream": { 526 | "version": "1.1.14", 527 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 528 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 529 | "requires": { 530 | "core-util-is": "~1.0.0", 531 | "inherits": "~2.0.1", 532 | "isarray": "0.0.1", 533 | "string_decoder": "~0.10.x" 534 | } 535 | }, 536 | "require-directory": { 537 | "version": "2.1.1", 538 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 539 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" 540 | }, 541 | "safe-buffer": { 542 | "version": "5.1.2", 543 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 544 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 545 | }, 546 | "safer-buffer": { 547 | "version": "2.1.2", 548 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 549 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 550 | }, 551 | "send": { 552 | "version": "0.17.1", 553 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 554 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 555 | "requires": { 556 | "debug": "2.6.9", 557 | "depd": "~1.1.2", 558 | "destroy": "~1.0.4", 559 | "encodeurl": "~1.0.2", 560 | "escape-html": "~1.0.3", 561 | "etag": "~1.8.1", 562 | "fresh": "0.5.2", 563 | "http-errors": "~1.7.2", 564 | "mime": "1.6.0", 565 | "ms": "2.1.1", 566 | "on-finished": "~2.3.0", 567 | "range-parser": "~1.2.1", 568 | "statuses": "~1.5.0" 569 | }, 570 | "dependencies": { 571 | "ms": { 572 | "version": "2.1.1", 573 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 574 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 575 | } 576 | } 577 | }, 578 | "serve-static": { 579 | "version": "1.14.1", 580 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 581 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 582 | "requires": { 583 | "encodeurl": "~1.0.2", 584 | "escape-html": "~1.0.3", 585 | "parseurl": "~1.3.3", 586 | "send": "0.17.1" 587 | } 588 | }, 589 | "setprototypeof": { 590 | "version": "1.1.1", 591 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 592 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 593 | }, 594 | "statuses": { 595 | "version": "1.5.0", 596 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 597 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 598 | }, 599 | "streamsearch": { 600 | "version": "0.1.2", 601 | "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", 602 | "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" 603 | }, 604 | "string-width": { 605 | "version": "4.2.0", 606 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", 607 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", 608 | "requires": { 609 | "emoji-regex": "^8.0.0", 610 | "is-fullwidth-code-point": "^3.0.0", 611 | "strip-ansi": "^6.0.0" 612 | } 613 | }, 614 | "string_decoder": { 615 | "version": "0.10.31", 616 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 617 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" 618 | }, 619 | "strip-ansi": { 620 | "version": "6.0.0", 621 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 622 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 623 | "requires": { 624 | "ansi-regex": "^5.0.0" 625 | } 626 | }, 627 | "toidentifier": { 628 | "version": "1.0.0", 629 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 630 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 631 | }, 632 | "tslib": { 633 | "version": "1.13.0", 634 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", 635 | "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" 636 | }, 637 | "type-is": { 638 | "version": "1.6.18", 639 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 640 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 641 | "requires": { 642 | "media-typer": "0.3.0", 643 | "mime-types": "~2.1.24" 644 | } 645 | }, 646 | "typedarray": { 647 | "version": "0.0.6", 648 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 649 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" 650 | }, 651 | "unpipe": { 652 | "version": "1.0.0", 653 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 654 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 655 | }, 656 | "util-deprecate": { 657 | "version": "1.0.2", 658 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 659 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 660 | }, 661 | "utils-merge": { 662 | "version": "1.0.1", 663 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 664 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 665 | }, 666 | "vary": { 667 | "version": "1.1.2", 668 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 669 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 670 | }, 671 | "wrap-ansi": { 672 | "version": "7.0.0", 673 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 674 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 675 | "requires": { 676 | "ansi-styles": "^4.0.0", 677 | "string-width": "^4.1.0", 678 | "strip-ansi": "^6.0.0" 679 | } 680 | }, 681 | "xtend": { 682 | "version": "4.0.2", 683 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 684 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" 685 | }, 686 | "y18n": { 687 | "version": "5.0.5", 688 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", 689 | "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" 690 | }, 691 | "yargs": { 692 | "version": "16.2.0", 693 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", 694 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", 695 | "requires": { 696 | "cliui": "^7.0.2", 697 | "escalade": "^3.1.1", 698 | "get-caller-file": "^2.0.5", 699 | "require-directory": "^2.1.1", 700 | "string-width": "^4.2.0", 701 | "y18n": "^5.0.5", 702 | "yargs-parser": "^20.2.2" 703 | } 704 | }, 705 | "yargs-parser": { 706 | "version": "20.2.4", 707 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", 708 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" 709 | } 710 | } 711 | } 712 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "workdiary", 3 | "version": "1.0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "MIT", 12 | "bin": { 13 | "workDiary": "./index.js" 14 | }, 15 | "dependencies": { 16 | "@pdf-lib/fontkit": "^1.0.0", 17 | "body-parser": "^1.19.0", 18 | "csv-parse": "^4.12.0", 19 | "express": "^4.17.1", 20 | "multer": "^1.4.2", 21 | "open": "^7.3.0", 22 | "pdf-lib": "^1.11.1", 23 | "yargs": "^16.2.0" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | signature pad 4 | 5 | 6 | 33 | 34 | 35 |

36 | 서명란 37 |

38 |
39 | 40 |
41 |
42 | 43 | 44 |
45 | 46 | 47 | --------------------------------------------------------------------------------