├── .gitignore ├── LICENSE ├── Moodle_Tool_Config.png ├── Provider ├── keyGenerator.js ├── launch_validation.js ├── mongoDB │ └── Database.js ├── oauth2_validation.js ├── oidc.js ├── register_platform.js ├── student_score.js └── token_generator.js ├── README.md ├── favicon.ico ├── package-lock.json ├── package.json └── tests ├── oauth_request.spec.js └── request_validation.spec.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 San Diego Code School 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 | -------------------------------------------------------------------------------- /Moodle_Tool_Config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SanDiegoCodeSchool/lti-node-library/8bfe9af23738ae8dd705fb7be1e369e396ba47c6/Moodle_Tool_Config.png -------------------------------------------------------------------------------- /Provider/keyGenerator.js: -------------------------------------------------------------------------------- 1 | const { generateKeyPairSync } = require("crypto"); 2 | const crypto = require("crypto"); 3 | 4 | /* 5 | * Creates a unique pass phrase 6 | * @returns phrase 7 | */ 8 | function passPhrase() { 9 | var phrase = ""; 10 | var characters = 11 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 12 | for (let i = 0; i < 255; i++) { 13 | phrase += characters.charAt(Math.random() * characters.length); 14 | } 15 | 16 | return phrase.toString(); 17 | } 18 | 19 | /* 20 | * Generate RSA public and private key pair to validate between Tool and the Platform 21 | * @returns key pair 22 | * NOTE: The signature and the verification needs to be updated with a proper consumerID or some other unique identifer 23 | */ 24 | function keyGenerator() { 25 | var keys = {}; 26 | var kid = passPhrase(); 27 | 28 | const { publicKey, privateKey } = generateKeyPairSync( 29 | "rsa", 30 | { 31 | modulusLength: 4096, 32 | publicKeyEncoding: { 33 | type: "spki", 34 | format: "pem" 35 | }, 36 | privateKeyEncoding: { 37 | type: "pkcs8", 38 | format: "pem", 39 | cipher: "aes-256-cbc", 40 | passphrase: kid 41 | } 42 | }, 43 | (err, publicKey, privateKey) => { 44 | var sign = crypto.createSign("RSA-SHA256"); 45 | sign.update("ConsumerClientID"); 46 | const signature = sign.sign(privateKey, "base64"); 47 | console.info("signature: %s", signature); 48 | 49 | const verify = crypto.createVerify("RSA-SHA256"); 50 | verify.update("ConsumerClientID"); 51 | const verified = verify.verify(publicKey, "base64"); 52 | console.info("is signature ok? %s", verified); 53 | } 54 | ); 55 | 56 | keys = { 'publicKey': publicKey , 'privateKey': privateKey, keyID: kid }; 57 | return keys; 58 | } 59 | 60 | module.exports = { keyGenerator, passPhrase }; 61 | -------------------------------------------------------------------------------- /Provider/launch_validation.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | const jwkToPem = require('jwk-to-pem'); 3 | const axios = require('axios'); 4 | 5 | /* 6 | * Validate LTI 1.3 Launch Request 7 | * @param req - HTTP Tool launch request to be validated 8 | * @returns an array, which if empty indicates 0 errors, otherwise, contains description of each error 9 | */ 10 | function valid_launch_request(body, req) { 11 | let errors = []; 12 | 13 | // Per the LTI1.3 spec, the following are the minimum valid roles 14 | const VALID_ROLES = [ 15 | "http://purl.imsglobal.org/vocab/lis/v2/system/person#Administrator", 16 | "http://purl.imsglobal.org/vocab/lis/v2/system/person#None", 17 | "http://purl.imsglobal.org/vocab/lis/v2/institution/person#Administrator", 18 | "http://purl.imsglobal.org/vocab/lis/v2/institution/person#Faculty", 19 | "http://purl.imsglobal.org/vocab/lis/v2/institution/person#Guest", 20 | "http://purl.imsglobal.org/vocab/lis/v2/institution/person#None", 21 | "http://purl.imsglobal.org/vocab/lis/v2/institution/person#Other", 22 | "http://purl.imsglobal.org/vocab/lis/v2/institution/person#Staff", 23 | "http://purl.imsglobal.org/vocab/lis/v2/institution/person#Student", 24 | "http://purl.imsglobal.org/vocab/lis/v2/membership#Administrator", 25 | "http://purl.imsglobal.org/vocab/lis/v2/membership#ContentDeveloper", 26 | "http://purl.imsglobal.org/vocab/lis/v2/membership#Instructor", 27 | "http://purl.imsglobal.org/vocab/lis/v2/membership#Learner", 28 | "http://purl.imsglobal.org/vocab/lis/v2/membership#Mentor" 29 | ]; 30 | 31 | const VALID_CONTEXTS = [ 32 | 'http://purl.imsglobal.org/vocab/lis/v2/course#CourseOffering', 33 | 'CourseOffering', // deprecated 34 | 'urn:lti:context-type:ims/lis/CourseOffering', // decrecated 35 | 'http://purl.imsglobal.org/vocab/lis/v2/course#CourseSection', 36 | 'CourseSection', // deprecated 37 | 'urn:lti:context-type:ims/lis/CourseSection', // deprecated 38 | 'http://purl.imsglobal.org/vocab/lis/v2/course#CourseTemplate', 39 | 'CourseTemplate', // deprecated 40 | 'urn:lti:context-type:ims/lis/CourseTemplate', // deprecated 41 | 'http://purl.imsglobal.org/vocab/lis/v2/course#Group', 42 | 'Group', // deprecated 43 | 'urn:lti:context-type:ims/lis/Group' // deprecated 44 | ]; 45 | 46 | // Check it is a POST request 47 | if (req.method !== "POST") { 48 | errors.push("Method invalid"); 49 | } 50 | 51 | // Check the LTI message type is LtiResourceLinkRequest 52 | if (body.hasOwnProperty("https://purl.imsglobal.org/spec/lti/claim/message_type")) { 53 | if (body["https://purl.imsglobal.org/spec/lti/claim/message_type"] !== "LtiResourceLinkRequest") { 54 | errors.push("LTI message type invalid"); 55 | } 56 | } else { 57 | errors.push("LTI message type missing"); 58 | } 59 | 60 | // Check the LTI version is 1.3.0 61 | if (body.hasOwnProperty("https://purl.imsglobal.org/spec/lti/claim/version")) { 62 | if (body["https://purl.imsglobal.org/spec/lti/claim/version"] !== "1.3.0") { 63 | errors.push("LTI Version invalid"); 64 | } 65 | } else { 66 | errors.push("LTI Version missing"); 67 | } 68 | 69 | //Check the Issuer is same as issuer in Login Request 70 | if (body.hasOwnProperty('iss')) { 71 | if (body.iss !== req.session.login_request.iss) { 72 | errors.push("Issuer invalid", body.iss, req.session.login_request.iss); 73 | } 74 | } else { 75 | errors.push("Issuer missing"); 76 | } 77 | 78 | //Check the Audience matches Tool's Client ID. Note Audience can be an array or a single string 79 | //If multiple Audiences are present, must all check that the Authorized Party is present and valid. 80 | if (body.hasOwnProperty('aud')) { 81 | if (typeof body.aud === 'array' && !body.aud.includes(req.session.platform_DBinfo.consumerToolClientID && 82 | body.hasOwnProperty('azp') && !body.azp !== req.session.platform_DBinfo.consumerToolClientID) || 83 | body.aud !== req.session.platform_DBinfo.consumerToolClientID) { 84 | errors.push("Audience invalid", body.aud); 85 | } 86 | } else { 87 | errors.push("Audience missing"); 88 | } 89 | 90 | //If present, check the security Algorithm is RS256 91 | if (body.hasOwnProperty('alg')) { 92 | if (body.alg !== 'RS256') { 93 | errors.push("Algorithm invalid", body.alg); 94 | } 95 | } 96 | 97 | //Check that the Token has not passed its Expiration time 98 | if (body.hasOwnProperty('exp')) { 99 | if (Date.now()/1000 >= body.exp) { 100 | errors.push("Expiration invalid", Date.now(), body.exp); 101 | } 102 | } else { 103 | errors.push("Expiration missing"); 104 | } 105 | 106 | //Check that the Token's Issued At time is within the past 1 hour (3600 seconds) 107 | if (body.hasOwnProperty('iat')) { 108 | if (Date.now()/1000 - 3600 >= body.iat) { 109 | errors.push("Issued At invalid", Date.now(), body.iat); 110 | } 111 | } else { 112 | errors.push("Issued At missing"); 113 | } 114 | 115 | //Check that the Nonce is valid to mitigate replay attacks. The nonce value is a case-sensitive string and cannot be 116 | //used more than once within a Tool-specified time frame. 117 | //TODO: implement cleanup function to remove old nonce values (to allow nonces to be reused after a certain timeframe). 118 | if (body.hasOwnProperty('nonce')) { 119 | if (!req.session.hasOwnProperty('nonce_list')) { 120 | req.session.nonce_list = [body.nonce]; 121 | } else if (req.session.nonce_list.includes(body.nonce)) { 122 | errors.push("Nonce invalid: duplicated"); 123 | } else { 124 | req.session.nonce_list.push(body.nonce); 125 | } 126 | } else { 127 | errors.push("Nonce missing"); 128 | } 129 | 130 | // Check the Deployment ID. deployment_id is a stable unique id within the iss (Issuer) & client_id (Tool). 131 | // TODO: check actual value against database once registration data is being stored 132 | if (body.hasOwnProperty("https://purl.imsglobal.org/spec/lti/claim/deployment_id")) { 133 | if (body["https://purl.imsglobal.org/spec/lti/claim/deployment_id"].length > 255) { 134 | errors.push("Deployment ID invalid"); 135 | } 136 | } else { 137 | errors.push("Deployment ID missing"); 138 | } 139 | 140 | // Check Target Link URI - MUST be the same value as the target_link_uri passed by the platform in the OIDC third party 141 | // initiated login request, which was stored for this session. 142 | if (body.hasOwnProperty('https://purl.imsglobal.org/spec/lti/claim/target_link_uri')) { 143 | if (body['https://purl.imsglobal.org/spec/lti/claim/target_link_uri'] === "") { 144 | errors.push("Target Link URI invalid"); 145 | } else if (body['https://purl.imsglobal.org/spec/lti/claim/target_link_uri'] !== req.session.login_request.target_link_uri) { 146 | errors.push("Target Link URI invalid"); 147 | } 148 | } else { 149 | errors.push("Target Link URI missing"); 150 | } 151 | 152 | // Check a resource link ID exists 153 | // TODO: check actual value against database once registration data is being stored 154 | if (body.hasOwnProperty("https://purl.imsglobal.org/spec/lti/claim/resource_link") && 155 | body["https://purl.imsglobal.org/spec/lti/claim/resource_link"].hasOwnProperty("id")) { 156 | if (body["https://purl.imsglobal.org/spec/lti/claim/resource_link"].id.length > 255) { 157 | errors.push("Resource Link invalid"); 158 | } 159 | } else { 160 | errors.push("Resource Link missing"); 161 | } 162 | 163 | // Check sub exists for OIDC request. Anonymous requests are not currently supported. 164 | // TODO: check actual value against database once user data is being stored 165 | if (body.hasOwnProperty('sub')) { 166 | if (body['sub'].length > 255) { 167 | errors.push('Sub invalid', body['sub']); 168 | } 169 | } else { 170 | errors.push("Sub missing"); 171 | } 172 | 173 | // Check any user roles provided are valid, ok if array is empty, but if non-empty, must contain 174 | // at least one of the VALID_ROLES defined in this function 175 | if (body.hasOwnProperty("https://purl.imsglobal.org/spec/lti/claim/roles")) { 176 | if (body["https://purl.imsglobal.org/spec/lti/claim/roles"].length !== 0 && 177 | !body["https://purl.imsglobal.org/spec/lti/claim/roles"].some( 178 | role => VALID_ROLES.indexOf(role) >= 0)) { 179 | errors.push("Role invalid"); 180 | } 181 | } else { 182 | errors.push("Role missing"); 183 | } 184 | 185 | // Context is optional, but if present, check validity of those provided. 186 | if (body.hasOwnProperty('https://purl.imsglobal.org/spec/lti/claim/context')) { 187 | if (!body['https://purl.imsglobal.org/spec/lti/claim/context'].hasOwnProperty('label') && 188 | !body['https://purl.imsglobal.org/spec/lti/claim/context'].hasOwnProperty('title') ) { 189 | errors.push('Context invalid: does not contain label OR title'); 190 | } 191 | if (body['https://purl.imsglobal.org/spec/lti/claim/context'].hasOwnProperty('type')) { 192 | if (!body['https://purl.imsglobal.org/spec/lti/claim/context'].type.some( 193 | context => VALID_CONTEXTS.indexOf(context) >= 0)) { 194 | errors.push('Context invalid: type invalid', body['https://purl.imsglobal.org/spec/lti/claim/context'].type); 195 | } 196 | } else { 197 | errors.push('Context type missing'); 198 | } 199 | } 200 | 201 | // User name information is optional, but if present, check validity of what is provided. 202 | if (body.hasOwnProperty('given_name') && typeof body['given_name'] !== 'string') { 203 | errors.push('Name information invalid'); 204 | } 205 | if (body.hasOwnProperty('family_name') && typeof body['family_name'] !== 'string') { 206 | errors.push('Name information invalid'); 207 | } 208 | if (body.hasOwnProperty('name') && typeof body['name'] !== 'string') { 209 | errors.push('Name information invalid'); 210 | } 211 | 212 | // Returning scores is optional, but if requested, check validity of what is provided. 213 | if (body.hasOwnProperty('https://purl.imsglobal.org/spec/lti-ags/claim/endpoint')) { 214 | if (!body['https://purl.imsglobal.org/spec/lti-ags/claim/endpoint'].hasOwnProperty('scope') || 215 | body['https://purl.imsglobal.org/spec/lti-ags/claim/endpoint'].scope.length === 0) { 216 | errors.push('Score setup invalid'); 217 | } 218 | if (!body['https://purl.imsglobal.org/spec/lti-ags/claim/endpoint'].hasOwnProperty('lineitem') || 219 | typeof body['https://purl.imsglobal.org/spec/lti-ags/claim/endpoint'].lineitem !== 'string') { 220 | errors.push('Score setup invalid'); 221 | } 222 | } 223 | 224 | return errors; 225 | } 226 | 227 | /* 228 | * Validate that the state sent with an OIDC launch matches the state that was sent in the OIDC response 229 | * @param req - HTTP OIDC request to launch Tool. 230 | * @returns - boolean on whether it is valid or not 231 | */ 232 | function is_valid_oidc_launch(req) { 233 | //TODO: when state is signed before being sent, need to decode before validation 234 | if (req.body.state !== req.session.login_response.state) { 235 | return false; 236 | } 237 | return true; 238 | } 239 | 240 | /* 241 | * Validates that the required keys are present and filled per LTI 1.3 standards in conjunction with the OAuth_validation 242 | * before launching Tool. 243 | * @param req Request 244 | * @param res Response 245 | * @param path - if any path needs to be appended to the URI to launch the Tool to the correct route 246 | * @returns object with errors if invalid launch, otherwise, redirects to Tool 247 | */ 248 | function launchTool(req, res, path) { 249 | let errors = []; 250 | 251 | //If Platform rejected login response, show error 252 | if (req.body.hasOwnProperty('error')) { 253 | errors.push(`Login Response was rejected: ${req.body.error}`); 254 | } else { 255 | //Validate OIDC Launch Request 256 | if (!is_valid_oidc_launch(req)) { 257 | errors.push('Invalid OIDC Launch Request: state mismatch'); 258 | } else { 259 | //If valid, save OIDC Launch Request for later reference during current session 260 | req.session.payload = req.body; 261 | 262 | //Decode the JWT into header, payload, and signature 263 | const jwt_string = req.body.id_token; 264 | let basic_decoded = jwt.decode(jwt_string, {complete: true}); 265 | 266 | //Get the key to verify the JWT 267 | axios.get(req.session.platform_DBinfo.consumerAuthorizationconfig.key + '?kid=' + basic_decoded.header.kid) 268 | .then(keys => { 269 | jwt.verify(jwt_string, jwkToPem(keys.data.keys[0]), {algorithm: 'RS256'}, (err, decoded) => { 270 | if (err) { 271 | errors.push(`Could not verify token: ${err}`); 272 | } else { 273 | //Save decoded OIDC Launch Request to reference later during the current session 274 | req.session.decoded_launch = decoded; 275 | 276 | //Validate Launch Request details 277 | errors = valid_launch_request(decoded, req); 278 | 279 | if (errors.length === 0) { 280 | //No errors, so redirect to the Tool 281 | return res.send({ payload: req.session.payload } && res.redirect(decoded['https://purl.imsglobal.org/spec/lti/claim/target_link_uri'] + path)); 282 | } 283 | } 284 | }); 285 | }); 286 | } 287 | } 288 | if (errors.length > 0) { 289 | return res.status(400).send({ 290 | error: "invalid_request", 291 | errors: errors 292 | }); 293 | } 294 | } 295 | 296 | module.exports = { launchTool, valid_launch_request }; 297 | -------------------------------------------------------------------------------- /Provider/mongoDB/Database.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | 3 | /* 4 | * Database class to maintain and access Platform information 5 | */ 6 | class Database { 7 | 8 | static async Get(collection, platformSchema, query) { 9 | let Model = mongoose.model(collection, platformSchema); 10 | let platformData; 11 | 12 | await Model.find(query) 13 | .then(registeredPlatform => { 14 | platformData = registeredPlatform; 15 | }) 16 | .catch(err => console.log(`Error finding platform ${err}`)); 17 | return platformData; 18 | }; 19 | 20 | static async GetKey(collection, platformSchema, query) { 21 | let Model = mongoose.model(collection, platformSchema); 22 | let publicKey; 23 | 24 | await Model.find(query) 25 | .then(key => { 26 | publicKey = key[0].kid.publicKey; 27 | }) 28 | .catch(err => console.log(`Error finding platform ${err}`)); 29 | return publicKey; 30 | } 31 | 32 | static Insert(collection, platformSchema, platform) { 33 | let Model = mongoose.model(collection, platformSchema); 34 | 35 | let newPlatform = new Model(platform); 36 | newPlatform.save(); 37 | return true; 38 | }; 39 | 40 | }; 41 | 42 | module.exports = Database; 43 | -------------------------------------------------------------------------------- /Provider/oauth2_validation.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Validate LTI 1.3 OAuth2 Client Credentials Request 4 | * @param req - HTTP request to validate 5 | * @returns an array, which if empty indicates 0 errors, otherwise, contains description of each error 6 | */ 7 | function valid_oauth2_request(req) { 8 | let body = req.body; 9 | let errors = []; 10 | 11 | // Check it is a POST request 12 | if (req.method !== 'POST') { 13 | errors.push('Method invalid'); 14 | }; 15 | 16 | // Check the data exists 17 | if (Object.entries(body).length === 0 && body.constructor === Object) { 18 | errors.push('body data missing'); 19 | } else { 20 | // Check the grant type 21 | if (!body.hasOwnProperty('grant_type')) { 22 | errors.push('grant type missing') 23 | } else { 24 | if (body.grant_type !== 'client_credentials') { 25 | errors.push('grant type invalid') 26 | } 27 | } 28 | 29 | // Check the client_id 30 | if (!body.hasOwnProperty('client_id')) { 31 | errors.push('client id missing') 32 | } else { 33 | //TODO: Must retrieve Consumer information from DB 34 | if (body.client_id === '') { 35 | errors.push('client id invalid') 36 | } 37 | } 38 | 39 | // Check the client_secret 40 | if (!body.hasOwnProperty('client_secret')) { 41 | errors.push('client secret missing') 42 | } else { 43 | //TODO: Must retrieve Consumer information from DB 44 | if (body.client_secret === '') { 45 | errors.push('client secret invalid') 46 | } 47 | } 48 | } 49 | 50 | return errors; 51 | } 52 | 53 | 54 | module.exports = { valid_oauth2_request }; 55 | -------------------------------------------------------------------------------- /Provider/oidc.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | const url = require('url'); 3 | const Database = require('../Provider/mongoDB/Database.js'); 4 | const { platformSchema } = require('../Provider/register_platform'); 5 | 6 | /* 7 | * Validates OIDC login request. Checkes required parameters are present. 8 | * @param req - OIDC login request sent from LMS to Tool 9 | * @returns array of errors, if empty then request is valid 10 | */ 11 | function is_valid_oidc_login(req) { 12 | let errors = []; 13 | if (!req.body.hasOwnProperty('iss')) { 14 | errors.push('Issuer missing'); 15 | } 16 | if (!req.body.hasOwnProperty('login_hint')) { 17 | errors.push('Login hint missing'); 18 | } 19 | if (!req.body.hasOwnProperty('target_link_uri')) { 20 | errors.push('Target Link URI missing'); 21 | } 22 | return errors; 23 | } 24 | 25 | /* 26 | * Validate OIDC login and construct response for valid logins. Looks up Issuer in database to ensure they are registered 27 | * with the Tool. 28 | * @param req - req sent from OIDC to Tool's OIDC login endpoint 29 | * @returns if valid request, returns properly formated response object 30 | * @return if invalid request, returns array of errors with the request 31 | */ 32 | 33 | function create_oidc_response(req, res) { 34 | let errors = []; 35 | 36 | //Save the OIDC Login Request to reference later during current session 37 | req.session.login_request = req.body; 38 | 39 | Database.Get('platforms', platformSchema, { consumerUrl: req.session.login_request.iss }) 40 | .then(dbResult => { 41 | 42 | if (dbResult.length === 1) return dbResult[0] 43 | else res.send(['Issuer invalid: not registered']); 44 | }).then(platform => { 45 | //Save the Platform information from the database to reference later during current session 46 | req.session.platform_DBinfo = platform; 47 | 48 | errors = is_valid_oidc_login(req); 49 | 50 | if (errors.length === 0 && req.session.platform_DBinfo) { 51 | let response = { 52 | scope: 'openid', 53 | response_type: 'id_token', 54 | client_id: req.session.platform_DBinfo.consumerToolClientID, 55 | redirect_uri: req.session.platform_DBinfo.consumerRedirect_URI, 56 | login_hint: req.body.login_hint, 57 | state: create_unique_string(30, true), 58 | response_mode: 'form_post', 59 | nonce: create_unique_string(25, false), 60 | prompt: 'none' 61 | } 62 | if (req.body.hasOwnProperty('lti_message_hint')) { 63 | response = { 64 | ...response, 65 | lti_message_hint: req.body.lti_message_hint, 66 | }; 67 | } 68 | //Save the OIDC Login Response to reference later during current session 69 | req.session.login_response = response; 70 | 71 | res.redirect(url.format({ 72 | pathname: platform.consumerAuthorizationURL, 73 | query: req.session.login_response 74 | })); 75 | } else if (!req.session.platform_DBinfo) { 76 | errors.push('Issuer invalid: not registered'); 77 | } 78 | }); 79 | //errors were found, so return the errors 80 | if (errors.length > 0) { 81 | res.send('Error with OIDC Login: ' + errors); 82 | } 83 | } 84 | 85 | /* 86 | * Create a long, unique string consisting of upper and lower case letters and numbers. 87 | * @param length - desired length of string 88 | * @param signed - boolean whether string should be signed with Tool's private key 89 | * @returns unique string 90 | */ 91 | function create_unique_string(length, signed) { 92 | let unique_string = ''; 93 | const possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 94 | for(let i = 0; i < length; i++) { 95 | unique_string += possible.charAt(Math.floor(Math.random() * possible.length)); 96 | } 97 | //TODO: if signed === true, sign the string with our private key 98 | return unique_string; 99 | } 100 | 101 | module.exports = { create_oidc_response, create_unique_string }; 102 | -------------------------------------------------------------------------------- /Provider/register_platform.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose'); 2 | const Database = require('./mongoDB/Database.js'); 3 | const { keyGenerator } = require('./keyGenerator.js'); 4 | const Schema = mongoose.Schema; 5 | 6 | const platformSchema = new Schema({ 7 | consumerUrl: String, 8 | consumerName: String, 9 | consumerToolClientID: String, 10 | consumerAuthorizationURL: String, 11 | consumerAccessTokenURL: String, 12 | consumerRedirect_URI: String, 13 | kid: Object, 14 | consumerAuthorizationconfig: { 15 | method: String, 16 | key: String 17 | } 18 | }); 19 | 20 | /* 21 | * Register a new Platform for the Tool 22 | * @params - all of the Platform/Tool fields shown below 23 | * @returns Platform object, if Platform is already registered 24 | */ 25 | const registerPlatform = async ( 26 | consumerUrl, /* Base url of the LMS. */ 27 | consumerName, /* Domain name of the LMS. */ 28 | consumerToolClientID, /* Client ID created from the LMS. */ 29 | consumerAuthorizationURL, /* URL that the LMS redirects to launch the tool. */ 30 | consumerAccessTokenURL, /* URL that the LMS redirects to obtain an access token/login . */ 31 | consumerRedirect_URI, /* URL that the LMS redirects to launch tool . */ 32 | consumerAuthorizationconfig, /* Authentication method and key for verifying messages from the platform. {method: "RSA_KEY", key:"PUBLIC KEY..."} */ 33 | ) => { 34 | if ( !consumerUrl || !consumerName || !consumerToolClientID || !consumerAuthorizationURL || !consumerAccessTokenURL || !consumerRedirect_URI || !consumerAuthorizationconfig ) { 35 | console.log('Error: registerPlatform function is missing argument.'); 36 | }; 37 | let existingPlatform; 38 | 39 | //checks database for existing platform. 40 | await Database.Get('platforms', platformSchema,{ 'consumerUrl': consumerUrl }) 41 | .then( (registeringPlatform) => { 42 | if (typeof registeringPlatform === 'undefined' || registeringPlatform.length === 0) { 43 | 44 | const keyPairs = keyGenerator(); 45 | 46 | // creates/inserts platform data into database. 47 | Database.Insert('platforms', platformSchema, { 48 | 'consumerUrl': consumerUrl, 49 | 'consumerName': consumerName, 50 | 'consumerToolClientID': consumerToolClientID, 51 | 'consumerAuthorizationURL': consumerAuthorizationURL, 52 | 'consumerAccessTokenURL': consumerAccessTokenURL, 53 | 'consumerRedirect_URI': consumerRedirect_URI, 54 | 'kid': keyPairs, 55 | 'consumerAuthorizationconfig': consumerAuthorizationconfig, 56 | }); 57 | return console.log(`Platform registered at: ${consumerUrl}`); 58 | } else { 59 | existingPlatform = registeringPlatform; 60 | return existingPlatform; 61 | }; 62 | }) 63 | .catch(err => console.log(`Error finding platform: ${err}`)); 64 | return existingPlatform; 65 | }; 66 | 67 | module.exports = { platformSchema, registerPlatform }; 68 | -------------------------------------------------------------------------------- /Provider/student_score.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | const { createHash } = require('crypto'); 3 | const { fromBase64, encode } = require('base64url'); 4 | const { passPhrase } = require('../Provider/keyGenerator'); 5 | 6 | /* 7 | * Check if Platform allows scores to be sent, if it does, request Authorization Code 8 | * @param payload - decoded Launch Request 9 | * @returns boolean of whether sending scores is in scope or not 10 | */ 11 | function prep_send_score(req) { 12 | if (req.session.decoded_launch.hasOwnProperty('https://purl.imsglobal.org/spec/lti-ags/claim/endpoint') && 13 | req.session.decoded_launch["https://purl.imsglobal.org/spec/lti-ags/claim/endpoint"].scope.includes('https://purl.imsglobal.org/spec/lti-ags/scope/score')) { 14 | return code_request(req, 'https://purl.imsglobal.org/spec/lti-ags/scope/score'); 15 | } else { 16 | return false; 17 | } 18 | } 19 | 20 | /* 21 | * Creates appropriate payload to request Authorization code for provided scope 22 | * @param req - original Request 23 | * @param scope - scope requested 24 | * @return - endpoint with parameters 25 | */ 26 | function code_request(req, scope) { 27 | const code_verifier = passPhrase(); 28 | req.session.code_verifier = code_verifier; 29 | 30 | const payload = { 31 | response_type: 'code', 32 | client_id: req.session.platform_DBinfo.consumerToolClientID, 33 | redirect_uri: 'https://piedpiper.localtunnel.me/auth_code', 34 | scope: scope, 35 | state: passPhrase(), 36 | code_challenge: generate_challenge(code_verifier), 37 | code_challenge_method: 'S256' 38 | }; 39 | return req.session.platform_DBinfo.consumerAuthorizationURL + '?' + Object.keys(payload).map(key => key + '=' + payload[key]).join('&'); 40 | } 41 | 42 | /* 43 | * Create BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) 44 | * @param code_verifier - random string to endcode 45 | * @returns encoded challenge 46 | */ 47 | function generate_challenge(code_verifier) { 48 | const hash = createHash('sha256') 49 | .update(code_verifier) 50 | .digest('base64'); 51 | return fromBase64(hash); 52 | } 53 | 54 | /* 55 | * Send score to Platform. Must get appropriate access token and then send score 56 | * @param req 57 | * @param score - final score for student's work 58 | * @param scoreMax - maximum score allowed for work 59 | */ 60 | function send_score(req, score, scoreMax) { 61 | //Request the access token 62 | const payload = { 63 | grant_type: 'authorization_code', 64 | code: req.params.code, 65 | client_id: req.session.platform_DBinfo.consumerToolClientID, 66 | redirect_uri: 'https://piedpiper.localtunnel.me/auth_code', 67 | scope: 'https://purl.imsglobal.org/spec/lti-ags/scope/score', 68 | code_verifier: req.session.code_verifier 69 | } 70 | const base64_user_pass = encode(req.session.platform_DBinfo.kid[0].keyID + ':' + req.session.platform_DBinfo.kid[0].privateKey, 'base64'); 71 | 72 | axios.post(req.session.platform_DBinfo.consumerAccessTokenURL, payload, 73 | { headers: { 74 | 'Authorization': 'Basic ' + base64_user_pass, 75 | 'Content-Type': 'application/x-www-form-urlencoded' 76 | } 77 | }) 78 | .then(result => { 79 | //With access token, send score to Platform 80 | const score_message = { 81 | "userId": req.session.payload.sub, 82 | "scoreGiven": score, 83 | "scoreMaximum": scoreMax, 84 | "timestamp": new Date(Date.now()).toJSON(), 85 | "activityProgress": "Completed", 86 | "gradingProgress": "FullyGraded" 87 | }; 88 | axios.post(req.session.payload["https://purl.imsglobal.org/spec/lti-ags/claim/endpoint"].lineitem + "/scores", 89 | score_message, 90 | { headers: { 91 | 'Authorization': result.token_type + ' ' + result.access_token, 92 | 'Content-Type': 'application/vnd.ims.lis.v1.score+json' 93 | }}) 94 | .then(success => console.log(success)) //successfully posted grade 95 | .catch(err => console.log(err)); //error posting grade 96 | }) 97 | .catch(err => console.log(err)); //error getting token 98 | } 99 | 100 | module.exports = { prep_send_score, send_score }; 101 | -------------------------------------------------------------------------------- /Provider/token_generator.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken'); 2 | const { valid_oauth2_request } = require("../Provider/oauth2_validation"); 3 | 4 | /* 5 | * Creates a JSON web token in accordance with the LTI 1.3 standard and in conjunction with Oauth 2.0 validation. 6 | * @param errors - errors array from validation 7 | * @param res - Result to send 8 | * @returns result with JWT, if successful, or an object with errors listed 9 | */ 10 | function tokenMaker(req, res) { 11 | let errors = valid_oauth2_request(req); 12 | 13 | if (errors.length === 0) { 14 | // no errors 15 | res.setHeader("Content-Type", "application/json;charset=UTF-8"); 16 | res.setHeader("Cache-Control", "no-store"); 17 | res.setHeader("Pragma", "no-cache"); 18 | const payload = { 19 | sub: req.body.client_id, 20 | expires_in: 3600, // 1 hour per IMS spec 21 | token_type: "bearer", 22 | scope: "" 23 | }; 24 | const jwt_payload = jwt.sign(payload, req.body.client_secret, { 25 | algorithm: "RS256" 26 | }); 27 | return res.status(200).send({ jwt: jwt_payload }); 28 | } else { 29 | if (errors.findIndex(e => e.includes("grant type invalid")) >= 0) { 30 | return res.status(400).send({ 31 | error: "unsupported_grant_type", 32 | errors: errors 33 | }); 34 | } else if (errors.findIndex(e => e.includes("invalid")) >= 0) { 35 | return res.status(401).send({ 36 | error: "invalid_client", 37 | errors: errors 38 | }); 39 | } else { 40 | return res.status(400).send({ 41 | error: "invalid_request", 42 | errors: errors 43 | }); 44 | } 45 | } 46 | } 47 | 48 | module.exports = { tokenMaker }; 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LTI 1.3 Compliant NodeJS Library for External Tool Integration 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | This Javascript-based Library allows an education provider to integrate web-based external Tools into their chosen learning Platform, such as Moodle, Blackboard, Edgenuity, etc, without needing to understand the underlying Learning Tools Interoperability (LTI) standards (https://www.imsglobal.org/activity/learning-tools-interoperability). 6 | 7 | This Library supports the LTI 1.3 Core standards, which implements up-to-date privacy and security standards. It also provides limited support the Assignment and Grade Services. 8 | 9 | In the future, this Library will be updated to fully support the LTI Advantage extensions for Assignments/Grades. At this time, LTI Advantage Names and Roles Provisioning Services and Deep Linking is not supported. 10 | 11 | ## Overview 12 | 13 | Follow these steps to implement this Library: 14 | 15 | 0. [Develop a Tool](#develop-a-tool) 16 | 2. [Install Library](#install-library) 17 | 3. [Setup Server and Routes](#setup-server-and-routes) 18 | 4. [Setup MongoDB](#setup-mongodb) 19 | 5. [Add Tool to Platform](#add-tool-to-platform) 20 | 6. [Register Platform with Tool](#register-platform-with-tool) 21 | 7. [Run your Server](#run-your-server) 22 | 23 | 24 | Optionally, you can: 25 | 26 | 1. Use Example Tool (https://github.com/SanDiegoCodeSchool/lti-node-example) 27 | 2. View the OIDC Tool Launch Flow (see the related 'lti-node-example' repo for this) 28 | 3. Use the Test Suite 29 | 4. View the Glossary 30 | 31 | ### Develop a Tool 32 | 33 | It is assumed if you are interested in integrating a Tool into a Platform, that you have already developed a working Tool. If not, Step 0 is to develop your Tool that will be dropped into a learning Platform. If you are not at that point yet, you can use the Example Tool related to this Library. 34 | 35 | ### Install Library 36 | 37 | To install this Library, use the Node Package Manager (NPM) and run in your terminal: 38 | 39 | ``` 40 | npm install lti-node-library 41 | ``` 42 | 43 | ### Setup Server and Routes 44 | 45 | This library requires the use of an Express server. Setup a basic Express server add middleware, and routes within your server.js file to launch your Tool. You can refer to the server.js example file in our Example Tool. 46 | 47 | In addition, add the following to your server: 48 | 49 | *Middleware to store session information* 50 | ``` 51 | app.use(session({ 52 | name: 'lti_v1p3_library', 53 | secret: 'iualcoelknasfnk', 54 | saveUninitialized: true, 55 | resave: true, 56 | secure: true, 57 | ephemeral: true, 58 | httpOnly: true, 59 | store: new MongoStore({ mongooseConnection: mongoose.connection }) 60 | })); 61 | ```` 62 | 63 | *Route to Handle OIDC Login Requests* 64 | ``` 65 | app.post('/oidc', (req, res) => { 66 | create_oidc_response(req, res); 67 | }); 68 | ``` 69 | 70 | *Route to Handle Tool Launches, 'route to add to Base URL' can be an empty string if unneeded* 71 | ``` 72 | app.post('/project/submit', (req, res) => { 73 | launchTool(req, res, < route to add to Base URL, if any >); 74 | }); 75 | ``` 76 | 77 | *Route to send score back to Platform* 78 | ``` 79 | app.post('/auth_code', (req, res) => { 80 | if (!req.body.error) { 81 | send_score(req, req.session.grade, < maximum grade allowed >); 82 | } else { 83 | res.status(401).send('Access denied: ' + req.params.error); 84 | } 85 | }); 86 | ``` 87 | 88 | *Within your Tool's route where grading is performed, set up the score to be returned to the Platform.* 89 | This initiates the score submission, which will end at the above /auth_code route where the score is finally sent 90 | ``` 91 | req.session.grade = < student's grade >; 92 | res.redirect(307, prep_send_score(req)); 93 | ``` 94 | 95 | *Route to return from Tool to Platform* 96 | ``` 97 | app.post('/project/return', (req, res) => { 98 | res.redirect(req.session.decoded_launch["https://purl.imsglobal.org/spec/lti/claim/launch_presentation"].return_url); 99 | req.session.destroy(); 100 | }); 101 | ``` 102 | 103 | ### Setup MongoDB 104 | 105 | This library requires MongoDB. If you do not currently have MongoDB setup, follow these instructions. 106 | 107 | * MacOS - use homebrew: https://docs.mongodb.com/master/tutorial/install-mongodb-on-os-x/ 108 | * Windows - use the installer from here: https://docs.mongodb.com/master/tutorial/install-mongodb-on-windows/ 109 | * Linux - choose your flavor to install here: https://docs.mongodb.com/master/administration/install-on-linux/ 110 | 111 | Add the following to your server.js file: 112 | ``` 113 | mongoose.connect('mongodb://localhost:27017/TESTLTI', { 114 | useNewUrlParser: true, 115 | }, 116 | (err) => { 117 | if(err) { 118 | return console.log(err); 119 | } 120 | }); 121 | mongoose.Promise = Promise; 122 | ``` 123 | 124 | ### Add Tool to Platform 125 | 126 | Within the Platform, the Site Administrator needs to setup the External Tool. For example, in Moodle s/he goes to Site Administration->Plugins->External Tool->Manage Tools. At a minimum, the following fields should be setup: 127 | 128 | - Tool's Name 129 | - Tool's Base URL 130 | - Tool's Description, if desired 131 | - Mark the tool as a 'LTI1.3' Tool 132 | - Tool's Public Key -- you will need to come back and add this in a moment, see below about obtaining your Public key 133 | - Initiate Login URL - < Tool Base URL > + '/oidc' 134 | - Redirection URIs - all of the endpoints that may be used, for example < Tool Base URL >/project/submit 135 | - Enable Assignment and Grade Services, if Tool should send grades to Platform 136 | - Enable sharing of launcher's name, if Tool should have ability to display this information 137 | - Choose 'Always' Accept grades from the Tool, if Tool should send grades to Platform 138 | 139 | After saving the External Tool, the Platform will assign a Client ID to the Tool and provide endpoints. Make note of all of this information as it will be used in Step 5. 140 | 141 | The next step will be to add the Tool to course(s). This can be done by an Administrator or a Teacher. In Moodle, the steps are to navigate the appropriate course and use the Gear icon to `Turn editing on`. You will then be able to `Add an Activty or Resource` for an `External Tool`. Simply give it a name and select the Tool you added above from the drop down box for `Preconfigured tool`. Click `Save and return to course`. 142 | 143 | ### Register Platform with Tool 144 | 145 | In order register a Platform with the Tool, add a call to `registerPlatform` in your server file, with the values you received from Step 4. For reference, here is a screenshot from the Moodle sandbox showing these values: 146 | 147 | ![Moodle Tool Config](./Moodle_Tool_Config.png "this screenshot from Moodle") 148 | ``` 149 | registerPlatform( 150 | consumerUrl, // Base url of the Platform (1st line on screenshot - Platform ID from Moodle). 151 | consumerName, // Domain name of the Platform, e.g., moodle 152 | consumerToolClientID, // Client ID generated upon configuration of an external tool on the platform. (2nd line on screenshot) 153 | consumerAuthorizationURL, // URL that the Tool sends Authorization Requests/Responses to. (6th line on screen shot, Authentication request URL) 154 | consumerAccessTokenURL, // URL that the Tool can use to obtain an access Tokens. (5th line on screen shot, Access Token URL) 155 | consumerRedirectURL // Tool's base URL PLUS slash route where Example Tool is served from. e.g., locally: '' // cloud: 'https://node-lti-v1p3.herokuapp.com/' PLUS '/project/submit' 156 | consumerAuthorizationconfig, // WILL always be an object with two properties: Authentication method and key for verifying messages from the Platform. (method will be "JWK_SET" and key will be on 4th line of screen shot, Public keyset URL) 157 | ); 158 | ``` 159 | For example: 160 | ``` 161 | registerPlatform( 162 | 'https://demo.moodle.net', 163 | 'moodle', 164 | 'BMe642xnf4ag3Pd', 165 | 'https://demo.moodle.net/mod/lti/auth.php', 166 | 'https://demo.moodle.net/mod/lti/token.php', 167 | 'https://piedpiper.localtunnel.me/project/submit', 168 | { method: 'JWK_SET', key: 'https://demo.moodle.net/mod/lti/certs.php' } 169 | ); 170 | ``` 171 | 172 | ### Run your Server 173 | 174 | Once the Tool is integrated with the Platform, your server must be up and running so that the Tool can be accessed. In a development environment, start your MongoDB and your server in separate terminals: 175 | 176 | ``` 177 | mongod 178 | npm start 179 | ``` 180 | 181 | Now that your server is running, you are able to access the Tool's generated Client Public key by making a GET request with `` as a parameter to `/publickey`. This key must be put into the Tool's Public Key field in Step 4 above on the Platform. 182 | 183 | --- 184 | 185 | ### Optional Activities 186 | 187 | #### Test Suite 188 | 189 | The Library provides a test suite to verify portions of the basic functionality. 190 | 191 | To launch the automated tests for this Library, run in separate terminals: 192 | 193 | ``` 194 | mongod 195 | npm test 196 | ``` 197 | 198 | --- 199 | 200 | #### Glossary 201 | 202 | JWT - JSON Web Tokens (JWTs) are an open, industry standard that supports securely transmitting information between parties as a JSON object. Signed tokens can verify the integrity of the claims contained within it. (https://openid.net/specs/draft-jones-json-web-token-07.html). 203 | 204 | LTI 1.3 - The IMS Learning Tools Interoperability specification ((https://www.imsglobal.org/spec/lti/v1p3)) allows Platforms to integrate external Tools and content in a standard way. As of 2019, LTI v1p3 is the latest standard. 205 | 206 | LTI Advantage - Services (https://www.imsglobal.org/spec/lti/v1p3/impl) built on top of LTI 1.3 for: 207 | * Assignment and Grades Services - (https://www.imsglobal.org/spec/lti-ags/v2p0) 208 | * Names and Roles Provisioning Services (https://www.imsglobal.org/spec/lti-nrps/v2p0/) 209 | * Deep Linking Services (https://www.imsglobal.org/spec/lti-dl/v2p0/) 210 | 211 | LTI v1.3 and the LTI Advantage - together this set of services incorporate a new model for secure message and service authentication with OAuth 2.0. (https://www.imsglobal.org/activity/learning-tools-interoperability) 212 | 213 | LMS - Learning Management System. Referred to as Platforms in this document. 214 | 215 | OAuth 2.0 - LTI 1.3 specifies the use of the OAuth 2.0 Client Credential Grant mechanism to secure web services between trusted systems. This Library makes use of JSON Web Tokens, JWT, for the access tokens. (https://www.imsglobal.org/spec/security/v1p0) 216 | 217 | OIDC - OpenID Connect is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner. https://openid.net/connect/ 218 | 219 | Platform - previously referred to as the Tool Consumer is the Learning Management System (LMS) that the educational provider is using. Examples are Moodle, Blackboard, Edgenuity, Canvas, Schoology, etc. 220 | 221 | Tool - previously referred to as the Tool Provider, this is the external Tool that contains educational material to include in a course. Tools can range from a single piece of content, for example a quiz, to an extensive interactive website featuring specialized course content. 222 | 223 | --- 224 | 225 | #### Contributors 226 | * Argenis De Los Santos 227 | * Gian Delprado 228 | * Godfrey Martinez 229 | * Michael Roberts 230 | * Sherry Freitas 231 | 232 | --- 233 | 234 | #### Keywords 235 | 236 | LTI LMS Tool LTIv1.3 Node/Express Javascript 237 | -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SanDiegoCodeSchool/lti-node-library/8bfe9af23738ae8dd705fb7be1e369e396ba47c6/favicon.ico -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lti-node-library", 3 | "version": "0.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abbrev": { 8 | "version": "1.1.1", 9 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", 10 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" 11 | }, 12 | "accepts": { 13 | "version": "1.3.7", 14 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 15 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 16 | "requires": { 17 | "mime-types": "~2.1.24", 18 | "negotiator": "0.6.2" 19 | } 20 | }, 21 | "ansi-align": { 22 | "version": "2.0.0", 23 | "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", 24 | "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", 25 | "requires": { 26 | "string-width": "^2.0.0" 27 | } 28 | }, 29 | "ansi-colors": { 30 | "version": "3.2.3", 31 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", 32 | "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", 33 | "dev": true 34 | }, 35 | "ansi-regex": { 36 | "version": "3.0.0", 37 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 38 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 39 | }, 40 | "ansi-styles": { 41 | "version": "3.2.1", 42 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 43 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 44 | "requires": { 45 | "color-convert": "^1.9.0" 46 | } 47 | }, 48 | "anymatch": { 49 | "version": "2.0.0", 50 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", 51 | "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", 52 | "requires": { 53 | "micromatch": "^3.1.4", 54 | "normalize-path": "^2.1.1" 55 | }, 56 | "dependencies": { 57 | "normalize-path": { 58 | "version": "2.1.1", 59 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", 60 | "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", 61 | "requires": { 62 | "remove-trailing-separator": "^1.0.1" 63 | } 64 | } 65 | } 66 | }, 67 | "argparse": { 68 | "version": "1.0.10", 69 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 70 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 71 | "dev": true, 72 | "requires": { 73 | "sprintf-js": "~1.0.2" 74 | } 75 | }, 76 | "arr-diff": { 77 | "version": "4.0.0", 78 | "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", 79 | "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" 80 | }, 81 | "arr-flatten": { 82 | "version": "1.1.0", 83 | "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", 84 | "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" 85 | }, 86 | "arr-union": { 87 | "version": "3.1.0", 88 | "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", 89 | "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" 90 | }, 91 | "array-flatten": { 92 | "version": "1.1.1", 93 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 94 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 95 | }, 96 | "array-unique": { 97 | "version": "0.3.2", 98 | "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", 99 | "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" 100 | }, 101 | "asn1.js": { 102 | "version": "4.10.1", 103 | "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", 104 | "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", 105 | "requires": { 106 | "bn.js": "^4.0.0", 107 | "inherits": "^2.0.1", 108 | "minimalistic-assert": "^1.0.0" 109 | } 110 | }, 111 | "assertion-error": { 112 | "version": "1.1.0", 113 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", 114 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", 115 | "dev": true 116 | }, 117 | "assign-symbols": { 118 | "version": "1.0.0", 119 | "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", 120 | "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" 121 | }, 122 | "async": { 123 | "version": "2.6.2", 124 | "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", 125 | "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", 126 | "requires": { 127 | "lodash": "^4.17.11" 128 | } 129 | }, 130 | "async-each": { 131 | "version": "1.0.3", 132 | "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", 133 | "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" 134 | }, 135 | "atob": { 136 | "version": "2.1.2", 137 | "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", 138 | "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" 139 | }, 140 | "axios": { 141 | "version": "0.19.0", 142 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", 143 | "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", 144 | "requires": { 145 | "follow-redirects": "1.5.10", 146 | "is-buffer": "^2.0.2" 147 | } 148 | }, 149 | "balanced-match": { 150 | "version": "1.0.0", 151 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 152 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 153 | }, 154 | "base": { 155 | "version": "0.11.2", 156 | "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", 157 | "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", 158 | "requires": { 159 | "cache-base": "^1.0.1", 160 | "class-utils": "^0.3.5", 161 | "component-emitter": "^1.2.1", 162 | "define-property": "^1.0.0", 163 | "isobject": "^3.0.1", 164 | "mixin-deep": "^1.2.0", 165 | "pascalcase": "^0.1.1" 166 | }, 167 | "dependencies": { 168 | "define-property": { 169 | "version": "1.0.0", 170 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", 171 | "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", 172 | "requires": { 173 | "is-descriptor": "^1.0.0" 174 | } 175 | }, 176 | "is-accessor-descriptor": { 177 | "version": "1.0.0", 178 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", 179 | "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", 180 | "requires": { 181 | "kind-of": "^6.0.0" 182 | } 183 | }, 184 | "is-data-descriptor": { 185 | "version": "1.0.0", 186 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", 187 | "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", 188 | "requires": { 189 | "kind-of": "^6.0.0" 190 | } 191 | }, 192 | "is-descriptor": { 193 | "version": "1.0.2", 194 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", 195 | "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", 196 | "requires": { 197 | "is-accessor-descriptor": "^1.0.0", 198 | "is-data-descriptor": "^1.0.0", 199 | "kind-of": "^6.0.2" 200 | } 201 | } 202 | } 203 | }, 204 | "base64url": { 205 | "version": "3.0.1", 206 | "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", 207 | "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" 208 | }, 209 | "basic-auth": { 210 | "version": "2.0.1", 211 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", 212 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", 213 | "requires": { 214 | "safe-buffer": "5.1.2" 215 | }, 216 | "dependencies": { 217 | "safe-buffer": { 218 | "version": "5.1.2", 219 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 220 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 221 | } 222 | } 223 | }, 224 | "binary-extensions": { 225 | "version": "1.13.1", 226 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", 227 | "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" 228 | }, 229 | "bluebird": { 230 | "version": "3.5.1", 231 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", 232 | "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" 233 | }, 234 | "bn.js": { 235 | "version": "4.11.8", 236 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", 237 | "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" 238 | }, 239 | "body-parser": { 240 | "version": "1.19.0", 241 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 242 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 243 | "requires": { 244 | "bytes": "3.1.0", 245 | "content-type": "~1.0.4", 246 | "debug": "2.6.9", 247 | "depd": "~1.1.2", 248 | "http-errors": "1.7.2", 249 | "iconv-lite": "0.4.24", 250 | "on-finished": "~2.3.0", 251 | "qs": "6.7.0", 252 | "raw-body": "2.4.0", 253 | "type-is": "~1.6.17" 254 | }, 255 | "dependencies": { 256 | "debug": { 257 | "version": "2.6.9", 258 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 259 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 260 | "requires": { 261 | "ms": "2.0.0" 262 | } 263 | } 264 | } 265 | }, 266 | "boxen": { 267 | "version": "1.3.0", 268 | "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", 269 | "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", 270 | "requires": { 271 | "ansi-align": "^2.0.0", 272 | "camelcase": "^4.0.0", 273 | "chalk": "^2.0.1", 274 | "cli-boxes": "^1.0.0", 275 | "string-width": "^2.0.0", 276 | "term-size": "^1.2.0", 277 | "widest-line": "^2.0.0" 278 | } 279 | }, 280 | "brace-expansion": { 281 | "version": "1.1.11", 282 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 283 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 284 | "requires": { 285 | "balanced-match": "^1.0.0", 286 | "concat-map": "0.0.1" 287 | } 288 | }, 289 | "braces": { 290 | "version": "2.3.2", 291 | "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", 292 | "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", 293 | "requires": { 294 | "arr-flatten": "^1.1.0", 295 | "array-unique": "^0.3.2", 296 | "extend-shallow": "^2.0.1", 297 | "fill-range": "^4.0.0", 298 | "isobject": "^3.0.1", 299 | "repeat-element": "^1.1.2", 300 | "snapdragon": "^0.8.1", 301 | "snapdragon-node": "^2.0.1", 302 | "split-string": "^3.0.2", 303 | "to-regex": "^3.0.1" 304 | }, 305 | "dependencies": { 306 | "extend-shallow": { 307 | "version": "2.0.1", 308 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", 309 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", 310 | "requires": { 311 | "is-extendable": "^0.1.0" 312 | } 313 | } 314 | } 315 | }, 316 | "brorand": { 317 | "version": "1.1.0", 318 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", 319 | "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" 320 | }, 321 | "browser-stdout": { 322 | "version": "1.3.1", 323 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 324 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 325 | "dev": true 326 | }, 327 | "bson": { 328 | "version": "1.1.1", 329 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.1.tgz", 330 | "integrity": "sha512-jCGVYLoYMHDkOsbwJZBCqwMHyH4c+wzgI9hG7Z6SZJRXWr+x58pdIbm2i9a/jFGCkRJqRUr8eoI7lDWa0hTkxg==" 331 | }, 332 | "buffer-equal-constant-time": { 333 | "version": "1.0.1", 334 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", 335 | "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" 336 | }, 337 | "bytes": { 338 | "version": "3.1.0", 339 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 340 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 341 | }, 342 | "cache-base": { 343 | "version": "1.0.1", 344 | "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", 345 | "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", 346 | "requires": { 347 | "collection-visit": "^1.0.0", 348 | "component-emitter": "^1.2.1", 349 | "get-value": "^2.0.6", 350 | "has-value": "^1.0.0", 351 | "isobject": "^3.0.1", 352 | "set-value": "^2.0.0", 353 | "to-object-path": "^0.3.0", 354 | "union-value": "^1.0.0", 355 | "unset-value": "^1.0.0" 356 | } 357 | }, 358 | "camelcase": { 359 | "version": "4.1.0", 360 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", 361 | "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" 362 | }, 363 | "capture-stack-trace": { 364 | "version": "1.0.1", 365 | "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", 366 | "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==" 367 | }, 368 | "chai": { 369 | "version": "4.2.0", 370 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", 371 | "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", 372 | "dev": true, 373 | "requires": { 374 | "assertion-error": "^1.1.0", 375 | "check-error": "^1.0.2", 376 | "deep-eql": "^3.0.1", 377 | "get-func-name": "^2.0.0", 378 | "pathval": "^1.1.0", 379 | "type-detect": "^4.0.5" 380 | } 381 | }, 382 | "chalk": { 383 | "version": "2.4.2", 384 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 385 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 386 | "requires": { 387 | "ansi-styles": "^3.2.1", 388 | "escape-string-regexp": "^1.0.5", 389 | "supports-color": "^5.3.0" 390 | } 391 | }, 392 | "check-error": { 393 | "version": "1.0.2", 394 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 395 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", 396 | "dev": true 397 | }, 398 | "chokidar": { 399 | "version": "2.1.6", 400 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", 401 | "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", 402 | "requires": { 403 | "anymatch": "^2.0.0", 404 | "async-each": "^1.0.1", 405 | "braces": "^2.3.2", 406 | "fsevents": "^1.2.7", 407 | "glob-parent": "^3.1.0", 408 | "inherits": "^2.0.3", 409 | "is-binary-path": "^1.0.0", 410 | "is-glob": "^4.0.0", 411 | "normalize-path": "^3.0.0", 412 | "path-is-absolute": "^1.0.0", 413 | "readdirp": "^2.2.1", 414 | "upath": "^1.1.1" 415 | } 416 | }, 417 | "ci-info": { 418 | "version": "1.6.0", 419 | "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", 420 | "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==" 421 | }, 422 | "class-utils": { 423 | "version": "0.3.6", 424 | "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", 425 | "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", 426 | "requires": { 427 | "arr-union": "^3.1.0", 428 | "define-property": "^0.2.5", 429 | "isobject": "^3.0.0", 430 | "static-extend": "^0.1.1" 431 | }, 432 | "dependencies": { 433 | "define-property": { 434 | "version": "0.2.5", 435 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", 436 | "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", 437 | "requires": { 438 | "is-descriptor": "^0.1.0" 439 | } 440 | } 441 | } 442 | }, 443 | "cli-boxes": { 444 | "version": "1.0.0", 445 | "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", 446 | "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" 447 | }, 448 | "cliui": { 449 | "version": "4.1.0", 450 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", 451 | "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", 452 | "dev": true, 453 | "requires": { 454 | "string-width": "^2.1.1", 455 | "strip-ansi": "^4.0.0", 456 | "wrap-ansi": "^2.0.0" 457 | } 458 | }, 459 | "code-point-at": { 460 | "version": "1.1.0", 461 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 462 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", 463 | "dev": true 464 | }, 465 | "collection-visit": { 466 | "version": "1.0.0", 467 | "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", 468 | "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", 469 | "requires": { 470 | "map-visit": "^1.0.0", 471 | "object-visit": "^1.0.0" 472 | } 473 | }, 474 | "color-convert": { 475 | "version": "1.9.3", 476 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 477 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 478 | "requires": { 479 | "color-name": "1.1.3" 480 | } 481 | }, 482 | "color-name": { 483 | "version": "1.1.3", 484 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 485 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 486 | }, 487 | "component-emitter": { 488 | "version": "1.3.0", 489 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", 490 | "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" 491 | }, 492 | "concat-map": { 493 | "version": "0.0.1", 494 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 495 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 496 | }, 497 | "configstore": { 498 | "version": "3.1.2", 499 | "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", 500 | "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", 501 | "requires": { 502 | "dot-prop": "^4.1.0", 503 | "graceful-fs": "^4.1.2", 504 | "make-dir": "^1.0.0", 505 | "unique-string": "^1.0.0", 506 | "write-file-atomic": "^2.0.0", 507 | "xdg-basedir": "^3.0.0" 508 | } 509 | }, 510 | "connect-mongo": { 511 | "version": "3.0.0", 512 | "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-3.0.0.tgz", 513 | "integrity": "sha512-Y95urWNGrAoKY2w31s7Q9Gs/W3qdMCshUIeDTgulssHi6KueYtz4XrbV3kcnQaR8EcBQvooNNX7aOaAJDgudag==", 514 | "requires": { 515 | "mongodb": "^3.1.0" 516 | } 517 | }, 518 | "content-disposition": { 519 | "version": "0.5.3", 520 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 521 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 522 | "requires": { 523 | "safe-buffer": "5.1.2" 524 | }, 525 | "dependencies": { 526 | "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 | } 532 | }, 533 | "content-type": { 534 | "version": "1.0.4", 535 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 536 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 537 | }, 538 | "cookie": { 539 | "version": "0.4.0", 540 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 541 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 542 | }, 543 | "cookie-signature": { 544 | "version": "1.0.6", 545 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 546 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 547 | }, 548 | "copy-descriptor": { 549 | "version": "0.1.1", 550 | "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", 551 | "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" 552 | }, 553 | "core-util-is": { 554 | "version": "1.0.2", 555 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 556 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 557 | }, 558 | "create-error-class": { 559 | "version": "3.0.2", 560 | "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", 561 | "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", 562 | "requires": { 563 | "capture-stack-trace": "^1.0.0" 564 | } 565 | }, 566 | "cross-spawn": { 567 | "version": "5.1.0", 568 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 569 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", 570 | "requires": { 571 | "lru-cache": "^4.0.1", 572 | "shebang-command": "^1.2.0", 573 | "which": "^1.2.9" 574 | } 575 | }, 576 | "crypto-random-string": { 577 | "version": "1.0.0", 578 | "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", 579 | "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" 580 | }, 581 | "debug": { 582 | "version": "3.1.0", 583 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 584 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 585 | "requires": { 586 | "ms": "2.0.0" 587 | } 588 | }, 589 | "decamelize": { 590 | "version": "1.2.0", 591 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 592 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 593 | "dev": true 594 | }, 595 | "decode-uri-component": { 596 | "version": "0.2.0", 597 | "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", 598 | "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" 599 | }, 600 | "deep-eql": { 601 | "version": "3.0.1", 602 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 603 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 604 | "dev": true, 605 | "requires": { 606 | "type-detect": "^4.0.0" 607 | } 608 | }, 609 | "deep-extend": { 610 | "version": "0.6.0", 611 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", 612 | "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" 613 | }, 614 | "define-properties": { 615 | "version": "1.1.3", 616 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 617 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 618 | "dev": true, 619 | "requires": { 620 | "object-keys": "^1.0.12" 621 | } 622 | }, 623 | "define-property": { 624 | "version": "2.0.2", 625 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", 626 | "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", 627 | "requires": { 628 | "is-descriptor": "^1.0.2", 629 | "isobject": "^3.0.1" 630 | }, 631 | "dependencies": { 632 | "is-accessor-descriptor": { 633 | "version": "1.0.0", 634 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", 635 | "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", 636 | "requires": { 637 | "kind-of": "^6.0.0" 638 | } 639 | }, 640 | "is-data-descriptor": { 641 | "version": "1.0.0", 642 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", 643 | "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", 644 | "requires": { 645 | "kind-of": "^6.0.0" 646 | } 647 | }, 648 | "is-descriptor": { 649 | "version": "1.0.2", 650 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", 651 | "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", 652 | "requires": { 653 | "is-accessor-descriptor": "^1.0.0", 654 | "is-data-descriptor": "^1.0.0", 655 | "kind-of": "^6.0.2" 656 | } 657 | } 658 | } 659 | }, 660 | "depd": { 661 | "version": "1.1.2", 662 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 663 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 664 | }, 665 | "destroy": { 666 | "version": "1.0.4", 667 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 668 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 669 | }, 670 | "diff": { 671 | "version": "3.5.0", 672 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 673 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 674 | "dev": true 675 | }, 676 | "dot-prop": { 677 | "version": "4.2.0", 678 | "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", 679 | "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", 680 | "requires": { 681 | "is-obj": "^1.0.0" 682 | } 683 | }, 684 | "dotenv": { 685 | "version": "8.0.0", 686 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.0.0.tgz", 687 | "integrity": "sha512-30xVGqjLjiUOArT4+M5q9sYdvuR4riM6yK9wMcas9Vbp6zZa+ocC9dp6QoftuhTPhFAiLK/0C5Ni2nou/Bk8lg==" 688 | }, 689 | "duplexer3": { 690 | "version": "0.1.4", 691 | "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", 692 | "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" 693 | }, 694 | "ecdsa-sig-formatter": { 695 | "version": "1.0.11", 696 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", 697 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", 698 | "requires": { 699 | "safe-buffer": "^5.0.1" 700 | } 701 | }, 702 | "ee-first": { 703 | "version": "1.1.1", 704 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 705 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 706 | }, 707 | "ejs": { 708 | "version": "2.6.2", 709 | "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.2.tgz", 710 | "integrity": "sha512-PcW2a0tyTuPHz3tWyYqtK6r1fZ3gp+3Sop8Ph+ZYN81Ob5rwmbHEzaqs10N3BEsaGTkh/ooniXK+WwszGlc2+Q==" 711 | }, 712 | "elliptic": { 713 | "version": "6.5.0", 714 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", 715 | "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", 716 | "requires": { 717 | "bn.js": "^4.4.0", 718 | "brorand": "^1.0.1", 719 | "hash.js": "^1.0.0", 720 | "hmac-drbg": "^1.0.0", 721 | "inherits": "^2.0.1", 722 | "minimalistic-assert": "^1.0.0", 723 | "minimalistic-crypto-utils": "^1.0.0" 724 | } 725 | }, 726 | "emoji-regex": { 727 | "version": "7.0.3", 728 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 729 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 730 | "dev": true 731 | }, 732 | "encodeurl": { 733 | "version": "1.0.2", 734 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 735 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 736 | }, 737 | "end-of-stream": { 738 | "version": "1.4.1", 739 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", 740 | "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", 741 | "dev": true, 742 | "requires": { 743 | "once": "^1.4.0" 744 | } 745 | }, 746 | "es-abstract": { 747 | "version": "1.13.0", 748 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", 749 | "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", 750 | "dev": true, 751 | "requires": { 752 | "es-to-primitive": "^1.2.0", 753 | "function-bind": "^1.1.1", 754 | "has": "^1.0.3", 755 | "is-callable": "^1.1.4", 756 | "is-regex": "^1.0.4", 757 | "object-keys": "^1.0.12" 758 | } 759 | }, 760 | "es-to-primitive": { 761 | "version": "1.2.0", 762 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", 763 | "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", 764 | "dev": true, 765 | "requires": { 766 | "is-callable": "^1.1.4", 767 | "is-date-object": "^1.0.1", 768 | "is-symbol": "^1.0.2" 769 | } 770 | }, 771 | "escape-html": { 772 | "version": "1.0.3", 773 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 774 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 775 | }, 776 | "escape-string-regexp": { 777 | "version": "1.0.5", 778 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 779 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 780 | }, 781 | "esprima": { 782 | "version": "4.0.1", 783 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 784 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 785 | "dev": true 786 | }, 787 | "etag": { 788 | "version": "1.8.1", 789 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 790 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 791 | }, 792 | "execa": { 793 | "version": "0.7.0", 794 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", 795 | "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", 796 | "requires": { 797 | "cross-spawn": "^5.0.1", 798 | "get-stream": "^3.0.0", 799 | "is-stream": "^1.1.0", 800 | "npm-run-path": "^2.0.0", 801 | "p-finally": "^1.0.0", 802 | "signal-exit": "^3.0.0", 803 | "strip-eof": "^1.0.0" 804 | } 805 | }, 806 | "expand-brackets": { 807 | "version": "2.1.4", 808 | "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", 809 | "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", 810 | "requires": { 811 | "debug": "^2.3.3", 812 | "define-property": "^0.2.5", 813 | "extend-shallow": "^2.0.1", 814 | "posix-character-classes": "^0.1.0", 815 | "regex-not": "^1.0.0", 816 | "snapdragon": "^0.8.1", 817 | "to-regex": "^3.0.1" 818 | }, 819 | "dependencies": { 820 | "debug": { 821 | "version": "2.6.9", 822 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 823 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 824 | "requires": { 825 | "ms": "2.0.0" 826 | } 827 | }, 828 | "define-property": { 829 | "version": "0.2.5", 830 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", 831 | "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", 832 | "requires": { 833 | "is-descriptor": "^0.1.0" 834 | } 835 | }, 836 | "extend-shallow": { 837 | "version": "2.0.1", 838 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", 839 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", 840 | "requires": { 841 | "is-extendable": "^0.1.0" 842 | } 843 | } 844 | } 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 | "dependencies": { 883 | "debug": { 884 | "version": "2.6.9", 885 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 886 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 887 | "requires": { 888 | "ms": "2.0.0" 889 | } 890 | }, 891 | "safe-buffer": { 892 | "version": "5.1.2", 893 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 894 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 895 | } 896 | } 897 | }, 898 | "express-session": { 899 | "version": "1.16.2", 900 | "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.16.2.tgz", 901 | "integrity": "sha512-oy0sRsdw6n93E9wpCNWKRnSsxYnSDX9Dnr9mhZgqUEEorzcq5nshGYSZ4ZReHFhKQ80WI5iVUUSPW7u3GaKauw==", 902 | "requires": { 903 | "cookie": "0.3.1", 904 | "cookie-signature": "1.0.6", 905 | "debug": "2.6.9", 906 | "depd": "~2.0.0", 907 | "on-headers": "~1.0.2", 908 | "parseurl": "~1.3.3", 909 | "safe-buffer": "5.1.2", 910 | "uid-safe": "~2.1.5" 911 | }, 912 | "dependencies": { 913 | "cookie": { 914 | "version": "0.3.1", 915 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 916 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 917 | }, 918 | "debug": { 919 | "version": "2.6.9", 920 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 921 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 922 | "requires": { 923 | "ms": "2.0.0" 924 | } 925 | }, 926 | "depd": { 927 | "version": "2.0.0", 928 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 929 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" 930 | }, 931 | "safe-buffer": { 932 | "version": "5.1.2", 933 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 934 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 935 | } 936 | } 937 | }, 938 | "extend-shallow": { 939 | "version": "3.0.2", 940 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", 941 | "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", 942 | "requires": { 943 | "assign-symbols": "^1.0.0", 944 | "is-extendable": "^1.0.1" 945 | }, 946 | "dependencies": { 947 | "is-extendable": { 948 | "version": "1.0.1", 949 | "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", 950 | "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", 951 | "requires": { 952 | "is-plain-object": "^2.0.4" 953 | } 954 | } 955 | } 956 | }, 957 | "extglob": { 958 | "version": "2.0.4", 959 | "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", 960 | "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", 961 | "requires": { 962 | "array-unique": "^0.3.2", 963 | "define-property": "^1.0.0", 964 | "expand-brackets": "^2.1.4", 965 | "extend-shallow": "^2.0.1", 966 | "fragment-cache": "^0.2.1", 967 | "regex-not": "^1.0.0", 968 | "snapdragon": "^0.8.1", 969 | "to-regex": "^3.0.1" 970 | }, 971 | "dependencies": { 972 | "define-property": { 973 | "version": "1.0.0", 974 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", 975 | "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", 976 | "requires": { 977 | "is-descriptor": "^1.0.0" 978 | } 979 | }, 980 | "extend-shallow": { 981 | "version": "2.0.1", 982 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", 983 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", 984 | "requires": { 985 | "is-extendable": "^0.1.0" 986 | } 987 | }, 988 | "is-accessor-descriptor": { 989 | "version": "1.0.0", 990 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", 991 | "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", 992 | "requires": { 993 | "kind-of": "^6.0.0" 994 | } 995 | }, 996 | "is-data-descriptor": { 997 | "version": "1.0.0", 998 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", 999 | "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", 1000 | "requires": { 1001 | "kind-of": "^6.0.0" 1002 | } 1003 | }, 1004 | "is-descriptor": { 1005 | "version": "1.0.2", 1006 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", 1007 | "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", 1008 | "requires": { 1009 | "is-accessor-descriptor": "^1.0.0", 1010 | "is-data-descriptor": "^1.0.0", 1011 | "kind-of": "^6.0.2" 1012 | } 1013 | } 1014 | } 1015 | }, 1016 | "fill-range": { 1017 | "version": "4.0.0", 1018 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", 1019 | "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", 1020 | "requires": { 1021 | "extend-shallow": "^2.0.1", 1022 | "is-number": "^3.0.0", 1023 | "repeat-string": "^1.6.1", 1024 | "to-regex-range": "^2.1.0" 1025 | }, 1026 | "dependencies": { 1027 | "extend-shallow": { 1028 | "version": "2.0.1", 1029 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", 1030 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", 1031 | "requires": { 1032 | "is-extendable": "^0.1.0" 1033 | } 1034 | } 1035 | } 1036 | }, 1037 | "finalhandler": { 1038 | "version": "1.1.2", 1039 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 1040 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 1041 | "requires": { 1042 | "debug": "2.6.9", 1043 | "encodeurl": "~1.0.2", 1044 | "escape-html": "~1.0.3", 1045 | "on-finished": "~2.3.0", 1046 | "parseurl": "~1.3.3", 1047 | "statuses": "~1.5.0", 1048 | "unpipe": "~1.0.0" 1049 | }, 1050 | "dependencies": { 1051 | "debug": { 1052 | "version": "2.6.9", 1053 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1054 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1055 | "requires": { 1056 | "ms": "2.0.0" 1057 | } 1058 | } 1059 | } 1060 | }, 1061 | "find-up": { 1062 | "version": "3.0.0", 1063 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 1064 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 1065 | "dev": true, 1066 | "requires": { 1067 | "locate-path": "^3.0.0" 1068 | } 1069 | }, 1070 | "flat": { 1071 | "version": "4.1.0", 1072 | "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", 1073 | "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", 1074 | "dev": true, 1075 | "requires": { 1076 | "is-buffer": "~2.0.3" 1077 | } 1078 | }, 1079 | "follow-redirects": { 1080 | "version": "1.5.10", 1081 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", 1082 | "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", 1083 | "requires": { 1084 | "debug": "=3.1.0" 1085 | } 1086 | }, 1087 | "for-in": { 1088 | "version": "1.0.2", 1089 | "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", 1090 | "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" 1091 | }, 1092 | "forwarded": { 1093 | "version": "0.1.2", 1094 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 1095 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 1096 | }, 1097 | "fragment-cache": { 1098 | "version": "0.2.1", 1099 | "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", 1100 | "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", 1101 | "requires": { 1102 | "map-cache": "^0.2.2" 1103 | } 1104 | }, 1105 | "fresh": { 1106 | "version": "0.5.2", 1107 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1108 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 1109 | }, 1110 | "fs.realpath": { 1111 | "version": "1.0.0", 1112 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1113 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 1114 | "dev": true 1115 | }, 1116 | "fsevents": { 1117 | "version": "1.2.9", 1118 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", 1119 | "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", 1120 | "optional": true, 1121 | "requires": { 1122 | "nan": "^2.12.1", 1123 | "node-pre-gyp": "^0.12.0" 1124 | }, 1125 | "dependencies": { 1126 | "abbrev": { 1127 | "version": "1.1.1", 1128 | "bundled": true, 1129 | "optional": true 1130 | }, 1131 | "ansi-regex": { 1132 | "version": "2.1.1", 1133 | "bundled": true, 1134 | "optional": true 1135 | }, 1136 | "aproba": { 1137 | "version": "1.2.0", 1138 | "bundled": true, 1139 | "optional": true 1140 | }, 1141 | "are-we-there-yet": { 1142 | "version": "1.1.5", 1143 | "bundled": true, 1144 | "optional": true, 1145 | "requires": { 1146 | "delegates": "^1.0.0", 1147 | "readable-stream": "^2.0.6" 1148 | } 1149 | }, 1150 | "balanced-match": { 1151 | "version": "1.0.0", 1152 | "bundled": true, 1153 | "optional": true 1154 | }, 1155 | "brace-expansion": { 1156 | "version": "1.1.11", 1157 | "bundled": true, 1158 | "optional": true, 1159 | "requires": { 1160 | "balanced-match": "^1.0.0", 1161 | "concat-map": "0.0.1" 1162 | } 1163 | }, 1164 | "chownr": { 1165 | "version": "1.1.1", 1166 | "bundled": true, 1167 | "optional": true 1168 | }, 1169 | "code-point-at": { 1170 | "version": "1.1.0", 1171 | "bundled": true, 1172 | "optional": true 1173 | }, 1174 | "concat-map": { 1175 | "version": "0.0.1", 1176 | "bundled": true, 1177 | "optional": true 1178 | }, 1179 | "console-control-strings": { 1180 | "version": "1.1.0", 1181 | "bundled": true, 1182 | "optional": true 1183 | }, 1184 | "core-util-is": { 1185 | "version": "1.0.2", 1186 | "bundled": true, 1187 | "optional": true 1188 | }, 1189 | "debug": { 1190 | "version": "4.1.1", 1191 | "bundled": true, 1192 | "optional": true, 1193 | "requires": { 1194 | "ms": "^2.1.1" 1195 | } 1196 | }, 1197 | "deep-extend": { 1198 | "version": "0.6.0", 1199 | "bundled": true, 1200 | "optional": true 1201 | }, 1202 | "delegates": { 1203 | "version": "1.0.0", 1204 | "bundled": true, 1205 | "optional": true 1206 | }, 1207 | "detect-libc": { 1208 | "version": "1.0.3", 1209 | "bundled": true, 1210 | "optional": true 1211 | }, 1212 | "fs-minipass": { 1213 | "version": "1.2.5", 1214 | "bundled": true, 1215 | "optional": true, 1216 | "requires": { 1217 | "minipass": "^2.2.1" 1218 | } 1219 | }, 1220 | "fs.realpath": { 1221 | "version": "1.0.0", 1222 | "bundled": true, 1223 | "optional": true 1224 | }, 1225 | "gauge": { 1226 | "version": "2.7.4", 1227 | "bundled": true, 1228 | "optional": true, 1229 | "requires": { 1230 | "aproba": "^1.0.3", 1231 | "console-control-strings": "^1.0.0", 1232 | "has-unicode": "^2.0.0", 1233 | "object-assign": "^4.1.0", 1234 | "signal-exit": "^3.0.0", 1235 | "string-width": "^1.0.1", 1236 | "strip-ansi": "^3.0.1", 1237 | "wide-align": "^1.1.0" 1238 | } 1239 | }, 1240 | "glob": { 1241 | "version": "7.1.3", 1242 | "bundled": true, 1243 | "optional": true, 1244 | "requires": { 1245 | "fs.realpath": "^1.0.0", 1246 | "inflight": "^1.0.4", 1247 | "inherits": "2", 1248 | "minimatch": "^3.0.4", 1249 | "once": "^1.3.0", 1250 | "path-is-absolute": "^1.0.0" 1251 | } 1252 | }, 1253 | "has-unicode": { 1254 | "version": "2.0.1", 1255 | "bundled": true, 1256 | "optional": true 1257 | }, 1258 | "iconv-lite": { 1259 | "version": "0.4.24", 1260 | "bundled": true, 1261 | "optional": true, 1262 | "requires": { 1263 | "safer-buffer": ">= 2.1.2 < 3" 1264 | } 1265 | }, 1266 | "ignore-walk": { 1267 | "version": "3.0.1", 1268 | "bundled": true, 1269 | "optional": true, 1270 | "requires": { 1271 | "minimatch": "^3.0.4" 1272 | } 1273 | }, 1274 | "inflight": { 1275 | "version": "1.0.6", 1276 | "bundled": true, 1277 | "optional": true, 1278 | "requires": { 1279 | "once": "^1.3.0", 1280 | "wrappy": "1" 1281 | } 1282 | }, 1283 | "inherits": { 1284 | "version": "2.0.3", 1285 | "bundled": true, 1286 | "optional": true 1287 | }, 1288 | "ini": { 1289 | "version": "1.3.5", 1290 | "bundled": true, 1291 | "optional": true 1292 | }, 1293 | "is-fullwidth-code-point": { 1294 | "version": "1.0.0", 1295 | "bundled": true, 1296 | "optional": true, 1297 | "requires": { 1298 | "number-is-nan": "^1.0.0" 1299 | } 1300 | }, 1301 | "isarray": { 1302 | "version": "1.0.0", 1303 | "bundled": true, 1304 | "optional": true 1305 | }, 1306 | "minimatch": { 1307 | "version": "3.0.4", 1308 | "bundled": true, 1309 | "optional": true, 1310 | "requires": { 1311 | "brace-expansion": "^1.1.7" 1312 | } 1313 | }, 1314 | "minimist": { 1315 | "version": "0.0.8", 1316 | "bundled": true, 1317 | "optional": true 1318 | }, 1319 | "minipass": { 1320 | "version": "2.3.5", 1321 | "bundled": true, 1322 | "optional": true, 1323 | "requires": { 1324 | "safe-buffer": "^5.1.2", 1325 | "yallist": "^3.0.0" 1326 | } 1327 | }, 1328 | "minizlib": { 1329 | "version": "1.2.1", 1330 | "bundled": true, 1331 | "optional": true, 1332 | "requires": { 1333 | "minipass": "^2.2.1" 1334 | } 1335 | }, 1336 | "mkdirp": { 1337 | "version": "0.5.1", 1338 | "bundled": true, 1339 | "optional": true, 1340 | "requires": { 1341 | "minimist": "0.0.8" 1342 | } 1343 | }, 1344 | "ms": { 1345 | "version": "2.1.1", 1346 | "bundled": true, 1347 | "optional": true 1348 | }, 1349 | "needle": { 1350 | "version": "2.3.0", 1351 | "bundled": true, 1352 | "optional": true, 1353 | "requires": { 1354 | "debug": "^4.1.0", 1355 | "iconv-lite": "^0.4.4", 1356 | "sax": "^1.2.4" 1357 | } 1358 | }, 1359 | "node-pre-gyp": { 1360 | "version": "0.12.0", 1361 | "bundled": true, 1362 | "optional": true, 1363 | "requires": { 1364 | "detect-libc": "^1.0.2", 1365 | "mkdirp": "^0.5.1", 1366 | "needle": "^2.2.1", 1367 | "nopt": "^4.0.1", 1368 | "npm-packlist": "^1.1.6", 1369 | "npmlog": "^4.0.2", 1370 | "rc": "^1.2.7", 1371 | "rimraf": "^2.6.1", 1372 | "semver": "^5.3.0", 1373 | "tar": "^4" 1374 | } 1375 | }, 1376 | "nopt": { 1377 | "version": "4.0.1", 1378 | "bundled": true, 1379 | "optional": true, 1380 | "requires": { 1381 | "abbrev": "1", 1382 | "osenv": "^0.1.4" 1383 | } 1384 | }, 1385 | "npm-bundled": { 1386 | "version": "1.0.6", 1387 | "bundled": true, 1388 | "optional": true 1389 | }, 1390 | "npm-packlist": { 1391 | "version": "1.4.1", 1392 | "bundled": true, 1393 | "optional": true, 1394 | "requires": { 1395 | "ignore-walk": "^3.0.1", 1396 | "npm-bundled": "^1.0.1" 1397 | } 1398 | }, 1399 | "npmlog": { 1400 | "version": "4.1.2", 1401 | "bundled": true, 1402 | "optional": true, 1403 | "requires": { 1404 | "are-we-there-yet": "~1.1.2", 1405 | "console-control-strings": "~1.1.0", 1406 | "gauge": "~2.7.3", 1407 | "set-blocking": "~2.0.0" 1408 | } 1409 | }, 1410 | "number-is-nan": { 1411 | "version": "1.0.1", 1412 | "bundled": true, 1413 | "optional": true 1414 | }, 1415 | "object-assign": { 1416 | "version": "4.1.1", 1417 | "bundled": true, 1418 | "optional": true 1419 | }, 1420 | "once": { 1421 | "version": "1.4.0", 1422 | "bundled": true, 1423 | "optional": true, 1424 | "requires": { 1425 | "wrappy": "1" 1426 | } 1427 | }, 1428 | "os-homedir": { 1429 | "version": "1.0.2", 1430 | "bundled": true, 1431 | "optional": true 1432 | }, 1433 | "os-tmpdir": { 1434 | "version": "1.0.2", 1435 | "bundled": true, 1436 | "optional": true 1437 | }, 1438 | "osenv": { 1439 | "version": "0.1.5", 1440 | "bundled": true, 1441 | "optional": true, 1442 | "requires": { 1443 | "os-homedir": "^1.0.0", 1444 | "os-tmpdir": "^1.0.0" 1445 | } 1446 | }, 1447 | "path-is-absolute": { 1448 | "version": "1.0.1", 1449 | "bundled": true, 1450 | "optional": true 1451 | }, 1452 | "process-nextick-args": { 1453 | "version": "2.0.0", 1454 | "bundled": true, 1455 | "optional": true 1456 | }, 1457 | "rc": { 1458 | "version": "1.2.8", 1459 | "bundled": true, 1460 | "optional": true, 1461 | "requires": { 1462 | "deep-extend": "^0.6.0", 1463 | "ini": "~1.3.0", 1464 | "minimist": "^1.2.0", 1465 | "strip-json-comments": "~2.0.1" 1466 | }, 1467 | "dependencies": { 1468 | "minimist": { 1469 | "version": "1.2.0", 1470 | "bundled": true, 1471 | "optional": true 1472 | } 1473 | } 1474 | }, 1475 | "readable-stream": { 1476 | "version": "2.3.6", 1477 | "bundled": true, 1478 | "optional": true, 1479 | "requires": { 1480 | "core-util-is": "~1.0.0", 1481 | "inherits": "~2.0.3", 1482 | "isarray": "~1.0.0", 1483 | "process-nextick-args": "~2.0.0", 1484 | "safe-buffer": "~5.1.1", 1485 | "string_decoder": "~1.1.1", 1486 | "util-deprecate": "~1.0.1" 1487 | } 1488 | }, 1489 | "rimraf": { 1490 | "version": "2.6.3", 1491 | "bundled": true, 1492 | "optional": true, 1493 | "requires": { 1494 | "glob": "^7.1.3" 1495 | } 1496 | }, 1497 | "safe-buffer": { 1498 | "version": "5.1.2", 1499 | "bundled": true, 1500 | "optional": true 1501 | }, 1502 | "safer-buffer": { 1503 | "version": "2.1.2", 1504 | "bundled": true, 1505 | "optional": true 1506 | }, 1507 | "sax": { 1508 | "version": "1.2.4", 1509 | "bundled": true, 1510 | "optional": true 1511 | }, 1512 | "semver": { 1513 | "version": "5.7.0", 1514 | "bundled": true, 1515 | "optional": true 1516 | }, 1517 | "set-blocking": { 1518 | "version": "2.0.0", 1519 | "bundled": true, 1520 | "optional": true 1521 | }, 1522 | "signal-exit": { 1523 | "version": "3.0.2", 1524 | "bundled": true, 1525 | "optional": true 1526 | }, 1527 | "string-width": { 1528 | "version": "1.0.2", 1529 | "bundled": true, 1530 | "optional": true, 1531 | "requires": { 1532 | "code-point-at": "^1.0.0", 1533 | "is-fullwidth-code-point": "^1.0.0", 1534 | "strip-ansi": "^3.0.0" 1535 | } 1536 | }, 1537 | "string_decoder": { 1538 | "version": "1.1.1", 1539 | "bundled": true, 1540 | "optional": true, 1541 | "requires": { 1542 | "safe-buffer": "~5.1.0" 1543 | } 1544 | }, 1545 | "strip-ansi": { 1546 | "version": "3.0.1", 1547 | "bundled": true, 1548 | "optional": true, 1549 | "requires": { 1550 | "ansi-regex": "^2.0.0" 1551 | } 1552 | }, 1553 | "strip-json-comments": { 1554 | "version": "2.0.1", 1555 | "bundled": true, 1556 | "optional": true 1557 | }, 1558 | "tar": { 1559 | "version": "4.4.8", 1560 | "bundled": true, 1561 | "optional": true, 1562 | "requires": { 1563 | "chownr": "^1.1.1", 1564 | "fs-minipass": "^1.2.5", 1565 | "minipass": "^2.3.4", 1566 | "minizlib": "^1.1.1", 1567 | "mkdirp": "^0.5.0", 1568 | "safe-buffer": "^5.1.2", 1569 | "yallist": "^3.0.2" 1570 | } 1571 | }, 1572 | "util-deprecate": { 1573 | "version": "1.0.2", 1574 | "bundled": true, 1575 | "optional": true 1576 | }, 1577 | "wide-align": { 1578 | "version": "1.1.3", 1579 | "bundled": true, 1580 | "optional": true, 1581 | "requires": { 1582 | "string-width": "^1.0.2 || 2" 1583 | } 1584 | }, 1585 | "wrappy": { 1586 | "version": "1.0.2", 1587 | "bundled": true, 1588 | "optional": true 1589 | }, 1590 | "yallist": { 1591 | "version": "3.0.3", 1592 | "bundled": true, 1593 | "optional": true 1594 | } 1595 | } 1596 | }, 1597 | "function-bind": { 1598 | "version": "1.1.1", 1599 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 1600 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 1601 | "dev": true 1602 | }, 1603 | "get-caller-file": { 1604 | "version": "2.0.5", 1605 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 1606 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 1607 | "dev": true 1608 | }, 1609 | "get-func-name": { 1610 | "version": "2.0.0", 1611 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 1612 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", 1613 | "dev": true 1614 | }, 1615 | "get-stream": { 1616 | "version": "3.0.0", 1617 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", 1618 | "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" 1619 | }, 1620 | "get-value": { 1621 | "version": "2.0.6", 1622 | "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", 1623 | "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" 1624 | }, 1625 | "glob": { 1626 | "version": "7.1.3", 1627 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", 1628 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", 1629 | "dev": true, 1630 | "requires": { 1631 | "fs.realpath": "^1.0.0", 1632 | "inflight": "^1.0.4", 1633 | "inherits": "2", 1634 | "minimatch": "^3.0.4", 1635 | "once": "^1.3.0", 1636 | "path-is-absolute": "^1.0.0" 1637 | } 1638 | }, 1639 | "glob-parent": { 1640 | "version": "3.1.0", 1641 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", 1642 | "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", 1643 | "requires": { 1644 | "is-glob": "^3.1.0", 1645 | "path-dirname": "^1.0.0" 1646 | }, 1647 | "dependencies": { 1648 | "is-glob": { 1649 | "version": "3.1.0", 1650 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", 1651 | "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", 1652 | "requires": { 1653 | "is-extglob": "^2.1.0" 1654 | } 1655 | } 1656 | } 1657 | }, 1658 | "global-dirs": { 1659 | "version": "0.1.1", 1660 | "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", 1661 | "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", 1662 | "requires": { 1663 | "ini": "^1.3.4" 1664 | } 1665 | }, 1666 | "got": { 1667 | "version": "6.7.1", 1668 | "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", 1669 | "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", 1670 | "requires": { 1671 | "create-error-class": "^3.0.0", 1672 | "duplexer3": "^0.1.4", 1673 | "get-stream": "^3.0.0", 1674 | "is-redirect": "^1.0.0", 1675 | "is-retry-allowed": "^1.0.0", 1676 | "is-stream": "^1.0.0", 1677 | "lowercase-keys": "^1.0.0", 1678 | "safe-buffer": "^5.0.1", 1679 | "timed-out": "^4.0.0", 1680 | "unzip-response": "^2.0.1", 1681 | "url-parse-lax": "^1.0.0" 1682 | } 1683 | }, 1684 | "graceful-fs": { 1685 | "version": "4.2.0", 1686 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", 1687 | "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" 1688 | }, 1689 | "growl": { 1690 | "version": "1.10.5", 1691 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 1692 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 1693 | "dev": true 1694 | }, 1695 | "has": { 1696 | "version": "1.0.3", 1697 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1698 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1699 | "dev": true, 1700 | "requires": { 1701 | "function-bind": "^1.1.1" 1702 | } 1703 | }, 1704 | "has-flag": { 1705 | "version": "3.0.0", 1706 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1707 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 1708 | }, 1709 | "has-symbols": { 1710 | "version": "1.0.0", 1711 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", 1712 | "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", 1713 | "dev": true 1714 | }, 1715 | "has-value": { 1716 | "version": "1.0.0", 1717 | "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", 1718 | "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", 1719 | "requires": { 1720 | "get-value": "^2.0.6", 1721 | "has-values": "^1.0.0", 1722 | "isobject": "^3.0.0" 1723 | } 1724 | }, 1725 | "has-values": { 1726 | "version": "1.0.0", 1727 | "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", 1728 | "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", 1729 | "requires": { 1730 | "is-number": "^3.0.0", 1731 | "kind-of": "^4.0.0" 1732 | }, 1733 | "dependencies": { 1734 | "is-buffer": { 1735 | "version": "1.1.6", 1736 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 1737 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 1738 | }, 1739 | "kind-of": { 1740 | "version": "4.0.0", 1741 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", 1742 | "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", 1743 | "requires": { 1744 | "is-buffer": "^1.1.5" 1745 | } 1746 | } 1747 | } 1748 | }, 1749 | "hash.js": { 1750 | "version": "1.1.7", 1751 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", 1752 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", 1753 | "requires": { 1754 | "inherits": "^2.0.3", 1755 | "minimalistic-assert": "^1.0.1" 1756 | } 1757 | }, 1758 | "he": { 1759 | "version": "1.2.0", 1760 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1761 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1762 | "dev": true 1763 | }, 1764 | "hmac-drbg": { 1765 | "version": "1.0.1", 1766 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", 1767 | "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", 1768 | "requires": { 1769 | "hash.js": "^1.0.3", 1770 | "minimalistic-assert": "^1.0.0", 1771 | "minimalistic-crypto-utils": "^1.0.1" 1772 | } 1773 | }, 1774 | "http-errors": { 1775 | "version": "1.7.2", 1776 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 1777 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 1778 | "requires": { 1779 | "depd": "~1.1.2", 1780 | "inherits": "2.0.3", 1781 | "setprototypeof": "1.1.1", 1782 | "statuses": ">= 1.5.0 < 2", 1783 | "toidentifier": "1.0.0" 1784 | } 1785 | }, 1786 | "iconv-lite": { 1787 | "version": "0.4.24", 1788 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1789 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1790 | "requires": { 1791 | "safer-buffer": ">= 2.1.2 < 3" 1792 | } 1793 | }, 1794 | "ignore-by-default": { 1795 | "version": "1.0.1", 1796 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", 1797 | "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=" 1798 | }, 1799 | "import-lazy": { 1800 | "version": "2.1.0", 1801 | "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", 1802 | "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" 1803 | }, 1804 | "imurmurhash": { 1805 | "version": "0.1.4", 1806 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1807 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" 1808 | }, 1809 | "inflight": { 1810 | "version": "1.0.6", 1811 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1812 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1813 | "dev": true, 1814 | "requires": { 1815 | "once": "^1.3.0", 1816 | "wrappy": "1" 1817 | } 1818 | }, 1819 | "inherits": { 1820 | "version": "2.0.3", 1821 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 1822 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 1823 | }, 1824 | "ini": { 1825 | "version": "1.3.5", 1826 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 1827 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" 1828 | }, 1829 | "invert-kv": { 1830 | "version": "2.0.0", 1831 | "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", 1832 | "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", 1833 | "dev": true 1834 | }, 1835 | "ipaddr.js": { 1836 | "version": "1.9.0", 1837 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", 1838 | "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" 1839 | }, 1840 | "is-accessor-descriptor": { 1841 | "version": "0.1.6", 1842 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", 1843 | "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", 1844 | "requires": { 1845 | "kind-of": "^3.0.2" 1846 | }, 1847 | "dependencies": { 1848 | "is-buffer": { 1849 | "version": "1.1.6", 1850 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 1851 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 1852 | }, 1853 | "kind-of": { 1854 | "version": "3.2.2", 1855 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 1856 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 1857 | "requires": { 1858 | "is-buffer": "^1.1.5" 1859 | } 1860 | } 1861 | } 1862 | }, 1863 | "is-binary-path": { 1864 | "version": "1.0.1", 1865 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", 1866 | "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", 1867 | "requires": { 1868 | "binary-extensions": "^1.0.0" 1869 | } 1870 | }, 1871 | "is-buffer": { 1872 | "version": "2.0.3", 1873 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", 1874 | "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" 1875 | }, 1876 | "is-callable": { 1877 | "version": "1.1.4", 1878 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", 1879 | "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", 1880 | "dev": true 1881 | }, 1882 | "is-ci": { 1883 | "version": "1.2.1", 1884 | "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", 1885 | "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", 1886 | "requires": { 1887 | "ci-info": "^1.5.0" 1888 | } 1889 | }, 1890 | "is-data-descriptor": { 1891 | "version": "0.1.4", 1892 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", 1893 | "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", 1894 | "requires": { 1895 | "kind-of": "^3.0.2" 1896 | }, 1897 | "dependencies": { 1898 | "is-buffer": { 1899 | "version": "1.1.6", 1900 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 1901 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 1902 | }, 1903 | "kind-of": { 1904 | "version": "3.2.2", 1905 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 1906 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 1907 | "requires": { 1908 | "is-buffer": "^1.1.5" 1909 | } 1910 | } 1911 | } 1912 | }, 1913 | "is-date-object": { 1914 | "version": "1.0.1", 1915 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", 1916 | "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", 1917 | "dev": true 1918 | }, 1919 | "is-descriptor": { 1920 | "version": "0.1.6", 1921 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", 1922 | "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", 1923 | "requires": { 1924 | "is-accessor-descriptor": "^0.1.6", 1925 | "is-data-descriptor": "^0.1.4", 1926 | "kind-of": "^5.0.0" 1927 | }, 1928 | "dependencies": { 1929 | "kind-of": { 1930 | "version": "5.1.0", 1931 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", 1932 | "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" 1933 | } 1934 | } 1935 | }, 1936 | "is-extendable": { 1937 | "version": "0.1.1", 1938 | "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", 1939 | "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" 1940 | }, 1941 | "is-extglob": { 1942 | "version": "2.1.1", 1943 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 1944 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" 1945 | }, 1946 | "is-fullwidth-code-point": { 1947 | "version": "2.0.0", 1948 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1949 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 1950 | }, 1951 | "is-glob": { 1952 | "version": "4.0.1", 1953 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 1954 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 1955 | "requires": { 1956 | "is-extglob": "^2.1.1" 1957 | } 1958 | }, 1959 | "is-installed-globally": { 1960 | "version": "0.1.0", 1961 | "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", 1962 | "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", 1963 | "requires": { 1964 | "global-dirs": "^0.1.0", 1965 | "is-path-inside": "^1.0.0" 1966 | } 1967 | }, 1968 | "is-npm": { 1969 | "version": "1.0.0", 1970 | "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", 1971 | "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" 1972 | }, 1973 | "is-number": { 1974 | "version": "3.0.0", 1975 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", 1976 | "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", 1977 | "requires": { 1978 | "kind-of": "^3.0.2" 1979 | }, 1980 | "dependencies": { 1981 | "is-buffer": { 1982 | "version": "1.1.6", 1983 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 1984 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 1985 | }, 1986 | "kind-of": { 1987 | "version": "3.2.2", 1988 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 1989 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 1990 | "requires": { 1991 | "is-buffer": "^1.1.5" 1992 | } 1993 | } 1994 | } 1995 | }, 1996 | "is-obj": { 1997 | "version": "1.0.1", 1998 | "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", 1999 | "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" 2000 | }, 2001 | "is-path-inside": { 2002 | "version": "1.0.1", 2003 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", 2004 | "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", 2005 | "requires": { 2006 | "path-is-inside": "^1.0.1" 2007 | } 2008 | }, 2009 | "is-plain-object": { 2010 | "version": "2.0.4", 2011 | "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", 2012 | "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", 2013 | "requires": { 2014 | "isobject": "^3.0.1" 2015 | } 2016 | }, 2017 | "is-redirect": { 2018 | "version": "1.0.0", 2019 | "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", 2020 | "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" 2021 | }, 2022 | "is-regex": { 2023 | "version": "1.0.4", 2024 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", 2025 | "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", 2026 | "dev": true, 2027 | "requires": { 2028 | "has": "^1.0.1" 2029 | } 2030 | }, 2031 | "is-retry-allowed": { 2032 | "version": "1.1.0", 2033 | "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", 2034 | "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" 2035 | }, 2036 | "is-stream": { 2037 | "version": "1.1.0", 2038 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 2039 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" 2040 | }, 2041 | "is-symbol": { 2042 | "version": "1.0.2", 2043 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", 2044 | "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", 2045 | "dev": true, 2046 | "requires": { 2047 | "has-symbols": "^1.0.0" 2048 | } 2049 | }, 2050 | "is-windows": { 2051 | "version": "1.0.2", 2052 | "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", 2053 | "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" 2054 | }, 2055 | "isarray": { 2056 | "version": "1.0.0", 2057 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 2058 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 2059 | }, 2060 | "isexe": { 2061 | "version": "2.0.0", 2062 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 2063 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 2064 | }, 2065 | "isobject": { 2066 | "version": "3.0.1", 2067 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", 2068 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" 2069 | }, 2070 | "js-yaml": { 2071 | "version": "3.13.1", 2072 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 2073 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 2074 | "dev": true, 2075 | "requires": { 2076 | "argparse": "^1.0.7", 2077 | "esprima": "^4.0.0" 2078 | } 2079 | }, 2080 | "jsonwebtoken": { 2081 | "version": "8.5.1", 2082 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", 2083 | "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", 2084 | "requires": { 2085 | "jws": "^3.2.2", 2086 | "lodash.includes": "^4.3.0", 2087 | "lodash.isboolean": "^3.0.3", 2088 | "lodash.isinteger": "^4.0.4", 2089 | "lodash.isnumber": "^3.0.3", 2090 | "lodash.isplainobject": "^4.0.6", 2091 | "lodash.isstring": "^4.0.1", 2092 | "lodash.once": "^4.0.0", 2093 | "ms": "^2.1.1", 2094 | "semver": "^5.6.0" 2095 | }, 2096 | "dependencies": { 2097 | "ms": { 2098 | "version": "2.1.2", 2099 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2100 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 2101 | } 2102 | } 2103 | }, 2104 | "jwa": { 2105 | "version": "1.4.1", 2106 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", 2107 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", 2108 | "requires": { 2109 | "buffer-equal-constant-time": "1.0.1", 2110 | "ecdsa-sig-formatter": "1.0.11", 2111 | "safe-buffer": "^5.0.1" 2112 | } 2113 | }, 2114 | "jwk-to-pem": { 2115 | "version": "2.0.1", 2116 | "resolved": "https://registry.npmjs.org/jwk-to-pem/-/jwk-to-pem-2.0.1.tgz", 2117 | "integrity": "sha512-KKu0WuDDjqw2FlRFp9/vk9TMO/KvgpZVKzdhhYcNyy5OwE8dw9lOK5OQTQHIJ7m+HioI/4P44sAtVuDrQ8KQfw==", 2118 | "requires": { 2119 | "asn1.js": "^4.5.2", 2120 | "elliptic": "^6.2.3", 2121 | "safe-buffer": "^5.0.1" 2122 | } 2123 | }, 2124 | "jws": { 2125 | "version": "3.2.2", 2126 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", 2127 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", 2128 | "requires": { 2129 | "jwa": "^1.4.1", 2130 | "safe-buffer": "^5.0.1" 2131 | } 2132 | }, 2133 | "kareem": { 2134 | "version": "2.3.0", 2135 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.0.tgz", 2136 | "integrity": "sha512-6hHxsp9e6zQU8nXsP+02HGWXwTkOEw6IROhF2ZA28cYbUk4eJ6QbtZvdqZOdD9YPKghG3apk5eOCvs+tLl3lRg==" 2137 | }, 2138 | "kind-of": { 2139 | "version": "6.0.2", 2140 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", 2141 | "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" 2142 | }, 2143 | "latest-version": { 2144 | "version": "3.1.0", 2145 | "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", 2146 | "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", 2147 | "requires": { 2148 | "package-json": "^4.0.0" 2149 | } 2150 | }, 2151 | "lcid": { 2152 | "version": "2.0.0", 2153 | "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", 2154 | "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", 2155 | "dev": true, 2156 | "requires": { 2157 | "invert-kv": "^2.0.0" 2158 | } 2159 | }, 2160 | "locate-path": { 2161 | "version": "3.0.0", 2162 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 2163 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 2164 | "dev": true, 2165 | "requires": { 2166 | "p-locate": "^3.0.0", 2167 | "path-exists": "^3.0.0" 2168 | } 2169 | }, 2170 | "lodash": { 2171 | "version": "4.17.15", 2172 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 2173 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" 2174 | }, 2175 | "lodash.includes": { 2176 | "version": "4.3.0", 2177 | "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", 2178 | "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" 2179 | }, 2180 | "lodash.isboolean": { 2181 | "version": "3.0.3", 2182 | "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", 2183 | "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" 2184 | }, 2185 | "lodash.isinteger": { 2186 | "version": "4.0.4", 2187 | "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", 2188 | "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" 2189 | }, 2190 | "lodash.isnumber": { 2191 | "version": "3.0.3", 2192 | "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", 2193 | "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" 2194 | }, 2195 | "lodash.isplainobject": { 2196 | "version": "4.0.6", 2197 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 2198 | "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" 2199 | }, 2200 | "lodash.isstring": { 2201 | "version": "4.0.1", 2202 | "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", 2203 | "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" 2204 | }, 2205 | "lodash.once": { 2206 | "version": "4.1.1", 2207 | "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", 2208 | "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" 2209 | }, 2210 | "log-symbols": { 2211 | "version": "2.2.0", 2212 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", 2213 | "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", 2214 | "dev": true, 2215 | "requires": { 2216 | "chalk": "^2.0.1" 2217 | } 2218 | }, 2219 | "lowercase-keys": { 2220 | "version": "1.0.1", 2221 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", 2222 | "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" 2223 | }, 2224 | "lru-cache": { 2225 | "version": "4.1.5", 2226 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", 2227 | "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", 2228 | "requires": { 2229 | "pseudomap": "^1.0.2", 2230 | "yallist": "^2.1.2" 2231 | } 2232 | }, 2233 | "make-dir": { 2234 | "version": "1.3.0", 2235 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", 2236 | "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", 2237 | "requires": { 2238 | "pify": "^3.0.0" 2239 | } 2240 | }, 2241 | "map-age-cleaner": { 2242 | "version": "0.1.3", 2243 | "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", 2244 | "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", 2245 | "dev": true, 2246 | "requires": { 2247 | "p-defer": "^1.0.0" 2248 | } 2249 | }, 2250 | "map-cache": { 2251 | "version": "0.2.2", 2252 | "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", 2253 | "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" 2254 | }, 2255 | "map-visit": { 2256 | "version": "1.0.0", 2257 | "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", 2258 | "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", 2259 | "requires": { 2260 | "object-visit": "^1.0.0" 2261 | } 2262 | }, 2263 | "media-typer": { 2264 | "version": "0.3.0", 2265 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 2266 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 2267 | }, 2268 | "mem": { 2269 | "version": "4.3.0", 2270 | "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", 2271 | "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", 2272 | "dev": true, 2273 | "requires": { 2274 | "map-age-cleaner": "^0.1.1", 2275 | "mimic-fn": "^2.0.0", 2276 | "p-is-promise": "^2.0.0" 2277 | } 2278 | }, 2279 | "memory-pager": { 2280 | "version": "1.5.0", 2281 | "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", 2282 | "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", 2283 | "optional": true 2284 | }, 2285 | "merge-descriptors": { 2286 | "version": "1.0.1", 2287 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 2288 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 2289 | }, 2290 | "methods": { 2291 | "version": "1.1.2", 2292 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 2293 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 2294 | }, 2295 | "micromatch": { 2296 | "version": "3.1.10", 2297 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", 2298 | "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", 2299 | "requires": { 2300 | "arr-diff": "^4.0.0", 2301 | "array-unique": "^0.3.2", 2302 | "braces": "^2.3.1", 2303 | "define-property": "^2.0.2", 2304 | "extend-shallow": "^3.0.2", 2305 | "extglob": "^2.0.4", 2306 | "fragment-cache": "^0.2.1", 2307 | "kind-of": "^6.0.2", 2308 | "nanomatch": "^1.2.9", 2309 | "object.pick": "^1.3.0", 2310 | "regex-not": "^1.0.0", 2311 | "snapdragon": "^0.8.1", 2312 | "to-regex": "^3.0.2" 2313 | } 2314 | }, 2315 | "mime": { 2316 | "version": "1.6.0", 2317 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 2318 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 2319 | }, 2320 | "mime-db": { 2321 | "version": "1.40.0", 2322 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", 2323 | "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" 2324 | }, 2325 | "mime-types": { 2326 | "version": "2.1.24", 2327 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", 2328 | "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", 2329 | "requires": { 2330 | "mime-db": "1.40.0" 2331 | } 2332 | }, 2333 | "mimic-fn": { 2334 | "version": "2.1.0", 2335 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", 2336 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", 2337 | "dev": true 2338 | }, 2339 | "minimalistic-assert": { 2340 | "version": "1.0.1", 2341 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", 2342 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" 2343 | }, 2344 | "minimalistic-crypto-utils": { 2345 | "version": "1.0.1", 2346 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", 2347 | "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" 2348 | }, 2349 | "minimatch": { 2350 | "version": "3.0.4", 2351 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 2352 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 2353 | "requires": { 2354 | "brace-expansion": "^1.1.7" 2355 | } 2356 | }, 2357 | "minimist": { 2358 | "version": "1.2.0", 2359 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 2360 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" 2361 | }, 2362 | "mixin-deep": { 2363 | "version": "1.3.2", 2364 | "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", 2365 | "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", 2366 | "requires": { 2367 | "for-in": "^1.0.2", 2368 | "is-extendable": "^1.0.1" 2369 | }, 2370 | "dependencies": { 2371 | "is-extendable": { 2372 | "version": "1.0.1", 2373 | "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", 2374 | "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", 2375 | "requires": { 2376 | "is-plain-object": "^2.0.4" 2377 | } 2378 | } 2379 | } 2380 | }, 2381 | "mkdirp": { 2382 | "version": "0.5.1", 2383 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 2384 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 2385 | "dev": true, 2386 | "requires": { 2387 | "minimist": "0.0.8" 2388 | }, 2389 | "dependencies": { 2390 | "minimist": { 2391 | "version": "0.0.8", 2392 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 2393 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 2394 | "dev": true 2395 | } 2396 | } 2397 | }, 2398 | "mocha": { 2399 | "version": "6.2.0", 2400 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.0.tgz", 2401 | "integrity": "sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ==", 2402 | "dev": true, 2403 | "requires": { 2404 | "ansi-colors": "3.2.3", 2405 | "browser-stdout": "1.3.1", 2406 | "debug": "3.2.6", 2407 | "diff": "3.5.0", 2408 | "escape-string-regexp": "1.0.5", 2409 | "find-up": "3.0.0", 2410 | "glob": "7.1.3", 2411 | "growl": "1.10.5", 2412 | "he": "1.2.0", 2413 | "js-yaml": "3.13.1", 2414 | "log-symbols": "2.2.0", 2415 | "minimatch": "3.0.4", 2416 | "mkdirp": "0.5.1", 2417 | "ms": "2.1.1", 2418 | "node-environment-flags": "1.0.5", 2419 | "object.assign": "4.1.0", 2420 | "strip-json-comments": "2.0.1", 2421 | "supports-color": "6.0.0", 2422 | "which": "1.3.1", 2423 | "wide-align": "1.1.3", 2424 | "yargs": "13.2.2", 2425 | "yargs-parser": "13.0.0", 2426 | "yargs-unparser": "1.5.0" 2427 | }, 2428 | "dependencies": { 2429 | "debug": { 2430 | "version": "3.2.6", 2431 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 2432 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 2433 | "dev": true, 2434 | "requires": { 2435 | "ms": "^2.1.1" 2436 | } 2437 | }, 2438 | "ms": { 2439 | "version": "2.1.1", 2440 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 2441 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", 2442 | "dev": true 2443 | }, 2444 | "supports-color": { 2445 | "version": "6.0.0", 2446 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", 2447 | "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", 2448 | "dev": true, 2449 | "requires": { 2450 | "has-flag": "^3.0.0" 2451 | } 2452 | } 2453 | } 2454 | }, 2455 | "mongodb": { 2456 | "version": "3.2.7", 2457 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.2.7.tgz", 2458 | "integrity": "sha512-2YdWrdf1PJgxcCrT1tWoL6nHuk6hCxhddAAaEh8QJL231ci4+P9FLyqopbTm2Z2sAU6mhCri+wd9r1hOcHdoMw==", 2459 | "requires": { 2460 | "mongodb-core": "3.2.7", 2461 | "safe-buffer": "^5.1.2" 2462 | } 2463 | }, 2464 | "mongodb-core": { 2465 | "version": "3.2.7", 2466 | "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.2.7.tgz", 2467 | "integrity": "sha512-WypKdLxFNPOH/Jy6i9z47IjG2wIldA54iDZBmHMINcgKOUcWJh8og+Wix76oGd7EyYkHJKssQ2FAOw5Su/n4XQ==", 2468 | "requires": { 2469 | "bson": "^1.1.1", 2470 | "require_optional": "^1.0.1", 2471 | "safe-buffer": "^5.1.2", 2472 | "saslprep": "^1.0.0" 2473 | } 2474 | }, 2475 | "mongoose": { 2476 | "version": "5.6.8", 2477 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.6.8.tgz", 2478 | "integrity": "sha512-BhgGU/KvnVX8WbamcWgtG/45rp+xZnaF9MhNbzESIIYxK7g5QurXYcaGGCm/JFiIdIxkVUgBycWG7UzRUEzvDg==", 2479 | "requires": { 2480 | "async": "2.6.2", 2481 | "bson": "~1.1.1", 2482 | "kareem": "2.3.0", 2483 | "mongodb": "3.2.7", 2484 | "mongodb-core": "3.2.7", 2485 | "mongoose-legacy-pluralize": "1.0.2", 2486 | "mpath": "0.6.0", 2487 | "mquery": "3.2.1", 2488 | "ms": "2.1.2", 2489 | "regexp-clone": "1.0.0", 2490 | "safe-buffer": "5.1.2", 2491 | "sift": "7.0.1", 2492 | "sliced": "1.0.1" 2493 | }, 2494 | "dependencies": { 2495 | "ms": { 2496 | "version": "2.1.2", 2497 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 2498 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 2499 | }, 2500 | "safe-buffer": { 2501 | "version": "5.1.2", 2502 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 2503 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 2504 | } 2505 | } 2506 | }, 2507 | "mongoose-legacy-pluralize": { 2508 | "version": "1.0.2", 2509 | "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz", 2510 | "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==" 2511 | }, 2512 | "morgan": { 2513 | "version": "1.9.1", 2514 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", 2515 | "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", 2516 | "requires": { 2517 | "basic-auth": "~2.0.0", 2518 | "debug": "2.6.9", 2519 | "depd": "~1.1.2", 2520 | "on-finished": "~2.3.0", 2521 | "on-headers": "~1.0.1" 2522 | }, 2523 | "dependencies": { 2524 | "debug": { 2525 | "version": "2.6.9", 2526 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 2527 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 2528 | "requires": { 2529 | "ms": "2.0.0" 2530 | } 2531 | } 2532 | } 2533 | }, 2534 | "mpath": { 2535 | "version": "0.6.0", 2536 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.6.0.tgz", 2537 | "integrity": "sha512-i75qh79MJ5Xo/sbhxrDrPSEG0H/mr1kcZXJ8dH6URU5jD/knFxCVqVC/gVSW7GIXL/9hHWlT9haLbCXWOll3qw==" 2538 | }, 2539 | "mquery": { 2540 | "version": "3.2.1", 2541 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.1.tgz", 2542 | "integrity": "sha512-kY/K8QToZWTTocm0U+r8rqcJCp5PRl6e8tPmoDs5OeSO3DInZE2rAL6AYH+V406JTo8305LdASOQcxRDqHojyw==", 2543 | "requires": { 2544 | "bluebird": "3.5.1", 2545 | "debug": "3.1.0", 2546 | "regexp-clone": "^1.0.0", 2547 | "safe-buffer": "5.1.2", 2548 | "sliced": "1.0.1" 2549 | }, 2550 | "dependencies": { 2551 | "safe-buffer": { 2552 | "version": "5.1.2", 2553 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 2554 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 2555 | } 2556 | } 2557 | }, 2558 | "ms": { 2559 | "version": "2.0.0", 2560 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 2561 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 2562 | }, 2563 | "nan": { 2564 | "version": "2.14.0", 2565 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", 2566 | "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", 2567 | "optional": true 2568 | }, 2569 | "nanomatch": { 2570 | "version": "1.2.13", 2571 | "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", 2572 | "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", 2573 | "requires": { 2574 | "arr-diff": "^4.0.0", 2575 | "array-unique": "^0.3.2", 2576 | "define-property": "^2.0.2", 2577 | "extend-shallow": "^3.0.2", 2578 | "fragment-cache": "^0.2.1", 2579 | "is-windows": "^1.0.2", 2580 | "kind-of": "^6.0.2", 2581 | "object.pick": "^1.3.0", 2582 | "regex-not": "^1.0.0", 2583 | "snapdragon": "^0.8.1", 2584 | "to-regex": "^3.0.1" 2585 | } 2586 | }, 2587 | "negotiator": { 2588 | "version": "0.6.2", 2589 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 2590 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 2591 | }, 2592 | "nice-try": { 2593 | "version": "1.0.5", 2594 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 2595 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 2596 | "dev": true 2597 | }, 2598 | "node-environment-flags": { 2599 | "version": "1.0.5", 2600 | "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", 2601 | "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", 2602 | "dev": true, 2603 | "requires": { 2604 | "object.getownpropertydescriptors": "^2.0.3", 2605 | "semver": "^5.7.0" 2606 | } 2607 | }, 2608 | "nodemon": { 2609 | "version": "1.19.1", 2610 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.19.1.tgz", 2611 | "integrity": "sha512-/DXLzd/GhiaDXXbGId5BzxP1GlsqtMGM9zTmkWrgXtSqjKmGSbLicM/oAy4FR0YWm14jCHRwnR31AHS2dYFHrg==", 2612 | "requires": { 2613 | "chokidar": "^2.1.5", 2614 | "debug": "^3.1.0", 2615 | "ignore-by-default": "^1.0.1", 2616 | "minimatch": "^3.0.4", 2617 | "pstree.remy": "^1.1.6", 2618 | "semver": "^5.5.0", 2619 | "supports-color": "^5.2.0", 2620 | "touch": "^3.1.0", 2621 | "undefsafe": "^2.0.2", 2622 | "update-notifier": "^2.5.0" 2623 | } 2624 | }, 2625 | "nopt": { 2626 | "version": "1.0.10", 2627 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", 2628 | "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", 2629 | "requires": { 2630 | "abbrev": "1" 2631 | } 2632 | }, 2633 | "normalize-path": { 2634 | "version": "3.0.0", 2635 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 2636 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" 2637 | }, 2638 | "npm-run-path": { 2639 | "version": "2.0.2", 2640 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", 2641 | "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", 2642 | "requires": { 2643 | "path-key": "^2.0.0" 2644 | } 2645 | }, 2646 | "number-is-nan": { 2647 | "version": "1.0.1", 2648 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 2649 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", 2650 | "dev": true 2651 | }, 2652 | "object-copy": { 2653 | "version": "0.1.0", 2654 | "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", 2655 | "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", 2656 | "requires": { 2657 | "copy-descriptor": "^0.1.0", 2658 | "define-property": "^0.2.5", 2659 | "kind-of": "^3.0.3" 2660 | }, 2661 | "dependencies": { 2662 | "define-property": { 2663 | "version": "0.2.5", 2664 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", 2665 | "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", 2666 | "requires": { 2667 | "is-descriptor": "^0.1.0" 2668 | } 2669 | }, 2670 | "is-buffer": { 2671 | "version": "1.1.6", 2672 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 2673 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 2674 | }, 2675 | "kind-of": { 2676 | "version": "3.2.2", 2677 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 2678 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 2679 | "requires": { 2680 | "is-buffer": "^1.1.5" 2681 | } 2682 | } 2683 | } 2684 | }, 2685 | "object-keys": { 2686 | "version": "1.1.1", 2687 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 2688 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 2689 | "dev": true 2690 | }, 2691 | "object-visit": { 2692 | "version": "1.0.1", 2693 | "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", 2694 | "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", 2695 | "requires": { 2696 | "isobject": "^3.0.0" 2697 | } 2698 | }, 2699 | "object.assign": { 2700 | "version": "4.1.0", 2701 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", 2702 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 2703 | "dev": true, 2704 | "requires": { 2705 | "define-properties": "^1.1.2", 2706 | "function-bind": "^1.1.1", 2707 | "has-symbols": "^1.0.0", 2708 | "object-keys": "^1.0.11" 2709 | } 2710 | }, 2711 | "object.getownpropertydescriptors": { 2712 | "version": "2.0.3", 2713 | "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", 2714 | "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", 2715 | "dev": true, 2716 | "requires": { 2717 | "define-properties": "^1.1.2", 2718 | "es-abstract": "^1.5.1" 2719 | } 2720 | }, 2721 | "object.pick": { 2722 | "version": "1.3.0", 2723 | "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", 2724 | "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", 2725 | "requires": { 2726 | "isobject": "^3.0.1" 2727 | } 2728 | }, 2729 | "on-finished": { 2730 | "version": "2.3.0", 2731 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 2732 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 2733 | "requires": { 2734 | "ee-first": "1.1.1" 2735 | } 2736 | }, 2737 | "on-headers": { 2738 | "version": "1.0.2", 2739 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", 2740 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" 2741 | }, 2742 | "once": { 2743 | "version": "1.4.0", 2744 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 2745 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 2746 | "dev": true, 2747 | "requires": { 2748 | "wrappy": "1" 2749 | } 2750 | }, 2751 | "os-locale": { 2752 | "version": "3.1.0", 2753 | "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", 2754 | "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", 2755 | "dev": true, 2756 | "requires": { 2757 | "execa": "^1.0.0", 2758 | "lcid": "^2.0.0", 2759 | "mem": "^4.0.0" 2760 | }, 2761 | "dependencies": { 2762 | "cross-spawn": { 2763 | "version": "6.0.5", 2764 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 2765 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 2766 | "dev": true, 2767 | "requires": { 2768 | "nice-try": "^1.0.4", 2769 | "path-key": "^2.0.1", 2770 | "semver": "^5.5.0", 2771 | "shebang-command": "^1.2.0", 2772 | "which": "^1.2.9" 2773 | } 2774 | }, 2775 | "execa": { 2776 | "version": "1.0.0", 2777 | "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", 2778 | "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", 2779 | "dev": true, 2780 | "requires": { 2781 | "cross-spawn": "^6.0.0", 2782 | "get-stream": "^4.0.0", 2783 | "is-stream": "^1.1.0", 2784 | "npm-run-path": "^2.0.0", 2785 | "p-finally": "^1.0.0", 2786 | "signal-exit": "^3.0.0", 2787 | "strip-eof": "^1.0.0" 2788 | } 2789 | }, 2790 | "get-stream": { 2791 | "version": "4.1.0", 2792 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", 2793 | "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", 2794 | "dev": true, 2795 | "requires": { 2796 | "pump": "^3.0.0" 2797 | } 2798 | } 2799 | } 2800 | }, 2801 | "p-defer": { 2802 | "version": "1.0.0", 2803 | "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", 2804 | "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", 2805 | "dev": true 2806 | }, 2807 | "p-finally": { 2808 | "version": "1.0.0", 2809 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", 2810 | "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" 2811 | }, 2812 | "p-is-promise": { 2813 | "version": "2.1.0", 2814 | "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", 2815 | "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", 2816 | "dev": true 2817 | }, 2818 | "p-limit": { 2819 | "version": "2.2.0", 2820 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", 2821 | "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", 2822 | "dev": true, 2823 | "requires": { 2824 | "p-try": "^2.0.0" 2825 | } 2826 | }, 2827 | "p-locate": { 2828 | "version": "3.0.0", 2829 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 2830 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 2831 | "dev": true, 2832 | "requires": { 2833 | "p-limit": "^2.0.0" 2834 | } 2835 | }, 2836 | "p-try": { 2837 | "version": "2.2.0", 2838 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 2839 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 2840 | "dev": true 2841 | }, 2842 | "package-json": { 2843 | "version": "4.0.1", 2844 | "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", 2845 | "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", 2846 | "requires": { 2847 | "got": "^6.7.1", 2848 | "registry-auth-token": "^3.0.1", 2849 | "registry-url": "^3.0.3", 2850 | "semver": "^5.1.0" 2851 | } 2852 | }, 2853 | "parseurl": { 2854 | "version": "1.3.3", 2855 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 2856 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 2857 | }, 2858 | "pascalcase": { 2859 | "version": "0.1.1", 2860 | "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", 2861 | "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" 2862 | }, 2863 | "path-dirname": { 2864 | "version": "1.0.2", 2865 | "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", 2866 | "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" 2867 | }, 2868 | "path-exists": { 2869 | "version": "3.0.0", 2870 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 2871 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 2872 | "dev": true 2873 | }, 2874 | "path-is-absolute": { 2875 | "version": "1.0.1", 2876 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 2877 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 2878 | }, 2879 | "path-is-inside": { 2880 | "version": "1.0.2", 2881 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 2882 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" 2883 | }, 2884 | "path-key": { 2885 | "version": "2.0.1", 2886 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 2887 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" 2888 | }, 2889 | "path-to-regexp": { 2890 | "version": "0.1.7", 2891 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 2892 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 2893 | }, 2894 | "pathval": { 2895 | "version": "1.1.0", 2896 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", 2897 | "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", 2898 | "dev": true 2899 | }, 2900 | "pify": { 2901 | "version": "3.0.0", 2902 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 2903 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" 2904 | }, 2905 | "posix-character-classes": { 2906 | "version": "0.1.1", 2907 | "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", 2908 | "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" 2909 | }, 2910 | "prepend-http": { 2911 | "version": "1.0.4", 2912 | "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", 2913 | "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" 2914 | }, 2915 | "process-nextick-args": { 2916 | "version": "2.0.1", 2917 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 2918 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 2919 | }, 2920 | "proxy-addr": { 2921 | "version": "2.0.5", 2922 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", 2923 | "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", 2924 | "requires": { 2925 | "forwarded": "~0.1.2", 2926 | "ipaddr.js": "1.9.0" 2927 | } 2928 | }, 2929 | "pseudomap": { 2930 | "version": "1.0.2", 2931 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 2932 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" 2933 | }, 2934 | "pstree.remy": { 2935 | "version": "1.1.7", 2936 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.7.tgz", 2937 | "integrity": "sha512-xsMgrUwRpuGskEzBFkH8NmTimbZ5PcPup0LA8JJkHIm2IMUbQcpo3yeLNWVrufEYjh8YwtSVh0xz6UeWc5Oh5A==" 2938 | }, 2939 | "pump": { 2940 | "version": "3.0.0", 2941 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 2942 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 2943 | "dev": true, 2944 | "requires": { 2945 | "end-of-stream": "^1.1.0", 2946 | "once": "^1.3.1" 2947 | } 2948 | }, 2949 | "qs": { 2950 | "version": "6.7.0", 2951 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 2952 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 2953 | }, 2954 | "random-bytes": { 2955 | "version": "1.0.0", 2956 | "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", 2957 | "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" 2958 | }, 2959 | "range-parser": { 2960 | "version": "1.2.1", 2961 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 2962 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 2963 | }, 2964 | "raw-body": { 2965 | "version": "2.4.0", 2966 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 2967 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 2968 | "requires": { 2969 | "bytes": "3.1.0", 2970 | "http-errors": "1.7.2", 2971 | "iconv-lite": "0.4.24", 2972 | "unpipe": "1.0.0" 2973 | } 2974 | }, 2975 | "rc": { 2976 | "version": "1.2.8", 2977 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", 2978 | "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", 2979 | "requires": { 2980 | "deep-extend": "^0.6.0", 2981 | "ini": "~1.3.0", 2982 | "minimist": "^1.2.0", 2983 | "strip-json-comments": "~2.0.1" 2984 | } 2985 | }, 2986 | "readable-stream": { 2987 | "version": "2.3.6", 2988 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 2989 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 2990 | "requires": { 2991 | "core-util-is": "~1.0.0", 2992 | "inherits": "~2.0.3", 2993 | "isarray": "~1.0.0", 2994 | "process-nextick-args": "~2.0.0", 2995 | "safe-buffer": "~5.1.1", 2996 | "string_decoder": "~1.1.1", 2997 | "util-deprecate": "~1.0.1" 2998 | }, 2999 | "dependencies": { 3000 | "safe-buffer": { 3001 | "version": "5.1.2", 3002 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 3003 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 3004 | } 3005 | } 3006 | }, 3007 | "readdirp": { 3008 | "version": "2.2.1", 3009 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", 3010 | "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", 3011 | "requires": { 3012 | "graceful-fs": "^4.1.11", 3013 | "micromatch": "^3.1.10", 3014 | "readable-stream": "^2.0.2" 3015 | } 3016 | }, 3017 | "regex-not": { 3018 | "version": "1.0.2", 3019 | "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", 3020 | "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", 3021 | "requires": { 3022 | "extend-shallow": "^3.0.2", 3023 | "safe-regex": "^1.1.0" 3024 | } 3025 | }, 3026 | "regexp-clone": { 3027 | "version": "1.0.0", 3028 | "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz", 3029 | "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==" 3030 | }, 3031 | "registry-auth-token": { 3032 | "version": "3.4.0", 3033 | "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", 3034 | "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", 3035 | "requires": { 3036 | "rc": "^1.1.6", 3037 | "safe-buffer": "^5.0.1" 3038 | } 3039 | }, 3040 | "registry-url": { 3041 | "version": "3.1.0", 3042 | "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", 3043 | "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", 3044 | "requires": { 3045 | "rc": "^1.0.1" 3046 | } 3047 | }, 3048 | "remove-trailing-separator": { 3049 | "version": "1.1.0", 3050 | "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", 3051 | "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" 3052 | }, 3053 | "repeat-element": { 3054 | "version": "1.1.3", 3055 | "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", 3056 | "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" 3057 | }, 3058 | "repeat-string": { 3059 | "version": "1.6.1", 3060 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", 3061 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" 3062 | }, 3063 | "require-directory": { 3064 | "version": "2.1.1", 3065 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 3066 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 3067 | "dev": true 3068 | }, 3069 | "require-main-filename": { 3070 | "version": "2.0.0", 3071 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 3072 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", 3073 | "dev": true 3074 | }, 3075 | "require_optional": { 3076 | "version": "1.0.1", 3077 | "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", 3078 | "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", 3079 | "requires": { 3080 | "resolve-from": "^2.0.0", 3081 | "semver": "^5.1.0" 3082 | } 3083 | }, 3084 | "resolve-from": { 3085 | "version": "2.0.0", 3086 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", 3087 | "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" 3088 | }, 3089 | "resolve-url": { 3090 | "version": "0.2.1", 3091 | "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", 3092 | "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" 3093 | }, 3094 | "ret": { 3095 | "version": "0.1.15", 3096 | "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", 3097 | "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" 3098 | }, 3099 | "safe-buffer": { 3100 | "version": "5.2.0", 3101 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", 3102 | "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" 3103 | }, 3104 | "safe-regex": { 3105 | "version": "1.1.0", 3106 | "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", 3107 | "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", 3108 | "requires": { 3109 | "ret": "~0.1.10" 3110 | } 3111 | }, 3112 | "safer-buffer": { 3113 | "version": "2.1.2", 3114 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 3115 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 3116 | }, 3117 | "saslprep": { 3118 | "version": "1.0.3", 3119 | "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", 3120 | "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", 3121 | "optional": true, 3122 | "requires": { 3123 | "sparse-bitfield": "^3.0.3" 3124 | } 3125 | }, 3126 | "semver": { 3127 | "version": "5.7.0", 3128 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", 3129 | "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" 3130 | }, 3131 | "semver-diff": { 3132 | "version": "2.1.0", 3133 | "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", 3134 | "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", 3135 | "requires": { 3136 | "semver": "^5.0.3" 3137 | } 3138 | }, 3139 | "send": { 3140 | "version": "0.17.1", 3141 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 3142 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 3143 | "requires": { 3144 | "debug": "2.6.9", 3145 | "depd": "~1.1.2", 3146 | "destroy": "~1.0.4", 3147 | "encodeurl": "~1.0.2", 3148 | "escape-html": "~1.0.3", 3149 | "etag": "~1.8.1", 3150 | "fresh": "0.5.2", 3151 | "http-errors": "~1.7.2", 3152 | "mime": "1.6.0", 3153 | "ms": "2.1.1", 3154 | "on-finished": "~2.3.0", 3155 | "range-parser": "~1.2.1", 3156 | "statuses": "~1.5.0" 3157 | }, 3158 | "dependencies": { 3159 | "debug": { 3160 | "version": "2.6.9", 3161 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 3162 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 3163 | "requires": { 3164 | "ms": "2.0.0" 3165 | }, 3166 | "dependencies": { 3167 | "ms": { 3168 | "version": "2.0.0", 3169 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 3170 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 3171 | } 3172 | } 3173 | }, 3174 | "ms": { 3175 | "version": "2.1.1", 3176 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 3177 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 3178 | } 3179 | } 3180 | }, 3181 | "serve-static": { 3182 | "version": "1.14.1", 3183 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 3184 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 3185 | "requires": { 3186 | "encodeurl": "~1.0.2", 3187 | "escape-html": "~1.0.3", 3188 | "parseurl": "~1.3.3", 3189 | "send": "0.17.1" 3190 | } 3191 | }, 3192 | "set-blocking": { 3193 | "version": "2.0.0", 3194 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 3195 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 3196 | "dev": true 3197 | }, 3198 | "set-value": { 3199 | "version": "2.0.1", 3200 | "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", 3201 | "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", 3202 | "requires": { 3203 | "extend-shallow": "^2.0.1", 3204 | "is-extendable": "^0.1.1", 3205 | "is-plain-object": "^2.0.3", 3206 | "split-string": "^3.0.1" 3207 | }, 3208 | "dependencies": { 3209 | "extend-shallow": { 3210 | "version": "2.0.1", 3211 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", 3212 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", 3213 | "requires": { 3214 | "is-extendable": "^0.1.0" 3215 | } 3216 | } 3217 | } 3218 | }, 3219 | "setprototypeof": { 3220 | "version": "1.1.1", 3221 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 3222 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 3223 | }, 3224 | "shebang-command": { 3225 | "version": "1.2.0", 3226 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 3227 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 3228 | "requires": { 3229 | "shebang-regex": "^1.0.0" 3230 | } 3231 | }, 3232 | "shebang-regex": { 3233 | "version": "1.0.0", 3234 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 3235 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" 3236 | }, 3237 | "sift": { 3238 | "version": "7.0.1", 3239 | "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz", 3240 | "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g==" 3241 | }, 3242 | "signal-exit": { 3243 | "version": "3.0.2", 3244 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 3245 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 3246 | }, 3247 | "sliced": { 3248 | "version": "1.0.1", 3249 | "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", 3250 | "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E=" 3251 | }, 3252 | "snapdragon": { 3253 | "version": "0.8.2", 3254 | "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", 3255 | "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", 3256 | "requires": { 3257 | "base": "^0.11.1", 3258 | "debug": "^2.2.0", 3259 | "define-property": "^0.2.5", 3260 | "extend-shallow": "^2.0.1", 3261 | "map-cache": "^0.2.2", 3262 | "source-map": "^0.5.6", 3263 | "source-map-resolve": "^0.5.0", 3264 | "use": "^3.1.0" 3265 | }, 3266 | "dependencies": { 3267 | "debug": { 3268 | "version": "2.6.9", 3269 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 3270 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 3271 | "requires": { 3272 | "ms": "2.0.0" 3273 | } 3274 | }, 3275 | "define-property": { 3276 | "version": "0.2.5", 3277 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", 3278 | "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", 3279 | "requires": { 3280 | "is-descriptor": "^0.1.0" 3281 | } 3282 | }, 3283 | "extend-shallow": { 3284 | "version": "2.0.1", 3285 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", 3286 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", 3287 | "requires": { 3288 | "is-extendable": "^0.1.0" 3289 | } 3290 | } 3291 | } 3292 | }, 3293 | "snapdragon-node": { 3294 | "version": "2.1.1", 3295 | "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", 3296 | "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", 3297 | "requires": { 3298 | "define-property": "^1.0.0", 3299 | "isobject": "^3.0.0", 3300 | "snapdragon-util": "^3.0.1" 3301 | }, 3302 | "dependencies": { 3303 | "define-property": { 3304 | "version": "1.0.0", 3305 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", 3306 | "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", 3307 | "requires": { 3308 | "is-descriptor": "^1.0.0" 3309 | } 3310 | }, 3311 | "is-accessor-descriptor": { 3312 | "version": "1.0.0", 3313 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", 3314 | "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", 3315 | "requires": { 3316 | "kind-of": "^6.0.0" 3317 | } 3318 | }, 3319 | "is-data-descriptor": { 3320 | "version": "1.0.0", 3321 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", 3322 | "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", 3323 | "requires": { 3324 | "kind-of": "^6.0.0" 3325 | } 3326 | }, 3327 | "is-descriptor": { 3328 | "version": "1.0.2", 3329 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", 3330 | "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", 3331 | "requires": { 3332 | "is-accessor-descriptor": "^1.0.0", 3333 | "is-data-descriptor": "^1.0.0", 3334 | "kind-of": "^6.0.2" 3335 | } 3336 | } 3337 | } 3338 | }, 3339 | "snapdragon-util": { 3340 | "version": "3.0.1", 3341 | "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", 3342 | "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", 3343 | "requires": { 3344 | "kind-of": "^3.2.0" 3345 | }, 3346 | "dependencies": { 3347 | "is-buffer": { 3348 | "version": "1.1.6", 3349 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 3350 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 3351 | }, 3352 | "kind-of": { 3353 | "version": "3.2.2", 3354 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 3355 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 3356 | "requires": { 3357 | "is-buffer": "^1.1.5" 3358 | } 3359 | } 3360 | } 3361 | }, 3362 | "source-map": { 3363 | "version": "0.5.7", 3364 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 3365 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" 3366 | }, 3367 | "source-map-resolve": { 3368 | "version": "0.5.2", 3369 | "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", 3370 | "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", 3371 | "requires": { 3372 | "atob": "^2.1.1", 3373 | "decode-uri-component": "^0.2.0", 3374 | "resolve-url": "^0.2.1", 3375 | "source-map-url": "^0.4.0", 3376 | "urix": "^0.1.0" 3377 | } 3378 | }, 3379 | "source-map-url": { 3380 | "version": "0.4.0", 3381 | "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", 3382 | "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" 3383 | }, 3384 | "sparse-bitfield": { 3385 | "version": "3.0.3", 3386 | "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", 3387 | "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", 3388 | "optional": true, 3389 | "requires": { 3390 | "memory-pager": "^1.0.2" 3391 | } 3392 | }, 3393 | "split-string": { 3394 | "version": "3.1.0", 3395 | "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", 3396 | "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", 3397 | "requires": { 3398 | "extend-shallow": "^3.0.0" 3399 | } 3400 | }, 3401 | "sprintf-js": { 3402 | "version": "1.0.3", 3403 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 3404 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 3405 | "dev": true 3406 | }, 3407 | "static-extend": { 3408 | "version": "0.1.2", 3409 | "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", 3410 | "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", 3411 | "requires": { 3412 | "define-property": "^0.2.5", 3413 | "object-copy": "^0.1.0" 3414 | }, 3415 | "dependencies": { 3416 | "define-property": { 3417 | "version": "0.2.5", 3418 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", 3419 | "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", 3420 | "requires": { 3421 | "is-descriptor": "^0.1.0" 3422 | } 3423 | } 3424 | } 3425 | }, 3426 | "statuses": { 3427 | "version": "1.5.0", 3428 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 3429 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 3430 | }, 3431 | "string-width": { 3432 | "version": "2.1.1", 3433 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 3434 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 3435 | "requires": { 3436 | "is-fullwidth-code-point": "^2.0.0", 3437 | "strip-ansi": "^4.0.0" 3438 | } 3439 | }, 3440 | "string_decoder": { 3441 | "version": "1.1.1", 3442 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 3443 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 3444 | "requires": { 3445 | "safe-buffer": "~5.1.0" 3446 | }, 3447 | "dependencies": { 3448 | "safe-buffer": { 3449 | "version": "5.1.2", 3450 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 3451 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 3452 | } 3453 | } 3454 | }, 3455 | "strip-ansi": { 3456 | "version": "4.0.0", 3457 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 3458 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 3459 | "requires": { 3460 | "ansi-regex": "^3.0.0" 3461 | } 3462 | }, 3463 | "strip-eof": { 3464 | "version": "1.0.0", 3465 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", 3466 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" 3467 | }, 3468 | "strip-json-comments": { 3469 | "version": "2.0.1", 3470 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 3471 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" 3472 | }, 3473 | "supports-color": { 3474 | "version": "5.5.0", 3475 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 3476 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 3477 | "requires": { 3478 | "has-flag": "^3.0.0" 3479 | } 3480 | }, 3481 | "term-size": { 3482 | "version": "1.2.0", 3483 | "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", 3484 | "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", 3485 | "requires": { 3486 | "execa": "^0.7.0" 3487 | } 3488 | }, 3489 | "timed-out": { 3490 | "version": "4.0.1", 3491 | "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", 3492 | "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" 3493 | }, 3494 | "to-object-path": { 3495 | "version": "0.3.0", 3496 | "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", 3497 | "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", 3498 | "requires": { 3499 | "kind-of": "^3.0.2" 3500 | }, 3501 | "dependencies": { 3502 | "is-buffer": { 3503 | "version": "1.1.6", 3504 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 3505 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 3506 | }, 3507 | "kind-of": { 3508 | "version": "3.2.2", 3509 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 3510 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 3511 | "requires": { 3512 | "is-buffer": "^1.1.5" 3513 | } 3514 | } 3515 | } 3516 | }, 3517 | "to-regex": { 3518 | "version": "3.0.2", 3519 | "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", 3520 | "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", 3521 | "requires": { 3522 | "define-property": "^2.0.2", 3523 | "extend-shallow": "^3.0.2", 3524 | "regex-not": "^1.0.2", 3525 | "safe-regex": "^1.1.0" 3526 | } 3527 | }, 3528 | "to-regex-range": { 3529 | "version": "2.1.1", 3530 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", 3531 | "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", 3532 | "requires": { 3533 | "is-number": "^3.0.0", 3534 | "repeat-string": "^1.6.1" 3535 | } 3536 | }, 3537 | "toidentifier": { 3538 | "version": "1.0.0", 3539 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 3540 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 3541 | }, 3542 | "touch": { 3543 | "version": "3.1.0", 3544 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", 3545 | "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", 3546 | "requires": { 3547 | "nopt": "~1.0.10" 3548 | } 3549 | }, 3550 | "type-detect": { 3551 | "version": "4.0.8", 3552 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 3553 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 3554 | "dev": true 3555 | }, 3556 | "type-is": { 3557 | "version": "1.6.18", 3558 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 3559 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 3560 | "requires": { 3561 | "media-typer": "0.3.0", 3562 | "mime-types": "~2.1.24" 3563 | } 3564 | }, 3565 | "uid-safe": { 3566 | "version": "2.1.5", 3567 | "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", 3568 | "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", 3569 | "requires": { 3570 | "random-bytes": "~1.0.0" 3571 | } 3572 | }, 3573 | "undefsafe": { 3574 | "version": "2.0.2", 3575 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", 3576 | "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=", 3577 | "requires": { 3578 | "debug": "^2.2.0" 3579 | }, 3580 | "dependencies": { 3581 | "debug": { 3582 | "version": "2.6.9", 3583 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 3584 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 3585 | "requires": { 3586 | "ms": "2.0.0" 3587 | } 3588 | } 3589 | } 3590 | }, 3591 | "union-value": { 3592 | "version": "1.0.1", 3593 | "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", 3594 | "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", 3595 | "requires": { 3596 | "arr-union": "^3.1.0", 3597 | "get-value": "^2.0.6", 3598 | "is-extendable": "^0.1.1", 3599 | "set-value": "^2.0.1" 3600 | } 3601 | }, 3602 | "unique-string": { 3603 | "version": "1.0.0", 3604 | "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", 3605 | "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", 3606 | "requires": { 3607 | "crypto-random-string": "^1.0.0" 3608 | } 3609 | }, 3610 | "unpipe": { 3611 | "version": "1.0.0", 3612 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 3613 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 3614 | }, 3615 | "unset-value": { 3616 | "version": "1.0.0", 3617 | "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", 3618 | "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", 3619 | "requires": { 3620 | "has-value": "^0.3.1", 3621 | "isobject": "^3.0.0" 3622 | }, 3623 | "dependencies": { 3624 | "has-value": { 3625 | "version": "0.3.1", 3626 | "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", 3627 | "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", 3628 | "requires": { 3629 | "get-value": "^2.0.3", 3630 | "has-values": "^0.1.4", 3631 | "isobject": "^2.0.0" 3632 | }, 3633 | "dependencies": { 3634 | "isobject": { 3635 | "version": "2.1.0", 3636 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", 3637 | "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", 3638 | "requires": { 3639 | "isarray": "1.0.0" 3640 | } 3641 | } 3642 | } 3643 | }, 3644 | "has-values": { 3645 | "version": "0.1.4", 3646 | "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", 3647 | "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" 3648 | } 3649 | } 3650 | }, 3651 | "unzip-response": { 3652 | "version": "2.0.1", 3653 | "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", 3654 | "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=" 3655 | }, 3656 | "upath": { 3657 | "version": "1.1.2", 3658 | "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", 3659 | "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==" 3660 | }, 3661 | "update-notifier": { 3662 | "version": "2.5.0", 3663 | "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", 3664 | "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", 3665 | "requires": { 3666 | "boxen": "^1.2.1", 3667 | "chalk": "^2.0.1", 3668 | "configstore": "^3.0.0", 3669 | "import-lazy": "^2.1.0", 3670 | "is-ci": "^1.0.10", 3671 | "is-installed-globally": "^0.1.0", 3672 | "is-npm": "^1.0.0", 3673 | "latest-version": "^3.0.0", 3674 | "semver-diff": "^2.0.0", 3675 | "xdg-basedir": "^3.0.0" 3676 | } 3677 | }, 3678 | "urix": { 3679 | "version": "0.1.0", 3680 | "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", 3681 | "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" 3682 | }, 3683 | "url-parse-lax": { 3684 | "version": "1.0.0", 3685 | "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", 3686 | "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", 3687 | "requires": { 3688 | "prepend-http": "^1.0.1" 3689 | } 3690 | }, 3691 | "use": { 3692 | "version": "3.1.1", 3693 | "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", 3694 | "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" 3695 | }, 3696 | "util-deprecate": { 3697 | "version": "1.0.2", 3698 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 3699 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 3700 | }, 3701 | "utils-merge": { 3702 | "version": "1.0.1", 3703 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 3704 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 3705 | }, 3706 | "vary": { 3707 | "version": "1.1.2", 3708 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 3709 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 3710 | }, 3711 | "which": { 3712 | "version": "1.3.1", 3713 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 3714 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 3715 | "requires": { 3716 | "isexe": "^2.0.0" 3717 | } 3718 | }, 3719 | "which-module": { 3720 | "version": "2.0.0", 3721 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 3722 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", 3723 | "dev": true 3724 | }, 3725 | "wide-align": { 3726 | "version": "1.1.3", 3727 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 3728 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 3729 | "dev": true, 3730 | "requires": { 3731 | "string-width": "^1.0.2 || 2" 3732 | } 3733 | }, 3734 | "widest-line": { 3735 | "version": "2.0.1", 3736 | "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", 3737 | "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", 3738 | "requires": { 3739 | "string-width": "^2.1.1" 3740 | } 3741 | }, 3742 | "wrap-ansi": { 3743 | "version": "2.1.0", 3744 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", 3745 | "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", 3746 | "dev": true, 3747 | "requires": { 3748 | "string-width": "^1.0.1", 3749 | "strip-ansi": "^3.0.1" 3750 | }, 3751 | "dependencies": { 3752 | "ansi-regex": { 3753 | "version": "2.1.1", 3754 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 3755 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 3756 | "dev": true 3757 | }, 3758 | "is-fullwidth-code-point": { 3759 | "version": "1.0.0", 3760 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 3761 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 3762 | "dev": true, 3763 | "requires": { 3764 | "number-is-nan": "^1.0.0" 3765 | } 3766 | }, 3767 | "string-width": { 3768 | "version": "1.0.2", 3769 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 3770 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 3771 | "dev": true, 3772 | "requires": { 3773 | "code-point-at": "^1.0.0", 3774 | "is-fullwidth-code-point": "^1.0.0", 3775 | "strip-ansi": "^3.0.0" 3776 | } 3777 | }, 3778 | "strip-ansi": { 3779 | "version": "3.0.1", 3780 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 3781 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 3782 | "dev": true, 3783 | "requires": { 3784 | "ansi-regex": "^2.0.0" 3785 | } 3786 | } 3787 | } 3788 | }, 3789 | "wrappy": { 3790 | "version": "1.0.2", 3791 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 3792 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 3793 | "dev": true 3794 | }, 3795 | "write-file-atomic": { 3796 | "version": "2.4.3", 3797 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", 3798 | "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", 3799 | "requires": { 3800 | "graceful-fs": "^4.1.11", 3801 | "imurmurhash": "^0.1.4", 3802 | "signal-exit": "^3.0.2" 3803 | } 3804 | }, 3805 | "xdg-basedir": { 3806 | "version": "3.0.0", 3807 | "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", 3808 | "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" 3809 | }, 3810 | "y18n": { 3811 | "version": "4.0.0", 3812 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", 3813 | "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", 3814 | "dev": true 3815 | }, 3816 | "yallist": { 3817 | "version": "2.1.2", 3818 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 3819 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" 3820 | }, 3821 | "yargs": { 3822 | "version": "13.2.2", 3823 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", 3824 | "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", 3825 | "dev": true, 3826 | "requires": { 3827 | "cliui": "^4.0.0", 3828 | "find-up": "^3.0.0", 3829 | "get-caller-file": "^2.0.1", 3830 | "os-locale": "^3.1.0", 3831 | "require-directory": "^2.1.1", 3832 | "require-main-filename": "^2.0.0", 3833 | "set-blocking": "^2.0.0", 3834 | "string-width": "^3.0.0", 3835 | "which-module": "^2.0.0", 3836 | "y18n": "^4.0.0", 3837 | "yargs-parser": "^13.0.0" 3838 | }, 3839 | "dependencies": { 3840 | "ansi-regex": { 3841 | "version": "4.1.0", 3842 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 3843 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 3844 | "dev": true 3845 | }, 3846 | "string-width": { 3847 | "version": "3.1.0", 3848 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 3849 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 3850 | "dev": true, 3851 | "requires": { 3852 | "emoji-regex": "^7.0.1", 3853 | "is-fullwidth-code-point": "^2.0.0", 3854 | "strip-ansi": "^5.1.0" 3855 | } 3856 | }, 3857 | "strip-ansi": { 3858 | "version": "5.2.0", 3859 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 3860 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 3861 | "dev": true, 3862 | "requires": { 3863 | "ansi-regex": "^4.1.0" 3864 | } 3865 | } 3866 | } 3867 | }, 3868 | "yargs-parser": { 3869 | "version": "13.0.0", 3870 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", 3871 | "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", 3872 | "dev": true, 3873 | "requires": { 3874 | "camelcase": "^5.0.0", 3875 | "decamelize": "^1.2.0" 3876 | }, 3877 | "dependencies": { 3878 | "camelcase": { 3879 | "version": "5.3.1", 3880 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 3881 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 3882 | "dev": true 3883 | } 3884 | } 3885 | }, 3886 | "yargs-unparser": { 3887 | "version": "1.5.0", 3888 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", 3889 | "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", 3890 | "dev": true, 3891 | "requires": { 3892 | "flat": "^4.1.0", 3893 | "lodash": "^4.17.11", 3894 | "yargs": "^12.0.5" 3895 | }, 3896 | "dependencies": { 3897 | "camelcase": { 3898 | "version": "5.3.1", 3899 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 3900 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 3901 | "dev": true 3902 | }, 3903 | "get-caller-file": { 3904 | "version": "1.0.3", 3905 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", 3906 | "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", 3907 | "dev": true 3908 | }, 3909 | "require-main-filename": { 3910 | "version": "1.0.1", 3911 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", 3912 | "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", 3913 | "dev": true 3914 | }, 3915 | "yargs": { 3916 | "version": "12.0.5", 3917 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", 3918 | "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", 3919 | "dev": true, 3920 | "requires": { 3921 | "cliui": "^4.0.0", 3922 | "decamelize": "^1.2.0", 3923 | "find-up": "^3.0.0", 3924 | "get-caller-file": "^1.0.1", 3925 | "os-locale": "^3.0.0", 3926 | "require-directory": "^2.1.1", 3927 | "require-main-filename": "^1.0.1", 3928 | "set-blocking": "^2.0.0", 3929 | "string-width": "^2.0.0", 3930 | "which-module": "^2.0.0", 3931 | "y18n": "^3.2.1 || ^4.0.0", 3932 | "yargs-parser": "^11.1.1" 3933 | } 3934 | }, 3935 | "yargs-parser": { 3936 | "version": "11.1.1", 3937 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", 3938 | "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", 3939 | "dev": true, 3940 | "requires": { 3941 | "camelcase": "^5.0.0", 3942 | "decamelize": "^1.2.0" 3943 | } 3944 | } 3945 | } 3946 | } 3947 | } 3948 | } 3949 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lti-node-library", 3 | "version": "0.0.0", 4 | "description": "This is a published npm package for implementing an IMS-Global LTI v1.3 conformant Tool Provider.", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "tests" 8 | }, 9 | "scripts": { 10 | "start": "node server/index.js", 11 | "test": "mocha tests/*.spec.js --exit" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/SanDiegoCodeSchool/lti-node-library.git" 16 | }, 17 | "dependencies": { 18 | "axios": "^0.19.0", 19 | "base64url": "^3.0.1", 20 | "connect-mongo": "^3.0.0", 21 | "dotenv": "^8.0.0", 22 | "ejs": "^2.6.2", 23 | "express": "^4.17.1", 24 | "express-session": "^1.16.2", 25 | "jsonwebtoken": "^8.5.1", 26 | "jwk-to-pem": "^2.0.1", 27 | "mongoose": "^5.6.6", 28 | "morgan": "^1.9.1", 29 | "nodemon": "^1.19.1", 30 | "qs": "^6.7.0" 31 | }, 32 | "devDependencies": { 33 | "chai": "^4.2.0", 34 | "mocha": "^6.2.0" 35 | }, 36 | "keywords": [ 37 | "ims", 38 | "global", 39 | "lti", 40 | "v1.3", 41 | "v1p3", 42 | "lms", 43 | "node", 44 | "javascript", 45 | "express" 46 | ], 47 | "author": "San Diego Code School", 48 | "license": "MIT", 49 | "bugs": { 50 | "url": "https://github.com/SanDiegoCodeSchool/lti-node-library/issues" 51 | }, 52 | "homepage": "https://github.com/SanDiegoCodeSchool/lti-node-library#readme" 53 | } 54 | -------------------------------------------------------------------------------- /tests/oauth_request.spec.js: -------------------------------------------------------------------------------- 1 | const expect = require('chai').expect; 2 | const axios = require('axios'); 3 | const qs = require('qs'); 4 | const app = require('../../../server/server.js'); 5 | 6 | describe('OAuth2.0 flow', function() { 7 | let httpServer = null; 8 | let url = 'http://localhost:8888'; 9 | let token_url = url + '/oauth2/token'; 10 | let good_data = null; 11 | let saved_token = null; 12 | 13 | beforeEach(() => { 14 | good_data = { 15 | 'grant_type': 'client_credentials', 16 | 'client_id': 'uuYLGWBmhhuZvBf', 17 | 'client_secret': '-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAy5CSU1VCiTdrRJnYNXoO91NE5NZYr1tyjsbvghaoabyzm4D9sp40QHReFb1OBZZZAwJYc9o+LRYU83/o5mDwlzyoYpz63wzNbXLF6kYK3JqP93mMXKJAs8q1EThuZCqc4RZAFI/QhMmqovLpKnEHSl8XPgxZOch2vQa14+3XaZdAgbUxfT6x08mFg71X/oNhNxhShiSLJ6xtKxC4+IDtAOlveIdvlfC50LVcMBbZahSo+j/MBVxdDDgTnMpxM3NsI+9aib9uzBjR4Lf43+OCrEOabg9nQbCZ2F2SAr/2+Ubl3ZJe/US4jkhfTbSClQZuSVNmNM+lMGxgXsZiCbzf1QIDAQABAoIBAQCQJRxoY/xMe/C6UBI4s+i7G7yyKlH8Qk4ZaicZQAAbd6LbH3kGLV6ksYIZ9MW10SPQrK2Dw+u5M2S8lDuQPt6+yRYXVj+TCFbDBL2+ycBRPCVrwScyRTZ52bVjr0kEJuSVwpK3vKqUDNWGs2mGQyk9cZ5cspPQBfKGoaTU9ItP2aXQzMY/+KLl46gmu5SK2igEaNIsNi1k41yRw7Sa7RDIH9jdWHlcl7WKxjHlIv21E9p2RUH8vqvNeH8joVH3IyS1w5F6mxaQrHjRp9RlXAkrIrDttn7bJ3jE55AxgvoYC8P3tV+wq/uqCJE+smfkH/umi2CPHzE0OMyQB7n9REh1AoGBAPKE9yZChjOPsf0cTQwnbZEIMZV4K3r+xYDV2kDa1NfEFooo9jsg34n/OMyC6xTgGYE98/10id/unAMNsLlX4PAelc3doBNRUt/bVFoNVHaw2JsghJ6qXm8Uj8rQgcXVOMhXoAQusUOyeL+2PyBhPt193EpNqYpKARx0Zi3waG7bAoGBANbhSLAAGpvaZPulLJ0pI1AF2sf+UifCNFOwByRS3PzPVKWzNU8EuDTUfpUCTQKuU1qmu+jx9moBi8bhkXh7kGOZqv95L7UATZ/Ql/F5S53oH1E6+iEPR2vn83XNHXzCeHuPED2MMugL85KCweMvG5v9fOf6z4ovknR+dOl5FnMPAoGBAKUKyAdJjnrYd5CBCg4TZwUkRloqBa0WZOJgpr8sLV0JHS244pkqrfYDsmu7TLBQMgs6VilOfeXfRFzvnC0GGRZQOjJ3eNCsr3GYmbcPC0Qa5c3sO1SfLNT7cT/c1fQEPzhYKZWvEQO5GWOeaydmBppFZP1MDO0Hn+n1bPQmf2uxAoGBAK0Dd6M+ci5LCkQUGnfwR56HGEEvZLbeh4NamGWG0qg7x8wjHykgg7EF52XTFG60LikvVt2Y9O8lj4Xy2U5JL1kCwcwxp1f1horHSZAEOf5Kh+y/r+YuhzM676xKGxP5AUl7R3hHCjYMaXHuFm713yUaVRfzumdpJmLl7vyNoqXBAoGATG1CDbTdDX/9Pq7RI34by/16IKropqYeb8rWINtp08sIqGYo68EGohP5SDbeyP12pG4idV+6IsY8twv5bz/uhG/HWXQOeGWea8d2lcxQnfirlOVkfdux7CJisdFX4ANcwKNGWrvreFwRch44ZjnT7O4vlQ+ETzb4KXiHFmvjY9A=\n-----END RSA PRIVATE KEY-----' 18 | }; 19 | }); 20 | 21 | before(done => { 22 | httpServer = app.listen(8888); 23 | done(); 24 | }); 25 | 26 | after((done) => { 27 | httpServer.close(); 28 | done(); 29 | }); 30 | 31 | it('should load successfully', () => { 32 | return axios.get(url) 33 | .then(r => expect(r.status).to.equal(200)) 34 | .catch(error => console.log(`***error caught ${error}`)); 35 | }); 36 | 37 | it('should post correctly with good data', () => { 38 | return axios({ 39 | method: 'POST', 40 | url: token_url, 41 | headers: { 'content-type': 'application/x-www-form-urlencoded' }, 42 | data: qs.stringify({ 43 | ...good_data 44 | }) 45 | }) 46 | .then(res => { 47 | saved_token = res.data; 48 | expect(res.status).to.equal(200); 49 | }) 50 | .catch(err => { 51 | console.log(`***error caught: ${err}`); 52 | }); 53 | }); 54 | 55 | it('should get an error if it is missing the data', () => { 56 | return axios({ 57 | method: 'POST', 58 | url: token_url, 59 | headers: { 'content-type': 'application/x-www-form-urlencoded' } 60 | }) 61 | .catch(err => { 62 | expect(err.response.status).to.equal(400); 63 | expect(err.response.data.error).to.equal('invalid_request'); 64 | }) 65 | .catch(error => console.log(`***error caught ${error}`)); 66 | }); 67 | 68 | it('should get an error if it is missing the client id', () => { 69 | return axios({ 70 | method: 'POST', 71 | url: token_url, 72 | headers: { 'content-type': 'application/x-www-form-urlencoded' }, 73 | data: qs.stringify({ 74 | 'grant_type': 'client_credentials', 75 | 'client_secret': 'alisdbvibq87b9v03qrovbasvb83qrbvbacuvbd' 76 | }) 77 | }) 78 | .catch(err => { 79 | expect(err.response.status).to.equal(400); 80 | expect(err.response.data.error).to.equal('invalid_request'); 81 | }) 82 | .catch(error => console.log(`***error caught ${error}`)); 83 | }); 84 | 85 | it('should get an error with an invalid grant type', () => { 86 | return axios({ 87 | method: 'POST', 88 | url: token_url, 89 | headers: { 'content-type': 'application/x-www-form-urlencoded' }, 90 | data: qs.stringify({ 91 | ...good_data, 92 | 'grant_type': 'WHATis THIS?' 93 | }) 94 | }) 95 | .catch(err => { 96 | expect(err.response.status).to.equal(400); 97 | expect(err.response.data.error).to.equal('unsupported_grant_type'); 98 | }) 99 | .catch(error => console.log(`***error caught ${error}`)); 100 | }); 101 | 102 | it('should get an error with an invalid client id', () => { 103 | return axios({ 104 | method: 'POST', 105 | url: token_url, 106 | headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, 107 | data: qs.stringify({ 108 | ...good_data, 109 | 'client_id': '' 110 | }) 111 | }) 112 | .catch(err => { 113 | expect(err.response.status).to.equal(401); 114 | expect(err.response.data.error).to.equal('invalid_client'); 115 | }) 116 | .catch(error => console.log(`***error caught ${error}`)); 117 | }); 118 | 119 | it('should get an error with an invalid secret', () => { 120 | return axios({ 121 | method: 'POST', 122 | url: token_url, 123 | headers: { 'content-type': 'application/x-www-form-urlencoded' }, 124 | data: qs.stringify({ 125 | ...good_data, 126 | 'client_secret': '' 127 | }) 128 | }) 129 | .catch(err => { 130 | expect(err.response.status).to.equal(401); 131 | expect(err.response.data.error).to.equal('invalid_client'); 132 | }) 133 | .catch(error => { 134 | console.log(`***error caught ${error}`); 135 | }); 136 | }); 137 | 138 | }); 139 | 140 | -------------------------------------------------------------------------------- /tests/request_validation.spec.js: -------------------------------------------------------------------------------- 1 | const expect = require('chai').expect; 2 | const { valid_launch_request } = require('../Provider/launch_validation.js'); 3 | 4 | describe('Validate Launch Request', () => { 5 | let req = null; 6 | 7 | beforeEach(() => { 8 | req = { 9 | method: 'POST', 10 | url: 'http://this.is.a.fake.url', 11 | headers: { 12 | 'Content-Type': 'application/json' 13 | }, 14 | body: { 15 | nonce: 'g2f2cdPpYqPK7AwHcyXhjf5VL', 16 | iat: Date.now(), 17 | exp: Date.now() + 3600, 18 | iss: 'https://demo.moodle.net', 19 | aud: 'uuYLGWBmhhuZvBf', 20 | 'https://purl.imsglobal.org/spec/lti/claim/deployment_id': '2', 21 | 'https://purl.imsglobal.org/spec/lti/claim/target_link_uri': 'https://piedpiper.localtunnel.me', 22 | sub: '9', 23 | 'https://purl.imsglobal.org/spec/lti/claim/roles': 24 | [ 'http://purl.imsglobal.org/vocab/lis/v2/membership#Learner' ], 25 | 'https://purl.imsglobal.org/spec/lti/claim/context': 26 | { id: '47', 27 | label: 'AGILE200', 28 | title: 'Internship', 29 | type: [ 'CourseSection' ] }, 30 | 'https://purl.imsglobal.org/spec/lti/claim/resource_link': { title: 'Test LTI for Team Pied Piper', id: '4' }, 31 | given_name: 'John', 32 | family_name: 'Smith', 33 | name: 'John Smith', 34 | 'https://purl.imsglobal.org/spec/lti/claim/ext': 35 | { user_username: 'john.smith@gmail.com', lms: 'moodle-2' }, 36 | email: 'john.smith@gmail.com', 37 | 'https://purl.imsglobal.org/spec/lti/claim/launch_presentation': 38 | { locale: 'en', 39 | document_target: 'window', 40 | return_url: 41 | 'https://www.sandiegocode.school/mod/lti/return.php?course=47&launch_container=4&instanceid=4&sesskey=xcsU4krTwV' }, 42 | 'https://purl.imsglobal.org/spec/lti/claim/tool_platform': 43 | { family_code: 'moodle', 44 | version: '2019052000.01', 45 | guid: 'demo.moodle.net', 46 | name: 'Moodle Demo', 47 | description: 'Moodle Demo Sandbox' }, 48 | 'https://purl.imsglobal.org/spec/lti/claim/version': '1.3.0', 49 | 'https://purl.imsglobal.org/spec/lti/claim/message_type': 'LtiResourceLinkRequest', 50 | 'https://purl.imsglobal.org/spec/lti-ags/claim/endpoint': 51 | { scope: 52 | [ 'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly', 53 | 'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly', 54 | 'https://purl.imsglobal.org/spec/lti-ags/scope/score' ], 55 | lineitems: 56 | 'https://www.sandiegocode.school/mod/lti/services.php/47/lineitems?type_id=2', 57 | lineitem: 58 | 'https://www.sandiegocode.school/mod/lti/services.php/47/lineitems/109/lineitem?type_id=2' }, 59 | 'https://purl.imsglobal.org/spec/lti-nrps/claim/namesroleservice': 60 | { context_memberships_url: 61 | 'https://www.sandiegocode.school/mod/lti/services.php/CourseSection/47/bindings/2/memberships', 62 | service_versions: [ '1.0', '2.0' ] } 63 | }, 64 | json: true, 65 | session: { 66 | login_request: { 67 | iss: 'https://demo.moodle.net', 68 | target_link_uri: 'https://piedpiper.localtunnel.me' 69 | }, 70 | platform_DBinfo: { 71 | consumerToolClientID: 'uuYLGWBmhhuZvBf' 72 | }, 73 | nonce_list: [] 74 | } 75 | }; 76 | 77 | }); 78 | 79 | it('should reject non-POST requests', () => { 80 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 81 | req.method = 'GET'; 82 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Method invalid'); 83 | }); 84 | 85 | it('should correctly validate that message has a type that is LtiResourceLinkRequest and reject if message type is not LtiResourceLinkRequest', () => { 86 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 87 | req.body['https://purl.imsglobal.org/spec/lti/claim/message_type'] = 'not correct'; 88 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('LTI message type invalid'); 89 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/message_type']; 90 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('LTI message type missing'); 91 | }); 92 | 93 | it('should correctly validate that message has a version that is 1.3.0 and reject if not', () => { 94 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 95 | req.body['https://purl.imsglobal.org/spec/lti/claim/version'] = 'not correct'; 96 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('LTI Version invalid'); 97 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/version']; 98 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('LTI Version missing'); 99 | }); 100 | 101 | it('should correctly validate that message has a deployment id that is no more than 255 characters', () => { 102 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 103 | req.body['https://purl.imsglobal.org/spec/lti/claim/deployment_id'] = 'a'.repeat(266); 104 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Deployment ID invalid'); 105 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/deployment_id']; 106 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Deployment ID missing'); 107 | }); 108 | 109 | it('should correctly validate that message has a target link URI to exist', () => { 110 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 111 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/target_link_uri']; 112 | req.session.nonce_list = []; 113 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Target Link URI missing'); 114 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/target_link_uri']; 115 | req.session.nonce_list = []; 116 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Target Link URI missing'); 117 | }); 118 | 119 | it('should correctly validate that message has a resource link id that is no more than 255 characters', () => { 120 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 121 | req.body['https://purl.imsglobal.org/spec/lti/claim/resource_link'].id = 'a'.repeat(266); 122 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Resource Link invalid'); 123 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/resource_link'].id; 124 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Resource Link missing'); 125 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/resource_link']; 126 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Resource Link missing'); 127 | }); 128 | 129 | it('should correctly validate that message has a sub specified that is no more than 255 characters', () => { 130 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 131 | req.body['sub'] = 'a'.repeat(266); 132 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Sub invalid'); 133 | delete req.body['sub']; 134 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Sub missing'); 135 | }); 136 | 137 | it('should correctly validate that message has a role specified that is valid', () => { 138 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 139 | req.body['https://purl.imsglobal.org/spec/lti/claim/roles'] = []; 140 | req.session.nonce_list = []; 141 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 142 | req.session.nonce_list = []; 143 | req.body['https://purl.imsglobal.org/spec/lti/claim/roles'] = ['WRONGhttp://purl.imsglobal.org/vocab/lis/v2/institution/person#Student']; 144 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Role invalid'); 145 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/roles']; 146 | req.session.nonce_list = []; 147 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Role missing'); 148 | }); 149 | 150 | it('should correctly validate Context if it is present', () => { 151 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 152 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/context'].title; 153 | req.session.nonce_list = []; 154 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 155 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/context'].label; 156 | req.session.nonce_list = []; 157 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Context invalid: does not contain label OR title'); 158 | req.body['https://purl.imsglobal.org/spec/lti/claim/context'].type = ['WRONGhttp://purl.imsglobal.org/vocab/lis/v2/course#CourseOffering']; 159 | req.session.nonce_list = []; 160 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Context invalid: type invalid'); 161 | req.body['https://purl.imsglobal.org/spec/lti/claim/context'].type = []; 162 | req.session.nonce_list = []; 163 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Context invalid: type invalid') 164 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/context'].type; 165 | req.session.nonce_list = []; 166 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Context type missing') 167 | }); 168 | 169 | it('should not give an error if Context is NOT present', () => { 170 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/context']; 171 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.is.empty; 172 | }); 173 | 174 | it('should check name information correctly', () => { 175 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 176 | req.body.name = 5; 177 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Name information invalid') 178 | }); 179 | 180 | it('should not give an error if Name information is NOT present', () => { 181 | delete req.body.name; 182 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.is.empty; 183 | req.session.nonce_list = []; 184 | delete req.body.given_name; 185 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.is.empty; 186 | delete req.body.family_name; 187 | req.session.nonce_list = []; 188 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.is.empty; 189 | }); 190 | 191 | it('should correctly validate Endpoint if it is present', () => { 192 | expect(valid_launch_request(req.body, req)).to.have.lengthOf(0); 193 | delete req.body['https://purl.imsglobal.org/spec/lti-ags/claim/endpoint'].lineitem; 194 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Score setup invalid'); 195 | delete req.body['https://purl.imsglobal.org/spec/lti-ags/claim/endpoint'].lineitems; 196 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Score setup invalid'); 197 | req.body['https://purl.imsglobal.org/spec/lti-ags/claim/endpoint'].scope = []; 198 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Score setup invalid') 199 | delete req.body['https://purl.imsglobal.org/spec/lti-ags/claim/endpoint'].scope; 200 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.includes('Score setup invalid') 201 | }); 202 | 203 | it('should not give an error if Endpoint is NOT present', () => { 204 | delete req.body['https://purl.imsglobal.org/spec/lti/claim/endpoint']; 205 | expect(valid_launch_request(req.body, req)).to.be.an('array').that.is.empty; 206 | }); 207 | 208 | }); 209 | --------------------------------------------------------------------------------