From f6e73a6cf576e6f5739c09b77ee5c361585448b2 Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Mon, 20 Mar 2023 17:43:13 -0700 Subject: [PATCH 01/22] got basic functionality on first iteration of elevator --- elevator/elevator.js | 212 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 elevator/elevator.js diff --git a/elevator/elevator.js b/elevator/elevator.js new file mode 100644 index 0000000..425ba04 --- /dev/null +++ b/elevator/elevator.js @@ -0,0 +1,212 @@ +// need to have the elevator constantly moving from 0 -> this.floors +// check if the next floor has any requests before we are moving +// this will ensure that we are never checking during and if we are between 4 and 5 and a request comes in we won't stop and pick up at 5 + +const fs = require('fs'); +const os = require('os'); + + +class Elevator { + constructor(floors) { + this.floors = floors; + this.state = 'stopped' + this.currentFloor = 0; + this.currentDirection = 1; + // this.currentDestination = 0; + // this.numOfPassengers = 0; + this.departMap = new Map(); + this.requestMap = new Map(); + + this.travelInterval = 3000; + this.stopInterval = 1000; + } + + move() { + if(!this.requestMap.size && !this.departMap.size) { + fs.appendFileSync('output.txt', 'we are done \n'); + return; + } + + // check if we are at top floor or bottom floor + if(this.currentDirection === 1 && this.currentFloor === this.floors - 1) { + this.currentDirection = -1; + } else if(this.currentDirection === -1 && this.currentFloor === 0) { + this.currentDirection = 1; + } + + // increment floor based on direction - change state to moving + this.currentFloor += this.currentDirection; + this.state = 'moving'; + + this.checkStop(); + } + + + checkStop() { + // run this.check and will return 2 arrays + const gettingOn = this.checkOn(); + const gettingOff = this.checkOff(); + + // if either array has a length we know we need to stop at the next floor + // make function here to board and depart elevator + if(gettingOn.length || gettingOff.length) { + // stop the elevator + this.state = 'stopped' + this.stop(gettingOn, gettingOff); + } else { + // call move again from next floor + this.move = this.move.bind(this); + setTimeout(this.move, this.travelInterval) + } + } + + + // we stop for 1 second + // we must board and deboard all passengers + // if we are stopped at a floor we should be able to check if any other requests to board at this floor have come in + + // this.requestMap.get(currentFloor).push({destination, direction, weight}); + stop(gettingOn, gettingOff) { + + // console.log(gettingOn); + // first we should remove everyone from the current departMap + if(gettingOff.length) { + // console.log(gettingOff); + + let output = 'current floor: ' + this.currentFloor.toString() + ' ' + JSON.stringify(this.departMap.get(this.currentFloor)) + 'all got off'; + fs.appendFileSync('output.txt', output + os.EOL); + this.departMap.delete(this.currentFloor); + + } + + + // next we must add all the current requests + + if(gettingOn.length) { + const currentFloorRequests = this.requestMap.get(this.currentFloor); + for(let i = currentFloorRequests.length - 1; i >= 0; i--) { + const {destination, direction, weight, name} = currentFloorRequests[i]; + + if(direction === this.currentDirection) { + this.passengerBoard(destination, weight, currentFloorRequests, i, name); + } + + + } + if(currentFloorRequests.length === 0) this.requestMap.delete(this.currentFloor); + + } + + this.move = this.move.bind(this); + setTimeout(this.move, this.stopInterval); + + + + } + + // this can be improved if we change how we store the data in the g et on map -> all up requests in one array / all down in another + passengerBoard(destination, weight, requestArray, index, name) { + // add to the depart map + if(this.departMap.get(destination) === undefined) { + this.departMap.set(destination, []); + } + + this.departMap.get(destination).push(name); + const output = 'current floor: ' + this.currentFloor.toString() + ' ' + JSON.stringify('destination: ' + destination + ' weight: ' + weight + ' name: ' + name + ' got on'); + fs.appendFileSync('output.txt', output + os.EOL); + + + // delete from the requestmap + requestArray.splice(index, 1); + + + } + + + // we should keep track of how many passengers are getting off so we can more easily know the weight when + // I decide to add that feature + + // should return an array of which passengers are getting on and where tf they're going + checkOff() { + // this will check if someone needs to get off + const gettingOff = []; + if(this.departMap.get(this.currentFloor) !== undefined) { + + gettingOff.push(...this.departMap.get(this.currentFloor)); + // this.departMap.delete(this.currentFloor); + } + console.log('checkoff getting off: ' + gettingOff); + return gettingOff; + } + + checkOn() { + const gettingOn = []; + // check if someone has made a request to get on + // this leads into does someone need to go in the same direction we are moving + if(this.requestMap.get(this.currentFloor) !== undefined) { + // returns the array of current requests at the floor + const currentFloorRequestArray = this.requestMap.get(this.currentFloor); + + // if the person in the array is going the same direction as the elevator then they will get added to getting on array + for(let i = 0; i < currentFloorRequestArray.length; i++) { + const {direction} = currentFloorRequestArray[i]; + if(direction === this.currentDirection) { + gettingOn.push(currentFloorRequestArray[i]) + } + } + } + return gettingOn; + + } + + + // we need to make sure the map is from Key > value ---> currentFloor -> [{destination, direction}, {destination, direction}] + request(request) { + const {currentFloor, destination, direction, weight, name} = request; + + // ****need to add bounds here**** + + if(this.requestMap.get(currentFloor) === undefined) { + this.requestMap.set(currentFloor, []); + } + this.requestMap.get(currentFloor).push({destination, direction, weight,name}); + } + +} + + + +// ** shouldn't be able to have the same destination and current floor +// ** also shouldn't be able to hit up on the elevator but also go down in the request +class Request { + constructor(currentFloor, destination, direction, weight, name) { + Object.assign(this, {currentFloor, destination, direction, weight,name}) + } +} + + +// create new elevator +// create new request +// add to the requestMap with request method +// see if the check works for that floor + + +const elevator = new Elevator(5); + +// request: currentfloor, destination, direction, weight +const aRequest = new Request(1, 2, 1,0,'shay'); +const bRequest = new Request(2, 3, 1,0,'sadie'); +const cRequest = new Request(3, 1, -1, 0,'mom'); +const dRequest = new Request(1, 4, 1,0,'dad'); + +elevator.request(aRequest) +elevator.request(bRequest) +elevator.request(cRequest) +elevator.request(dRequest) + +fs.writeFileSync('output.txt', ''); +elevator.move(); + + + + From b66179c21395f03a4c0a5e6020183d6c85597a83 Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Tue, 21 Mar 2023 21:01:02 -0700 Subject: [PATCH 02/22] Finished user input functionality on slower algorithm --- elevator/elevator.js | 140 +++++++++++++++++++++---------------------- elevator/main.js | 55 +++++++++++++++++ elevator/request.js | 14 +++++ 3 files changed, 137 insertions(+), 72 deletions(-) create mode 100644 elevator/main.js create mode 100644 elevator/request.js diff --git a/elevator/elevator.js b/elevator/elevator.js index 425ba04..7d4ffec 100644 --- a/elevator/elevator.js +++ b/elevator/elevator.js @@ -2,28 +2,39 @@ // check if the next floor has any requests before we are moving // this will ensure that we are never checking during and if we are between 4 and 5 and a request comes in we won't stop and pick up at 5 +// to write to new files for output const fs = require('fs'); + +// to add EOL character to file output const os = require('os'); +const output = txt => { + fs.appendFileSync('output.txt', txt + os.EOL); +} + class Elevator { constructor(floors) { this.floors = floors; this.state = 'stopped' this.currentFloor = 0; this.currentDirection = 1; + this.passengerCount = 0; // this.currentDestination = 0; - // this.numOfPassengers = 0; this.departMap = new Map(); this.requestMap = new Map(); - this.travelInterval = 3000; - this.stopInterval = 1000; + this.travelInterval = 1500; + this.stopInterval = 500; + this.quit = false; + this.passengerQueue = []; } move() { - if(!this.requestMap.size && !this.departMap.size) { - fs.appendFileSync('output.txt', 'we are done \n'); + output('Current floor: ' + this.currentFloor); + + if(this.quit) { + fs.appendFileSync('output.txt', 'we are done' + os.EOL); return; } @@ -37,7 +48,6 @@ class Elevator { // increment floor based on direction - change state to moving this.currentFloor += this.currentDirection; this.state = 'moving'; - this.checkStop(); } @@ -46,7 +56,7 @@ class Elevator { // run this.check and will return 2 arrays const gettingOn = this.checkOn(); const gettingOff = this.checkOff(); - + // console.log(gettingOn, gettingOff); // if either array has a length we know we need to stop at the next floor // make function here to board and depart elevator if(gettingOn.length || gettingOff.length) { @@ -56,8 +66,9 @@ class Elevator { } else { // call move again from next floor this.move = this.move.bind(this); - setTimeout(this.move, this.travelInterval) + setTimeout(this.move, this.travelInterval); } + } @@ -68,32 +79,28 @@ class Elevator { // this.requestMap.get(currentFloor).push({destination, direction, weight}); stop(gettingOn, gettingOff) { - // console.log(gettingOn); // first we should remove everyone from the current departMap if(gettingOff.length) { - // console.log(gettingOff); - - let output = 'current floor: ' + this.currentFloor.toString() + ' ' + JSON.stringify(this.departMap.get(this.currentFloor)) + 'all got off'; - fs.appendFileSync('output.txt', output + os.EOL); - this.departMap.delete(this.currentFloor); - + output(JSON.stringify(gettingOff) + 'all got off ' + this.currentFloor); + output('passenger off count : ' + this.passengerCount); } - // next we must add all the current requests + // ** can make a new array to hold the passengers who haven't put their destination request in yet ** // + if(gettingOn.length) { - const currentFloorRequests = this.requestMap.get(this.currentFloor); + const currentFloorRequests = this.requestMap.get(this.currentFloor.toString()); for(let i = currentFloorRequests.length - 1; i >= 0; i--) { - const {destination, direction, weight, name} = currentFloorRequests[i]; - + const {direction, weight} = currentFloorRequests[i]; if(direction === this.currentDirection) { - this.passengerBoard(destination, weight, currentFloorRequests, i, name); + + this.passengerBoard(weight, currentFloorRequests, i); } } - if(currentFloorRequests.length === 0) this.requestMap.delete(this.currentFloor); + if(currentFloorRequests.length === 0) this.requestMap.delete(this.currentFloor.toString()); } @@ -105,20 +112,26 @@ class Elevator { } // this can be improved if we change how we store the data in the g et on map -> all up requests in one array / all down in another - passengerBoard(destination, weight, requestArray, index, name) { - // add to the depart map - if(this.departMap.get(destination) === undefined) { - this.departMap.set(destination, []); - } + passengerBoard(weight, requestArray, index) { + + // add to the passenger queue for passengers who haven't yet chosen a destination + this.passengerQueue.push(weight); + + // delete from the requestmap + requestArray.splice(index, 1); - this.departMap.get(destination).push(name); - const output = 'current floor: ' + this.currentFloor.toString() + ' ' + JSON.stringify('destination: ' + destination + ' weight: ' + weight + ' name: ' + name + ' got on'); - fs.appendFileSync('output.txt', output + os.EOL); + } - // delete from the requestmap - requestArray.splice(index, 1); + // this could be improved conceptually if I used a queue but I got lazy and didn't want to implement one + selectFloor(floor) { + const weight = this.passengerQueue.shift(); + if(this.departMap.get(floor.toString()) === undefined) { + this.departMap.set(floor.toString(), []); + } + this.departMap.get(floor.toString()).push(weight); + // output('departed on floor ' + floor) } @@ -130,12 +143,12 @@ class Elevator { checkOff() { // this will check if someone needs to get off const gettingOff = []; - if(this.departMap.get(this.currentFloor) !== undefined) { + if(this.departMap.get(this.currentFloor.toString()) !== undefined) { - gettingOff.push(...this.departMap.get(this.currentFloor)); - // this.departMap.delete(this.currentFloor); + gettingOff.push(...this.departMap.get(this.currentFloor.toString())); + this.passengerCount += gettingOff.length; + this.departMap.delete(this.currentFloor.toString()); } - console.log('checkoff getting off: ' + gettingOff); return gettingOff; } @@ -143,70 +156,53 @@ class Elevator { const gettingOn = []; // check if someone has made a request to get on // this leads into does someone need to go in the same direction we are moving - if(this.requestMap.get(this.currentFloor) !== undefined) { - // returns the array of current requests at the floor - const currentFloorRequestArray = this.requestMap.get(this.currentFloor); - - // if the person in the array is going the same direction as the elevator then they will get added to getting on array - for(let i = 0; i < currentFloorRequestArray.length; i++) { - const {direction} = currentFloorRequestArray[i]; - if(direction === this.currentDirection) { - gettingOn.push(currentFloorRequestArray[i]) - } + + if(this.requestMap.get(this.currentFloor.toString()) !== undefined) { + // returns the array of current requests at the floor + const currentFloorRequestArray = this.requestMap.get(this.currentFloor.toString()); + + // if the person in the array is going the same direction as the elevator then they will get added to getting on array + for(let i = 0; i < currentFloorRequestArray.length; i++) { + const {direction} = currentFloorRequestArray[i]; + if(direction === this.currentDirection) { + gettingOn.push(currentFloorRequestArray[i]) } } - return gettingOn; + } + // output('getting on array : ', JSON.stringify(gettingOn)) + return gettingOn; } // we need to make sure the map is from Key > value ---> currentFloor -> [{destination, direction}, {destination, direction}] request(request) { - const {currentFloor, destination, direction, weight, name} = request; + const {currentFloor, direction, weight} = request; // ****need to add bounds here**** if(this.requestMap.get(currentFloor) === undefined) { this.requestMap.set(currentFloor, []); } - this.requestMap.get(currentFloor).push({destination, direction, weight,name}); + this.requestMap.get(currentFloor).push({direction, weight}); } -} - + -// ** shouldn't be able to have the same destination and current floor -// ** also shouldn't be able to hit up on the elevator but also go down in the request -class Request { - constructor(currentFloor, destination, direction, weight, name) { - Object.assign(this, {currentFloor, destination, direction, weight,name}) - } } -// create new elevator -// create new request -// add to the requestMap with request method -// see if the check works for that floor -const elevator = new Elevator(5); +// ** shouldn't be able to have the same destination and current floor +// ** also shouldn't be able to hit up on the elevator but also go down in the request + -// request: currentfloor, destination, direction, weight -const aRequest = new Request(1, 2, 1,0,'shay'); -const bRequest = new Request(2, 3, 1,0,'sadie'); -const cRequest = new Request(3, 1, -1, 0,'mom'); -const dRequest = new Request(1, 4, 1,0,'dad'); -elevator.request(aRequest) -elevator.request(bRequest) -elevator.request(cRequest) -elevator.request(dRequest) -fs.writeFileSync('output.txt', ''); -elevator.move(); +module.exports = {Elevator}; diff --git a/elevator/main.js b/elevator/main.js new file mode 100644 index 0000000..ee02fc1 --- /dev/null +++ b/elevator/main.js @@ -0,0 +1,55 @@ +const {Elevator} = require('./elevator'); +const {Request} = require('./request'); +const fs = require('fs'); +const readline = require('readline'); +const os = require('os'); + +const output = txt => { + fs.appendFileSync('output.txt', txt + os.EOL); +} +// Create an interface for reading from the command line +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + + +const elevator = new Elevator(5); +elevator.move(); + +const question = () => { + + + rl.question('What floor are you on and which direction are you going, OR which floor do you want to request?', (answer) => { + if(answer.at(-1).toLowerCase() === 'u') { + createRequest(answer.slice(0,-1), 1); + } else if (answer.at(-1).toLowerCase() === 'd') { + createRequest(answer.slice(0,-1), -1); + } else if(answer === 'quit') { + console.log('quitting...'); + rl.close(); + process.exit(); + } else { + if(elevator.passengerQueue.length) { + elevator.selectFloor(answer); + + } else { + + } + } + question(); + }) +} + + +const createRequest = (floor, direction) => { + const req = new Request(floor, direction, 0); + elevator.request(req); +} + + +fs.writeFileSync('output.txt', ''); +question(); + + + diff --git a/elevator/request.js b/elevator/request.js new file mode 100644 index 0000000..49cbac9 --- /dev/null +++ b/elevator/request.js @@ -0,0 +1,14 @@ +class Request { + constructor(currentFloor, direction, weight = 0) { + Object.assign(this, {currentFloor, direction, weight}) + this.destination = undefined; + } + + floorRequest(floor) { + if(this.destination === undefined) { + this.destination = floor; + } + } +} + +module.exports = {Request}; \ No newline at end of file From 0bd7f9128cd8b59b49dc364b4892cd36d89cb4f9 Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Wed, 22 Mar 2023 12:34:12 -0700 Subject: [PATCH 03/22] Finished quit functionality for slower algorithm --- elevator/elevator.js | 16 +++++++++------- elevator/main.js | 20 ++++++++++++++------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/elevator/elevator.js b/elevator/elevator.js index 7d4ffec..0cf1814 100644 --- a/elevator/elevator.js +++ b/elevator/elevator.js @@ -30,12 +30,17 @@ class Elevator { this.passengerQueue = []; } + stopProcess() { + this.quit = true; + } + move() { + output('Current floor: ' + this.currentFloor); - if(this.quit) { - fs.appendFileSync('output.txt', 'we are done' + os.EOL); - return; + if(this.quit && !this.requestMap.size && !this.departMap.size && !this.passengerQueue.length) { + output('we are done'); + process.exit(); } // check if we are at top floor or bottom floor @@ -185,10 +190,7 @@ class Elevator { this.requestMap.set(currentFloor, []); } this.requestMap.get(currentFloor).push({direction, weight}); - } - - - + } } diff --git a/elevator/main.js b/elevator/main.js index ee02fc1..c577018 100644 --- a/elevator/main.js +++ b/elevator/main.js @@ -19,7 +19,17 @@ elevator.move(); const question = () => { - + if(elevator.quit) { + if(elevator.passengerQueue.length) { + rl.question('No more outside requests at this time. Please input which floor is your destination', (answer) => { + elevator.selectFloor(answer); + }) + question() + } else { + rl.close(); + } + } + rl.question('What floor are you on and which direction are you going, OR which floor do you want to request?', (answer) => { if(answer.at(-1).toLowerCase() === 'u') { createRequest(answer.slice(0,-1), 1); @@ -27,18 +37,16 @@ const question = () => { createRequest(answer.slice(0,-1), -1); } else if(answer === 'quit') { console.log('quitting...'); + elevator.stopProcess(); rl.close(); process.exit(); } else { if(elevator.passengerQueue.length) { elevator.selectFloor(answer); - - } else { - } + } - question(); - }) + question()}); } From efb04e079d76b8292658d1b6b089e70be5645267 Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Sun, 26 Mar 2023 17:45:09 -0700 Subject: [PATCH 04/22] Starting to work on functionality where if elevator is not moving passenger can board at same floor --- elevator/elevator.js | 264 ++++++++++++++++++++++++------------------- elevator/main.js | 14 +-- elevator/request.js | 9 +- 3 files changed, 159 insertions(+), 128 deletions(-) diff --git a/elevator/elevator.js b/elevator/elevator.js index 0cf1814..076a818 100644 --- a/elevator/elevator.js +++ b/elevator/elevator.js @@ -1,7 +1,3 @@ -// need to have the elevator constantly moving from 0 -> this.floors -// check if the next floor has any requests before we are moving -// this will ensure that we are never checking during and if we are between 4 and 5 and a request comes in we won't stop and pick up at 5 - // to write to new files for output const fs = require('fs'); @@ -20,191 +16,221 @@ class Elevator { this.currentFloor = 0; this.currentDirection = 1; this.passengerCount = 0; - // this.currentDestination = 0; + this.currentDestination = -1; this.departMap = new Map(); - this.requestMap = new Map(); + this.requestObj = {}; this.travelInterval = 1500; this.stopInterval = 500; this.quit = false; this.passengerQueue = []; - } - stopProcess() { - this.quit = true; + this.on = []; + this.off = []; } + + /* ****** problems with move function + elevator takes 3s to move from floor to floor + + we need to check who is getting on / off -> then after we do -> we need to either tell the elevator to stop at next floor or continue to the next + when we get to the next floor -> if we are stopped -> people get on or off -> we then decide next direction / destination + if we get to next floor and don't stop -> check next floor -> wait 3s to get there -> repeat again + + the problem with the check destination thing is that we are checking destination before people have gotten on the elevator and the array in reqobj has been deleted + so it checks the destination and just moves in the opposite direction even though there isn't really any need to stop ? + + probably can circumvent this by not checking the current req floor array + + */ + + + + // still need to log here; move() { + this.move = this.move.bind(this); - output('Current floor: ' + this.currentFloor); - - if(this.quit && !this.requestMap.size && !this.departMap.size && !this.passengerQueue.length) { - output('we are done'); - process.exit(); - } + output('Current Floor: ' + this.currentFloor); + const changedDirection = this.decideDirection(); - // check if we are at top floor or bottom floor - if(this.currentDirection === 1 && this.currentFloor === this.floors - 1) { - this.currentDirection = -1; - } else if(this.currentDirection === -1 && this.currentFloor === 0) { - this.currentDirection = 1; + if(this.currentDestination === -1) { + setTimeout(this.move, this.stopInterval); + return; } - // increment floor based on direction - change state to moving this.currentFloor += this.currentDirection; - this.state = 'moving'; - this.checkStop(); - } - - checkStop() { - // run this.check and will return 2 arrays const gettingOn = this.checkOn(); + output(gettingOn); const gettingOff = this.checkOff(); - // console.log(gettingOn, gettingOff); - // if either array has a length we know we need to stop at the next floor - // make function here to board and depart elevator + if(gettingOn.length || gettingOff.length) { - // stop the elevator - this.state = 'stopped' + this.state = 'stopped'; this.stop(gettingOn, gettingOff); - } else { - // call move again from next floor - this.move = this.move.bind(this); - setTimeout(this.move, this.travelInterval); + return; } + + setTimeout(this.move, this.travelInterval); } - - - // we stop for 1 second - // we must board and deboard all passengers - // if we are stopped at a floor we should be able to check if any other requests to board at this floor have come in - // this.requestMap.get(currentFloor).push({destination, direction, weight}); - stop(gettingOn, gettingOff) { - - // first we should remove everyone from the current departMap - if(gettingOff.length) { - output(JSON.stringify(gettingOff) + 'all got off ' + this.currentFloor); - output('passenger off count : ' + this.passengerCount); - } - - // next we must add all the current requests - - // ** can make a new array to hold the passengers who haven't put their destination request in yet ** // + decideDirection() { - if(gettingOn.length) { - const currentFloorRequests = this.requestMap.get(this.currentFloor.toString()); - for(let i = currentFloorRequests.length - 1; i >= 0; i--) { - const {direction, weight} = currentFloorRequests[i]; - if(direction === this.currentDirection) { - - this.passengerBoard(weight, currentFloorRequests, i); - } + // we must change direction here because we are at the top or bottom floor + if(this.currentFloor === 0) { + this.currentDirection = 1; + } else if(this.currentFloor === this.floors) { + this.currentDirection = -1; + } else if(this.currentDestination === this.currentFloor) { - + // if there are no requests going in the same direction as we were just traveling at target floor + if(!this.requestObj[this.currentFloor][this.currentDirection].length) { + this.currentDirection = this.currentDirection === 1 ? -1 : 1; } - if(currentFloorRequests.length === 0) this.requestMap.delete(this.currentFloor.toString()); - } + } - this.move = this.move.bind(this); - setTimeout(this.move, this.stopInterval); - + // decides destination when we have reached current destination + // we also may need to keep track if there have been any requests made in the wrong direction? + decideDestination() { + const keys = Object.keys(this.requestObj); + keys.push(...Array.from(this.departMap.keys())); + keys.sort((a,b) => a-b); + + // if there are no requests to serve => do nothing; + if(!keys.length) { + this.currentDestination = -1; + return; + } + if(this.currentDirection === 1) { + this.currentDestination = keys.at(-1); + } else if(this.currentDestination === -1) { + this.currentDestination = keys[0]; + } } - // this can be improved if we change how we store the data in the g et on map -> all up requests in one array / all down in another - passengerBoard(weight, requestArray, index) { - - // add to the passenger queue for passengers who haven't yet chosen a destination - this.passengerQueue.push(weight); - - // delete from the requestmap - requestArray.splice(index, 1); - - } + stop(gettingOn, gettingOff) { - // this could be improved conceptually if I used a queue but I got lazy and didn't want to implement one - selectFloor(floor) { - const weight = this.passengerQueue.shift(); - if(this.departMap.get(floor.toString()) === undefined) { - this.departMap.set(floor.toString(), []); + if(gettingOff.length) { + output(JSON.stringify(gettingOff) + 'all got off ' + this.currentFloor); + output('passenger off count : ' + this.passengerCount); } - this.departMap.get(floor.toString()).push(weight); - // output('departed on floor ' + floor) + if(gettingOn.length) { + this.passengerQueue.push(...gettingOn); + output(JSON.stringify(gettingOff) + ' all got on ' + this.currentFloor) + } + this.move = this.move.bind(this); + setTimeout(this.move, this.stopInterval); } - - - // we should keep track of how many passengers are getting off so we can more easily know the weight when - // I decide to add that feature - // should return an array of which passengers are getting on and where tf they're going checkOff() { - // this will check if someone needs to get off const gettingOff = []; - if(this.departMap.get(this.currentFloor.toString()) !== undefined) { + // const nextFloor = this.currentFloor + this.currentDirection; + if(this.departMap.get(this.currentFloor) !== undefined) { - gettingOff.push(...this.departMap.get(this.currentFloor.toString())); + gettingOff.push(...this.departMap.get(this.currentFloor)); this.passengerCount += gettingOff.length; - this.departMap.delete(this.currentFloor.toString()); + this.departMap.delete(nextFloor); } return gettingOff; } checkOn() { const gettingOn = []; - // check if someone has made a request to get on - // this leads into does someone need to go in the same direction we are moving - - if(this.requestMap.get(this.currentFloor.toString()) !== undefined) { - // returns the array of current requests at the floor - const currentFloorRequestArray = this.requestMap.get(this.currentFloor.toString()); - - // if the person in the array is going the same direction as the elevator then they will get added to getting on array - for(let i = 0; i < currentFloorRequestArray.length; i++) { - const {direction} = currentFloorRequestArray[i]; - if(direction === this.currentDirection) { - gettingOn.push(currentFloorRequestArray[i]) - } + // const nextFloor = this.currentFloor + this.currentDirection; + + if(this.requestObj[this.currentFloor] !== undefined) { + gettingOn.push(...this.requestObj[this.currentFloor][this.currentDirection]) + this.requestObj[this.currentFloor][this.currentDirection] = []; + + if(!this.requestObj[this.currentFloor][this.currentDirection * -1].length) { + delete this.requestObj[this.currentFloor]; } + } - // output('getting on array : ', JSON.stringify(gettingOn)) + return gettingOn; + } + + selectFloor(floor) { + const weight = this.passengerQueue.shift(); + if(this.departMap.get(floor) === undefined) { + this.departMap.set(floor, []); + } + + this.departMap.get(floor).push(weight); } - // we need to make sure the map is from Key > value ---> currentFloor -> [{destination, direction}, {destination, direction}] request(request) { const {currentFloor, direction, weight} = request; - - // ****need to add bounds here**** - - if(this.requestMap.get(currentFloor) === undefined) { - this.requestMap.set(currentFloor, []); + if(this.requestObj[currentFloor] === undefined) { + this.requestObj[currentFloor] = { + 1: [], + '-1': [] + } } - this.requestMap.get(currentFloor).push({direction, weight}); - } -} + this.requestObj[currentFloor][direction].push(weight); + if(this.currentDestination === -1) { + this.currentDestination = currentFloor; + if(currentFloor < this.currentDestination) { + this.currentDirection = 1; + } else if(currentFloor > this.currentDestination) { + this.currentDirection = -1; + } + return; + } + + // change current destination if new floor request is further up or down in correct direction as elevator is currently traveling + if(this.currentDirection === 1) { + if(currentFloor > this.currentDestination) this.currentDestination = currentFloor; + } else if(this.currentDirection === -1) { + if(currentFloor < this.currentDestination) this.currentDestination = currentFloor; + } + } + stopProcess() { + this.quit = true; + } -// ** shouldn't be able to have the same destination and current floor -// ** also shouldn't be able to hit up on the elevator but also go down in the request +} +module.exports = {Elevator}; +const obj = {}; -module.exports = {Elevator}; +// console.log(obj.keys()) +console.log(Object.keys(obj)); +// console.log(obj.keys.length) + // move() { + // output('Current floor: ' + this.currentFloor); + + // if(this.quit && !this.requestMap.size && !this.departMap.size && !this.passengerQueue.length) { + // output('we are done'); + // process.exit(); + // } + + // if(this.currentDirection === 1 && this.currentFloor === this.floors - 1) { + // this.currentDirection = -1; + // } else if(this.currentDirection === -1 && this.currentFloor === 0) { + // this.currentDirection = 1; + // } + + // this.currentFloor += this.currentDirection; + // this.state = 'moving'; + // this.checkStop(); + // } \ No newline at end of file diff --git a/elevator/main.js b/elevator/main.js index c577018..c4c37b1 100644 --- a/elevator/main.js +++ b/elevator/main.js @@ -20,11 +20,12 @@ elevator.move(); const question = () => { if(elevator.quit) { - if(elevator.passengerQueue.length) { + if(elevator.passengerQueue.length || elevator.requestMap.size) { rl.question('No more outside requests at this time. Please input which floor is your destination', (answer) => { - elevator.selectFloor(answer); + elevator.selectFloor(Number(answer)); + question() }) - question() + } else { rl.close(); } @@ -36,13 +37,10 @@ const question = () => { } else if (answer.at(-1).toLowerCase() === 'd') { createRequest(answer.slice(0,-1), -1); } else if(answer === 'quit') { - console.log('quitting...'); elevator.stopProcess(); - rl.close(); - process.exit(); } else { if(elevator.passengerQueue.length) { - elevator.selectFloor(answer); + elevator.selectFloor(Number(answer)); } } @@ -51,7 +49,7 @@ const question = () => { const createRequest = (floor, direction) => { - const req = new Request(floor, direction, 0); + const req = new Request(Number(floor), direction, 0); elevator.request(req); } diff --git a/elevator/request.js b/elevator/request.js index 49cbac9..de34ae4 100644 --- a/elevator/request.js +++ b/elevator/request.js @@ -11,4 +11,11 @@ class Request { } } -module.exports = {Request}; \ No newline at end of file +module.exports = {Request}; + + + + + + + From 3d9b5d5552cbf7350b3812240b85b221d18ccfe7 Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Sun, 26 Mar 2023 21:15:24 -0700 Subject: [PATCH 05/22] Finished base functionality with better movement algorithm --- elevator/elevator.js | 143 +++++++++++++++++++------------------------ elevator/main.js | 2 +- 2 files changed, 63 insertions(+), 82 deletions(-) diff --git a/elevator/elevator.js b/elevator/elevator.js index 076a818..28b4839 100644 --- a/elevator/elevator.js +++ b/elevator/elevator.js @@ -1,4 +1,5 @@ // to write to new files for output +const { ifError } = require('assert'); const fs = require('fs'); // to add EOL character to file output @@ -18,7 +19,6 @@ class Elevator { this.passengerCount = 0; this.currentDestination = -1; this.departMap = new Map(); - this.requestObj = {}; this.travelInterval = 1500; this.stopInterval = 500; @@ -29,48 +29,45 @@ class Elevator { this.off = []; } - - /* ****** problems with move function - elevator takes 3s to move from floor to floor - - we need to check who is getting on / off -> then after we do -> we need to either tell the elevator to stop at next floor or continue to the next - when we get to the next floor -> if we are stopped -> people get on or off -> we then decide next direction / destination - if we get to next floor and don't stop -> check next floor -> wait 3s to get there -> repeat again - - the problem with the check destination thing is that we are checking destination before people have gotten on the elevator and the array in reqobj has been deleted - so it checks the destination and just moves in the opposite direction even though there isn't really any need to stop ? - - probably can circumvent this by not checking the current req floor array - - */ - - - // still need to log here; move() { this.move = this.move.bind(this); - output('Current Floor: ' + this.currentFloor); - const changedDirection = this.decideDirection(); + output('Current Dest: ' + this.currentDestination); + output('Current Dir: ' + this.currentDirection); + this.decideDirection(); + this.decideDestination(); - if(this.currentDestination === -1) { - setTimeout(this.move, this.stopInterval); + if(this.state === 'stopped' && this.currentDestination === -1 && this.requestObj[this.currentFloor]) { + if(this.requestObj[this.currentFloor][1].length) { // default to up if there is a decision between the two + this.currentDirection = 1; + } else if(this.requestObj[this.currentFloor][-1].length) { + this.currentDirection = -1; + } + this.checkOn(); + this.stop(); + return; + } else if(this.on.length || this.off.length) { + output('we got on'); + this.stop(); return; } - this.currentFloor += this.currentDirection; - - const gettingOn = this.checkOn(); - output(gettingOn); - const gettingOff = this.checkOff(); + - if(gettingOn.length || gettingOff.length) { - this.state = 'stopped'; - this.stop(gettingOn, gettingOff); + if(this.currentDestination === -1) { + setTimeout(this.move, this.stopInterval); return; } + + this.currentFloor += this.currentDirection; + this.state = 'moving'; + this.checkOn(); + this.checkOff(); + this.decideDestination(); + setTimeout(this.move, this.travelInterval); } @@ -84,7 +81,7 @@ class Elevator { } else if(this.currentDestination === this.currentFloor) { // if there are no requests going in the same direction as we were just traveling at target floor - if(!this.requestObj[this.currentFloor][this.currentDirection].length) { + if(this.requestObj[this.currentFloor] && !this.requestObj[this.currentFloor][this.currentDirection].length) { this.currentDirection = this.currentDirection === 1 ? -1 : 1; } } @@ -104,59 +101,66 @@ class Elevator { } if(this.currentDirection === 1) { - this.currentDestination = keys.at(-1); + this.currentDestination = Number(keys.at(-1)); } else if(this.currentDestination === -1) { - this.currentDestination = keys[0]; + this.currentDestination = Number(keys[0]); } - } + if(this.currentFloor < this.currentDestination) { + this.currentDirection = 1; + } else if(this.currentFloor > this.currentDestination) { + this.currentDirection = -1; + } - stop(gettingOn, gettingOff) { + } + stop() { + + this.state = 'stopped'; - if(gettingOff.length) { - output(JSON.stringify(gettingOff) + 'all got off ' + this.currentFloor); + if(this.off.length) { + output(JSON.stringify(this.off) + 'all got off ' + this.currentFloor); output('passenger off count : ' + this.passengerCount); } - if(gettingOn.length) { - this.passengerQueue.push(...gettingOn); - output(JSON.stringify(gettingOff) + ' all got on ' + this.currentFloor) + if(this.on.length) { + this.passengerQueue.push(...this.on); + output(JSON.stringify(this.on) + ' all got on ' + this.currentFloor) } + this.off = []; + this.on = []; this.move = this.move.bind(this); setTimeout(this.move, this.stopInterval); } checkOff() { - const gettingOff = []; - // const nextFloor = this.currentFloor + this.currentDirection; - if(this.departMap.get(this.currentFloor) !== undefined) { - gettingOff.push(...this.departMap.get(this.currentFloor)); - this.passengerCount += gettingOff.length; - this.departMap.delete(nextFloor); + if(this.departMap.get(this.currentFloor) !== undefined) { + this.off.push(...this.departMap.get(this.currentFloor)); + this.passengerCount -= this.off.length; + this.departMap.delete(this.currentFloor); } - return gettingOff; } checkOn() { - const gettingOn = []; - // const nextFloor = this.currentFloor + this.currentDirection; - + if(this.requestObj[this.currentFloor] !== undefined) { - gettingOn.push(...this.requestObj[this.currentFloor][this.currentDirection]) + if(this.currentFloor === this.currentDestination) { + this.decideDirection(); + } + + this.on.push(...this.requestObj[this.currentFloor][this.currentDirection]) + this.passengerCount += this.requestObj[this.currentFloor][this.currentDirection].length; this.requestObj[this.currentFloor][this.currentDirection] = []; - - if(!this.requestObj[this.currentFloor][this.currentDirection * -1].length) { + if(!this.requestObj[this.currentFloor][this.currentDirection * -1].length && !this.requestObj[this.currentFloor][this.currentDirection].length) { delete this.requestObj[this.currentFloor]; } } - - return gettingOn; } + selectFloor(floor) { const weight = this.passengerQueue.shift(); if(this.departMap.get(floor) === undefined) { @@ -169,6 +173,7 @@ class Elevator { request(request) { + const {currentFloor, direction, weight} = request; if(this.requestObj[currentFloor] === undefined) { this.requestObj[currentFloor] = { @@ -179,6 +184,8 @@ class Elevator { this.requestObj[currentFloor][direction].push(weight); + // if elevator has no current destination -> set request currentlFloor to currentDestination + // set currentDirection in right direction as well if(this.currentDestination === -1) { this.currentDestination = currentFloor; if(currentFloor < this.currentDestination) { @@ -208,29 +215,3 @@ module.exports = {Elevator}; -const obj = {}; - -// console.log(obj.keys()) -console.log(Object.keys(obj)); -// console.log(obj.keys.length) - - - // move() { - - // output('Current floor: ' + this.currentFloor); - - // if(this.quit && !this.requestMap.size && !this.departMap.size && !this.passengerQueue.length) { - // output('we are done'); - // process.exit(); - // } - - // if(this.currentDirection === 1 && this.currentFloor === this.floors - 1) { - // this.currentDirection = -1; - // } else if(this.currentDirection === -1 && this.currentFloor === 0) { - // this.currentDirection = 1; - // } - - // this.currentFloor += this.currentDirection; - // this.state = 'moving'; - // this.checkStop(); - // } \ No newline at end of file diff --git a/elevator/main.js b/elevator/main.js index c4c37b1..e12267a 100644 --- a/elevator/main.js +++ b/elevator/main.js @@ -14,7 +14,7 @@ const rl = readline.createInterface({ }); -const elevator = new Elevator(5); +const elevator = new Elevator(15); elevator.move(); const question = () => { From 4456d3adf4b50ecbc54738f38e43b89ce86d5fa1 Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Sun, 26 Mar 2023 23:41:43 -0700 Subject: [PATCH 06/22] Finished functionality without weight. Cleaned up to be more readable. Refactored destination search to be more efficient. --- elevator/elevator.js | 117 +++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 78 deletions(-) diff --git a/elevator/elevator.js b/elevator/elevator.js index 28b4839..2be739e 100644 --- a/elevator/elevator.js +++ b/elevator/elevator.js @@ -1,11 +1,10 @@ // to write to new files for output -const { ifError } = require('assert'); const fs = require('fs'); // to add EOL character to file output const os = require('os'); - +// to make output easier const output = txt => { fs.appendFileSync('output.txt', txt + os.EOL); } @@ -24,7 +23,6 @@ class Elevator { this.stopInterval = 500; this.quit = false; this.passengerQueue = []; - this.on = []; this.off = []; } @@ -33,66 +31,37 @@ class Elevator { move() { this.move = this.move.bind(this); output('Current Floor: ' + this.currentFloor); - output('Current Dest: ' + this.currentDestination); - output('Current Dir: ' + this.currentDirection); - this.decideDirection(); - this.decideDestination(); + + if(this.currentFloor === 0) this.currentDirection = 1; + else if(this.currentFloor === this.floors) this.currentDirection = -1; if(this.state === 'stopped' && this.currentDestination === -1 && this.requestObj[this.currentFloor]) { - if(this.requestObj[this.currentFloor][1].length) { // default to up if there is a decision between the two - this.currentDirection = 1; - } else if(this.requestObj[this.currentFloor][-1].length) { - this.currentDirection = -1; - } this.checkOn(); - this.stop(); - return; - } else if(this.on.length || this.off.length) { - output('we got on'); - this.stop(); + } else if(this.currentDestination === -1) { + setTimeout(this.move, this.stopInterval); return; + } else if(this.currentDestination === this.currentFloor) { + this.setDestinationDecision(); } - - - - if(this.currentDestination === -1) { - setTimeout(this.move, this.stopInterval); + + if(this.on.length || this.off.length) { + output('we got on / off') + this.stop(); return; } - - this.currentFloor += this.currentDirection; this.state = 'moving'; this.checkOn(); this.checkOff(); - this.decideDestination(); setTimeout(this.move, this.travelInterval); } - - decideDirection() { - - // we must change direction here because we are at the top or bottom floor - if(this.currentFloor === 0) { - this.currentDirection = 1; - } else if(this.currentFloor === this.floors) { - this.currentDirection = -1; - } else if(this.currentDestination === this.currentFloor) { - - // if there are no requests going in the same direction as we were just traveling at target floor - if(this.requestObj[this.currentFloor] && !this.requestObj[this.currentFloor][this.currentDirection].length) { - this.currentDirection = this.currentDirection === 1 ? -1 : 1; - } - } - } - // decides destination when we have reached current destination - // we also may need to keep track if there have been any requests made in the wrong direction? - decideDestination() { + // if elevator is empty and there are still unserved requests -> elevator decides where to go here + setDestinationDecision() { const keys = Object.keys(this.requestObj); keys.push(...Array.from(this.departMap.keys())); - keys.sort((a,b) => a-b); // if there are no requests to serve => do nothing; if(!keys.length) { @@ -101,16 +70,13 @@ class Elevator { } if(this.currentDirection === 1) { - this.currentDestination = Number(keys.at(-1)); - } else if(this.currentDestination === -1) { - this.currentDestination = Number(keys[0]); + this.currentDestination = Number(Math.max(...keys)); + } else if(this.currentDirection === -1) { + this.currentDestination = Number(Math.min(...keys)); } - if(this.currentFloor < this.currentDestination) { - this.currentDirection = 1; - } else if(this.currentFloor > this.currentDestination) { - this.currentDirection = -1; - } + + this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1; } @@ -120,7 +86,6 @@ class Elevator { if(this.off.length) { output(JSON.stringify(this.off) + 'all got off ' + this.currentFloor); - output('passenger off count : ' + this.passengerCount); } if(this.on.length) { @@ -146,15 +111,16 @@ class Elevator { checkOn() { if(this.requestObj[this.currentFloor] !== undefined) { - if(this.currentFloor === this.currentDestination) { - this.decideDirection(); + if(this.currentFloor === this.currentDestination && !this.requestObj[this.currentFloor][this.currentDirection].length) { + this.currentDirection = this.currentDirection === 1 ? -1 : 1; } this.on.push(...this.requestObj[this.currentFloor][this.currentDirection]) this.passengerCount += this.requestObj[this.currentFloor][this.currentDirection].length; this.requestObj[this.currentFloor][this.currentDirection] = []; - if(!this.requestObj[this.currentFloor][this.currentDirection * -1].length && !this.requestObj[this.currentFloor][this.currentDirection].length) { - delete this.requestObj[this.currentFloor]; + + if(!this.requestObj[this.currentFloor][1].length && !this.requestObj[this.currentFloor][-1].length) { + delete this.requestObj[this.currentFloor]; } } @@ -168,7 +134,21 @@ class Elevator { } this.departMap.get(floor).push(weight); + this.setDestinationExternal(floor); + + } + + // if there is an external request where our currentDestination should change + setDestinationExternal(floor) { + if(this.currentDestination === -1) { + this.currentDestination = floor; + this.currentDirection = floor > this.currentFloor ? 1 : -1; + } else if(this.currentDirection === 1) { + if(floor > this.currentDestination) this.currentDestination = floor; + } else if(this.currentDirection === -1) { + if(floor < this.currentDestination) this.currentDestination = floor; + } } @@ -183,25 +163,8 @@ class Elevator { } this.requestObj[currentFloor][direction].push(weight); - - // if elevator has no current destination -> set request currentlFloor to currentDestination - // set currentDirection in right direction as well - if(this.currentDestination === -1) { - this.currentDestination = currentFloor; - if(currentFloor < this.currentDestination) { - this.currentDirection = 1; - } else if(currentFloor > this.currentDestination) { - this.currentDirection = -1; - } - return; - } - // change current destination if new floor request is further up or down in correct direction as elevator is currently traveling - if(this.currentDirection === 1) { - if(currentFloor > this.currentDestination) this.currentDestination = currentFloor; - } else if(this.currentDirection === -1) { - if(currentFloor < this.currentDestination) this.currentDestination = currentFloor; - } + this.setDestinationExternal(currentFloor); } @@ -213,5 +176,3 @@ class Elevator { module.exports = {Elevator}; - - From 2dcd9058ea9c9efbae7481d904f7948806543657 Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Sun, 26 Mar 2023 23:59:41 -0700 Subject: [PATCH 07/22] Added quit functionality back to program --- elevator/elevator.js | 17 ++++++++++++++++- elevator/main.js | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/elevator/elevator.js b/elevator/elevator.js index 2be739e..30f2dc0 100644 --- a/elevator/elevator.js +++ b/elevator/elevator.js @@ -29,9 +29,15 @@ class Elevator { move() { + + + this.move = this.move.bind(this); output('Current Floor: ' + this.currentFloor); - + + if(this.quit && this.endProcess()) { + process.exit(); + } if(this.currentFloor === 0) this.currentDirection = 1; else if(this.currentFloor === this.floors) this.currentDirection = -1; @@ -50,6 +56,8 @@ class Elevator { return; } + + this.currentFloor += this.currentDirection; this.state = 'moving'; this.checkOn(); @@ -104,6 +112,7 @@ class Elevator { if(this.departMap.get(this.currentFloor) !== undefined) { this.off.push(...this.departMap.get(this.currentFloor)); this.passengerCount -= this.off.length; + console.log(this.departMap.get(this.currentFloor)) this.departMap.delete(this.currentFloor); } } @@ -172,6 +181,12 @@ class Elevator { this.quit = true; } + endProcess() { + console.log(this.departMap.size); + console.log(!Object.keys(this.requestObj).length && !this.passengerQueue.length && !this.departMap.size) + return (!Object.keys(this.requestObj).length && !this.passengerQueue.length && !this.departMap.size) + } + } module.exports = {Elevator}; diff --git a/elevator/main.js b/elevator/main.js index e12267a..5e643c9 100644 --- a/elevator/main.js +++ b/elevator/main.js @@ -20,7 +20,7 @@ elevator.move(); const question = () => { if(elevator.quit) { - if(elevator.passengerQueue.length || elevator.requestMap.size) { + if(elevator.passengerQueue.length || Object.keys(elevator.requestObj)) { rl.question('No more outside requests at this time. Please input which floor is your destination', (answer) => { elevator.selectFloor(Number(answer)); question() From 226d9de7e84cc06a93f691d891306b139bf222fa Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Mon, 27 Mar 2023 16:58:06 -0700 Subject: [PATCH 08/22] Functionality finished with weight --- elevator/elevator.js | 194 +------------------------------------------ elevator/main.js | 6 +- 2 files changed, 4 insertions(+), 196 deletions(-) diff --git a/elevator/elevator.js b/elevator/elevator.js index 30f2dc0..3918c74 100644 --- a/elevator/elevator.js +++ b/elevator/elevator.js @@ -1,193 +1 @@ -// to write to new files for output -const fs = require('fs'); - -// to add EOL character to file output -const os = require('os'); - -// to make output easier -const output = txt => { - fs.appendFileSync('output.txt', txt + os.EOL); -} - -class Elevator { - constructor(floors) { - this.floors = floors; - this.state = 'stopped' - this.currentFloor = 0; - this.currentDirection = 1; - this.passengerCount = 0; - this.currentDestination = -1; - this.departMap = new Map(); - this.requestObj = {}; - this.travelInterval = 1500; - this.stopInterval = 500; - this.quit = false; - this.passengerQueue = []; - this.on = []; - this.off = []; - } - - - move() { - - - - this.move = this.move.bind(this); - output('Current Floor: ' + this.currentFloor); - - if(this.quit && this.endProcess()) { - process.exit(); - } - if(this.currentFloor === 0) this.currentDirection = 1; - else if(this.currentFloor === this.floors) this.currentDirection = -1; - - if(this.state === 'stopped' && this.currentDestination === -1 && this.requestObj[this.currentFloor]) { - this.checkOn(); - } else if(this.currentDestination === -1) { - setTimeout(this.move, this.stopInterval); - return; - } else if(this.currentDestination === this.currentFloor) { - this.setDestinationDecision(); - } - - if(this.on.length || this.off.length) { - output('we got on / off') - this.stop(); - return; - } - - - - this.currentFloor += this.currentDirection; - this.state = 'moving'; - this.checkOn(); - this.checkOff(); - - setTimeout(this.move, this.travelInterval); - } - - // if elevator is empty and there are still unserved requests -> elevator decides where to go here - setDestinationDecision() { - const keys = Object.keys(this.requestObj); - keys.push(...Array.from(this.departMap.keys())); - - // if there are no requests to serve => do nothing; - if(!keys.length) { - this.currentDestination = -1; - return; - } - - if(this.currentDirection === 1) { - this.currentDestination = Number(Math.max(...keys)); - } else if(this.currentDirection === -1) { - this.currentDestination = Number(Math.min(...keys)); - } - - - this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1; - - } - - stop() { - - this.state = 'stopped'; - - if(this.off.length) { - output(JSON.stringify(this.off) + 'all got off ' + this.currentFloor); - } - - if(this.on.length) { - this.passengerQueue.push(...this.on); - output(JSON.stringify(this.on) + ' all got on ' + this.currentFloor) - } - - this.off = []; - this.on = []; - this.move = this.move.bind(this); - setTimeout(this.move, this.stopInterval); - } - - checkOff() { - - if(this.departMap.get(this.currentFloor) !== undefined) { - this.off.push(...this.departMap.get(this.currentFloor)); - this.passengerCount -= this.off.length; - console.log(this.departMap.get(this.currentFloor)) - this.departMap.delete(this.currentFloor); - } - } - - checkOn() { - - if(this.requestObj[this.currentFloor] !== undefined) { - if(this.currentFloor === this.currentDestination && !this.requestObj[this.currentFloor][this.currentDirection].length) { - this.currentDirection = this.currentDirection === 1 ? -1 : 1; - } - - this.on.push(...this.requestObj[this.currentFloor][this.currentDirection]) - this.passengerCount += this.requestObj[this.currentFloor][this.currentDirection].length; - this.requestObj[this.currentFloor][this.currentDirection] = []; - - if(!this.requestObj[this.currentFloor][1].length && !this.requestObj[this.currentFloor][-1].length) { - delete this.requestObj[this.currentFloor]; - } - - } - } - - - selectFloor(floor) { - const weight = this.passengerQueue.shift(); - if(this.departMap.get(floor) === undefined) { - this.departMap.set(floor, []); - } - - this.departMap.get(floor).push(weight); - this.setDestinationExternal(floor); - - } - - - // if there is an external request where our currentDestination should change - setDestinationExternal(floor) { - if(this.currentDestination === -1) { - this.currentDestination = floor; - this.currentDirection = floor > this.currentFloor ? 1 : -1; - } else if(this.currentDirection === 1) { - if(floor > this.currentDestination) this.currentDestination = floor; - } else if(this.currentDirection === -1) { - if(floor < this.currentDestination) this.currentDestination = floor; - } - } - - - request(request) { - - const {currentFloor, direction, weight} = request; - if(this.requestObj[currentFloor] === undefined) { - this.requestObj[currentFloor] = { - 1: [], - '-1': [] - } - } - - this.requestObj[currentFloor][direction].push(weight); - - this.setDestinationExternal(currentFloor); - - } - - stopProcess() { - this.quit = true; - } - - endProcess() { - console.log(this.departMap.size); - console.log(!Object.keys(this.requestObj).length && !this.passengerQueue.length && !this.departMap.size) - return (!Object.keys(this.requestObj).length && !this.passengerQueue.length && !this.departMap.size) - } - -} - -module.exports = {Elevator}; - +"use strict"; diff --git a/elevator/main.js b/elevator/main.js index 5e643c9..4398eec 100644 --- a/elevator/main.js +++ b/elevator/main.js @@ -39,7 +39,7 @@ const question = () => { } else if(answer === 'quit') { elevator.stopProcess(); } else { - if(elevator.passengerQueue.length) { + if(elevator.passengerRequestQueue.length) { elevator.selectFloor(Number(answer)); } @@ -47,9 +47,9 @@ const question = () => { question()}); } - +// defaulting to weight of 25 const createRequest = (floor, direction) => { - const req = new Request(Number(floor), direction, 0); + const req = new Request(Number(floor), direction, 25); elevator.request(req); } From f09ad9356f9334ec9321a0bbfe92814ccafe2e01 Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Mon, 27 Mar 2023 16:59:22 -0700 Subject: [PATCH 09/22] Re committing finished weight functionality --- elevator/elevator.js | 243 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 242 insertions(+), 1 deletion(-) diff --git a/elevator/elevator.js b/elevator/elevator.js index 3918c74..c5b2176 100644 --- a/elevator/elevator.js +++ b/elevator/elevator.js @@ -1 +1,242 @@ -"use strict"; +// to write to new files for output +const fs = require('fs'); + +// to add EOL character to file output +const os = require('os'); + +// to make output easier +const output = txt => { + fs.appendFileSync('output.txt', txt + os.EOL); +} + +// internal request : buttons pressed from inside the elevator by passengers +// external requets : buttons pressed on floor N going U or D + +const sum = arr => { + let sum = 0; + sum = arr.reduce((a,b) => a + b); + return sum; +} + +class Elevator { + constructor(floors) { + this.floors = floors; + this.state = 'stopped' + this.currentFloor = 0; + this.currentDirection = 1; + this.currentDestination = -1; + this.departureRequestMap = new Map(); + this.externalRequestObject = {}; + this.travelInterval = 1500; + this.stopInterval = 500; + this.quit = false; + this.passengerQueue = []; + this.boardingPassengers = []; + this.departingPassengers = []; + this.currentWeight = 0; + this.weightLimit = 50; + } + + + move() { + + this.move = this.move.bind(this); + output('Current Floor: ' + this.currentFloor); + + if(this.quit && this.endProcess()) { + process.exit(); + } + + // check if elevator is inside the correct boundary + if(this.currentFloor === 0) this.currentDirection = 1; + else if(this.currentFloor === this.floors) this.currentDirection = -1; + + + // if elevator is not moving and someone requests same floor to get on + if(this.state === 'stopped' && this.currentDestination === -1 && this.externalRequestObject[this.currentFloor]) { + this.checkOn(); + // if elevator is not moving and has no requests - wait 1s and check for new reqeusts + } else if(this.currentDestination === -1) { + setTimeout(this.move, this.stopInterval); + return; + // if we have reached the destination - check for new destination based on unserved requests + } else if(this.currentDestination === this.currentFloor) { + this.setDestinationDecision(); + } + + // check if anyone is getting on or off at current floor + if(this.boardingPassengers.length || this.departingPassengers.length) { + output('we got on / off') + this.stop(); + return; + } + + // if at or above weight limit : need to reset destination to only internal requests + if(this.currentWeight >= this.weightLimit) this.setDestinationDecision(); + + if(this.currentDestination === -1) { + setTimeout(this.move, this.stopInterval); + return; + } + + this.currentFloor += this.currentDirection; + this.state = 'moving'; + this.checkOff(); + this.checkOn(); + + + setTimeout(this.move, this.travelInterval); + } + + // if elevator is empty and there are still unserved requests -> elevator decides where to go here + // picks furthest away floor in opposite direction - either external floor request or internal elevator request + setDestinationDecision() { + + const keys = [...Array.from(this.departureRequestMap.keys())]; + + //if we are at or above the weight limit don't consider external requests + if(this.currentWeight < this.weightLimit) keys.push(...Object.keys(this.externalRequestObject)); + + // if there are no requests to serve => do nothing; + if(!keys.length) { + this.currentDestination = -1; + return; + } + + if(this.currentDirection === 1) { + this.currentDestination = Number(Math.max(...keys)); + } else if(this.currentDirection === -1) { + this.currentDestination = Number(Math.min(...keys)); + } + + + this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1; + + } + + // stops elevator and boards / deboards passengers depending on their request + stop() { + + this.state = 'stopped'; + + if(this.departingPassengers.length) { + output(JSON.stringify(this.departingPassengers) + 'all got off ' + this.currentFloor); + } + + if(this.boardingPassengers.length) { + this.passengerRequestQueue.push(...this.boardingPassengers); + output(JSON.stringify(this.boardingPassengers) + ' all got on ' + this.currentFloor) + } + output('current weight' + this.currentWeight); + + this.departingPassengers = []; + this.boardingPassengers = []; + this.move = this.move.bind(this); + setTimeout(this.move, this.stopInterval); + } + + // check who is getting off the elevator while it is in transit from floor n to floor n +/- 1 + // decrements weight of passengers getting off + checkOff() { + + if(this.departureRequestMap.get(this.currentFloor) !== undefined) { + this.departingPassengers.push(...this.departureRequestMap.get(this.currentFloor)); + + this.currentWeight -= sum(this.departingPassengers); + + this.departureRequestMap.delete(this.currentFloor); + } + } + + // checks who is getting on based on direction elevator is traveling and currentWeight of elevator + checkOn() { + + if(this.externalRequestObject[this.currentFloor] !== undefined) { + // if elevator has reached destination floor it needs to change direction if the request is in the opposite direction + if(this.currentFloor === this.currentDestination && !this.externalRequestObject[this.currentFloor][this.currentDirection].length) { + this.currentDirection = this.currentDirection === 1 ? -1 : 1; + } + + const boardingArr = this.externalRequestObject[this.currentFloor][this.currentDirection]; + for(let i = boardingArr.length - 1; i >= 0; i--) { + let currentBoarder = boardingArr[i]; + if(currentBoarder + this.currentWeight <= this.weightLimit) { + this.boardingPassengers.push(currentBoarder); + boardingArr.pop(); + this.currentWeight += currentBoarder; + + } else { + console.log('over weight limit ' + this.currentWeight) + } + } + if(!boardingArr.length) this.externalRequestObject[this.currentFloor][this.currentDirection] = []; + + + // clears request Obj of current floor if there aren't any more requests on this floor + if(!this.externalRequestObject[this.currentFloor][1].length && !this.externalRequestObject[this.currentFloor][-1].length) { + delete this.externalRequestObject[this.currentFloor]; + } + + } + } + + // internal floor request sets their destination in departMap + selectFloor(floor) { + const weight = this.passengerRequestQueue.shift(); + if(this.departureRequestMap.get(floor) === undefined) { + this.departureRequestMap.set(floor, []); + } + + this.departureRequestMap.get(floor).push(weight); + this.setDestinationExternal(floor); + + } + + + // if there is an external request where our currentDestination should change + setDestinationExternal(floor) { + + if(this.currentDestination === -1) { + this.currentDestination = floor; + this.currentDirection = floor > this.currentFloor ? 1 : -1; + } else if(this.currentDirection === 1) { + if(floor > this.currentDestination) this.currentDestination = floor; + } else if(this.currentDirection === -1) { + if(floor < this.currentDestination) this.currentDestination = floor; + } + } + + + // handles external request + request(request) { + + const {currentFloor, direction, weight} = request; + if(this.externalRequestObject[currentFloor] === undefined) { + this.externalRequestObject[currentFloor] = { + 1: [], + '-1': [] + } + } + + this.externalRequestObject[currentFloor][direction].push(weight); + + // if the destination needs to be changed based on current direction it will be set here if weight allows + if(this.currentWeight < this.weightLimit) this.setDestinationExternal(currentFloor); + + + } + + // when quit is typed into console + stopProcess() { + this.quit = true; + } + + // will end when all requests have been served and all passengers are off the elevator + endProcess() { + return (!Object.keys(this.externalRequestObject).length && !this.passengerRequestQueue.length && !this.departureRequestMap.size) + } + +} + +module.exports = {Elevator}; + From 681067c721780a7b6f894f6722bdc331521b6da0 Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Mon, 27 Mar 2023 20:30:11 -0700 Subject: [PATCH 10/22] Migrated to TypeScript --- elevator/elevator.ts | 267 ++++++++++++++++++++++++++++++++++++++++++ elevator/functions.ts | 7 ++ elevator/main.ts | 59 ++++++++++ elevator/request.ts | 20 ++++ elevator/types.ts | 34 ++++++ package.json | 11 ++ tsconfig.json | 109 +++++++++++++++++ 7 files changed, 507 insertions(+) create mode 100644 elevator/elevator.ts create mode 100644 elevator/functions.ts create mode 100644 elevator/main.ts create mode 100644 elevator/request.ts create mode 100644 elevator/types.ts create mode 100644 package.json create mode 100644 tsconfig.json diff --git a/elevator/elevator.ts b/elevator/elevator.ts new file mode 100644 index 0000000..107d435 --- /dev/null +++ b/elevator/elevator.ts @@ -0,0 +1,267 @@ +// to write to new files for output +import * as fs from 'fs' + +// to add EOL character to file output +import * as os from 'os'; + +import {ElevatorRequest, ExternalRequestObject, DirectionObject} from './types.js'; + +import {output} from './functions.js' + + +// internal request : buttons pressed from inside the elevator by passengers +// external requets : buttons pressed on floor N going U or D + +const sum = (arr: number[]) => { + let sum = 0; + sum = arr.reduce((a,b) => a + b); + return sum; +} + + + + + +class Elevator { + + floors: number; + state: 'stopped' | 'moving'; + currentFloor: number; + currentDirection: 1 | -1; + currentDestination: number; + departureRequestMap: Map; + externalRequestObject: ExternalRequestObject; + travelInterval: number; + stopInterval: number; + quit: boolean; + passengerRequestQueue: number[]; + boardingPassengers: number[]; + departingPassengers: number[]; + currentWeight: number; + weightLimit: number; + + constructor(floors: number) { + this.floors = floors; + this.state = 'stopped' + this.currentFloor = 0; + this.currentDirection = 1; + this.currentDestination = -1; + this.departureRequestMap = new Map(); + this.externalRequestObject = {}; + this.travelInterval = 1500; + this.stopInterval = 500; + this.quit = false; + this.passengerRequestQueue = []; + this.boardingPassengers = []; + this.departingPassengers = []; + this.currentWeight = 0; + this.weightLimit = 50; + } + + + move() { + + this.move = this.move.bind(this); + output('Current Floor: ' + this.currentFloor); + + if(this.quit && this.endProcess()) { + process.exit(); + } + + // check if elevator is inside the correct boundary + if(this.currentFloor === 0) this.currentDirection = 1; + else if(this.currentFloor === this.floors) this.currentDirection = -1; + + + // if elevator is not moving and someone requests same floor to get on + if(this.state === 'stopped' && this.currentDestination === -1 && this.externalRequestObject[this.currentFloor]) { + this.checkOn(); + // if elevator is not moving and has no requests - wait 1s and check for new reqeusts + } else if(this.currentDestination === -1) { + setTimeout(this.move, this.stopInterval); + return; + // if we have reached the destination - check for new destination based on unserved requests + } else if(this.currentDestination === this.currentFloor) { + this.setDestinationDecision(); + } + + // check if anyone is getting on or off at current floor + if(this.boardingPassengers.length || this.departingPassengers.length) { + output('we got on / off') + this.stop(); + return; + } + + // if at or above weight limit : need to reset destination to only internal requests + if(this.currentWeight >= this.weightLimit) { + this.setDestinationDecision(); + } + + if(this.currentDestination === -1) { + setTimeout(this.move, this.stopInterval); + return; + } + + this.currentFloor += this.currentDirection; + this.state = 'moving'; + this.checkOff(); + this.checkOn(); + + + setTimeout(this.move, this.travelInterval); + } + + // if elevator is empty and there are still unserved requests -> elevator decides where to go here + // picks furthest away floor in opposite direction - either external floor request or internal elevator request + setDestinationDecision() { + + const keys = this.departureRequestMap.size ? [Number(...Array.from(this.departureRequestMap.keys()))] : []; + //if we are at or above the weight limit don't consider external requests + if(this.currentWeight < this.weightLimit) { + if(Object.keys(this.externalRequestObject).length) keys.push(Number(...Object.keys(this.externalRequestObject))); + } + + // if there are no requests to serve => do nothing; + if(!keys.length) { + this.currentDestination = -1; + return; + } + + if(this.currentDirection === 1) { + this.currentDestination = Number(Math.max(...keys)); + } else if(this.currentDirection === -1) { + this.currentDestination = Number(Math.min(...keys)); + } + + + this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1; + + } + + // stops elevator and boards / deboards passengers depending on their request + stop() { + + this.state = 'stopped'; + + if(this.departingPassengers.length) { + output(JSON.stringify(this.departingPassengers) + 'all got off ' + this.currentFloor); + } + + if(this.boardingPassengers.length) { + this.passengerRequestQueue.push(...this.boardingPassengers); + output(JSON.stringify(this.boardingPassengers) + ' all got on ' + this.currentFloor) + } + output('current weight' + this.currentWeight); + + this.departingPassengers = []; + this.boardingPassengers = []; + this.move = this.move.bind(this); + setTimeout(this.move, this.stopInterval); + } + + // check who is getting off the elevator while it is in transit from floor n to floor n +/- 1 + // decrements weight of passengers getting off + checkOff() { + + if(this.departureRequestMap.get(this.currentFloor) !== undefined) { + this.departingPassengers.push(...this.departureRequestMap.get(this.currentFloor) ?? []); + + this.currentWeight -= sum(this.departingPassengers); + + this.departureRequestMap.delete(this.currentFloor); + + } + } + + // checks who is getting on based on direction elevator is traveling and currentWeight of elevator + checkOn() { + + if(this.externalRequestObject[this.currentFloor] !== undefined) { + // if elevator has reached destination floor it needs to change direction if the request is in the opposite direction + if(this.currentFloor === this.currentDestination && !this.externalRequestObject[this.currentFloor][this.currentDirection].length) { + this.currentDirection = this.currentDirection === 1 ? -1 : 1; + } + + const boardingArr = this.externalRequestObject[this.currentFloor][this.currentDirection]; + for(let i = boardingArr.length - 1; i >= 0; i--) { + let currentBoarder = boardingArr[i]; + if(currentBoarder + this.currentWeight <= this.weightLimit) { + this.boardingPassengers.push(currentBoarder); + boardingArr.pop(); + this.currentWeight += currentBoarder; + + } else { + console.log('over weight limit ' + this.currentWeight) + } + } + if(!boardingArr.length) this.externalRequestObject[this.currentFloor][this.currentDirection] = []; + + + // clears request Obj of current floor if there aren't any more requests on this floor + if(!this.externalRequestObject[this.currentFloor][1].length && !this.externalRequestObject[this.currentFloor][-1].length) { + delete this.externalRequestObject[this.currentFloor]; + } + + } + } + + // internal floor request sets their destination in departureRequestMap + selectFloor(floor: number) { + const weight = this.passengerRequestQueue.shift()!; + if(this.departureRequestMap.get(floor) === undefined) { + this.departureRequestMap.set(floor, []); + } + + this.departureRequestMap.get(floor)!.push(weight); + this.setDestinationExternal(floor); + + } + + + // if there is an external request where our currentDestination should change + setDestinationExternal(floor: number) { + + if(this.currentDestination === -1) { + this.currentDestination = floor; + this.currentDirection = floor > this.currentFloor ? 1 : -1; + } else if(this.currentDirection === 1) { + if(floor > this.currentDestination) this.currentDestination = floor; + } else if(this.currentDirection === -1) { + if(floor < this.currentDestination) this.currentDestination = floor; + } + } + + + // handles external request + request(request: ElevatorRequest) { + + const {currentFloor, direction, weight} = request; + if(this.externalRequestObject[currentFloor] === undefined) { + this.externalRequestObject[currentFloor] = { + '1': [], + '-1': [] + } as DirectionObject; + } + + this.externalRequestObject[currentFloor][direction].push(weight); + + // if the destination needs to be changed based on current direction it will be set here if weight allows + if(this.currentWeight < this.weightLimit) this.setDestinationExternal(currentFloor); + + + } + + // when quit is typed into console + stopProcess() { + this.quit = true; + } + + // will end when all requests have been served and all passengers are off the elevator + endProcess() { + return (!Object.keys(this.externalRequestObject).length && !this.passengerRequestQueue.length && !this.departureRequestMap.size) + } + +} + +export default Elevator; + diff --git a/elevator/functions.ts b/elevator/functions.ts new file mode 100644 index 0000000..c7e8b7b --- /dev/null +++ b/elevator/functions.ts @@ -0,0 +1,7 @@ +import * as fs from 'fs'; +import * as os from 'os'; + + +export const output = (txt: string) => { + fs.appendFileSync('output.txt', txt + os.EOL); +} diff --git a/elevator/main.ts b/elevator/main.ts new file mode 100644 index 0000000..22a786e --- /dev/null +++ b/elevator/main.ts @@ -0,0 +1,59 @@ +import Elevator from './elevator.js'; +import ElevatorRequest from './request.js'; +import * as fs from 'fs'; +import * as readline from 'readline'; + + +// Create an interface for reading from the command line +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); + + +const elevator = new Elevator(15); +elevator.move(); + +const question = () => { + + if(elevator.quit) { + if(elevator.passengerRequestQueue.length || Object.keys(elevator.externalRequestObject)) { + rl.question('No more outside requests at this time. Please input which floor is your destination', (answer) => { + elevator.selectFloor(Number(answer)); + question() + }) + + } else { + rl.close(); + } + } + + rl.question('What floor are you on and which direction are you going, OR which floor do you want to request?', (answer) => { + if(!answer.length) question(); + if(answer.at(-1)!.toLowerCase() === 'u') { + createRequest(answer.slice(0,-1), 1); + } else if (answer.at(-1)!.toLowerCase() === 'd') { + createRequest(answer.slice(0,-1), -1); + } else if(answer === 'quit') { + elevator.stopProcess(); + } else { + if(elevator.passengerRequestQueue.length) { + elevator.selectFloor(Number(answer)); + } + + } + question()}); +} + +// defaulting to weight of 25 +const createRequest = (floor: string, direction: number) => { + const req = new ElevatorRequest(Number(floor), direction, 25); + elevator.request(req); +} + + +fs.writeFileSync('output.txt', ''); +question(); + + + diff --git a/elevator/request.ts b/elevator/request.ts new file mode 100644 index 0000000..283e8d9 --- /dev/null +++ b/elevator/request.ts @@ -0,0 +1,20 @@ +class ElevatorRequest { + currentFloor: number; + direction: number; + weight: number; + + constructor(currentFloor: number, direction: number, weight?:number) { + this.currentFloor = currentFloor; + this.direction = direction; + this.weight = weight !== undefined ? weight : 0; + } +} + +export default ElevatorRequest; + + + + + + + diff --git a/elevator/types.ts b/elevator/types.ts new file mode 100644 index 0000000..f75a5d4 --- /dev/null +++ b/elevator/types.ts @@ -0,0 +1,34 @@ + +export type Elevator = { + floors: number; + state: 'stopped' | 'moving'; + currentFloor: number; + currentDirection: 1 | -1; + currentDestination: number; + departureRequestMap: Map; + externalRequestObject: ExternalRequestObject; + travelInterval: number; + stopInterval: number; + quit: boolean; + passengerRequestQueue: number[]; + boardingPassengers: number[]; + departingPassengers: number[]; + currentWeight: number; + weightLimit: number; +} + +export type ExternalRequestObject = { + [key: number | string] : DirectionObject +} + +export type DirectionObject = { + '1': number[], + '-1': number[]; + [key: number]: number[]; +} + +export type ElevatorRequest = { + currentFloor: number; + direction: number; + weight: number; +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..1c37334 --- /dev/null +++ b/package.json @@ -0,0 +1,11 @@ +{ + "dependencies": { + "fs": "^0.0.1-security", + "os": "^0.1.2" + }, + "devDependencies": { + "@types/node": "^18.15.10", + "typescript": "^5.0.2" + }, + "type": "module" +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..685e6a0 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,109 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "ESnext", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./build", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} From 7aa94324798fd0e78859de7ceb2a6028f98819b8 Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Mon, 27 Mar 2023 20:42:15 -0700 Subject: [PATCH 11/22] Fixed quit functionality --- elevator/elevator.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/elevator/elevator.ts b/elevator/elevator.ts index 107d435..eaba97a 100644 --- a/elevator/elevator.ts +++ b/elevator/elevator.ts @@ -258,7 +258,10 @@ class Elevator { // will end when all requests have been served and all passengers are off the elevator endProcess() { - return (!Object.keys(this.externalRequestObject).length && !this.passengerRequestQueue.length && !this.departureRequestMap.size) + return (!Object.keys(this.externalRequestObject).length && + !this.passengerRequestQueue.length && + !this.departureRequestMap.size && !this.boardingPassengers.length + && this.departingPassengers.length) } } From cff60f19ec0461be5b7156c4516ccf2386f914fd Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Tue, 28 Mar 2023 01:55:57 -0700 Subject: [PATCH 12/22] Finished testing and readme --- build/elevator/elevator.js | 199 + build/elevator/functions.js | 10 + build/elevator/main.js | 50 + build/elevator/output.js | 18 + build/elevator/request.js | 8 + build/elevator/types.js | 1 + build/test/elevator.test.js | 138 + coverage/clover.xml | 94 + coverage/coverage-final.json | 2 + coverage/lcov-report/base.css | 224 + coverage/lcov-report/block-navigation.js | 87 + coverage/lcov-report/elevator.ts.html | 889 +++ coverage/lcov-report/favicon.png | Bin 0 -> 445 bytes coverage/lcov-report/index.html | 116 + coverage/lcov-report/prettify.css | 1 + coverage/lcov-report/prettify.js | 2 + coverage/lcov-report/sort-arrow-sprite.png | Bin 0 -> 138 bytes coverage/lcov-report/sorter.js | 196 + coverage/lcov.info | 159 + elevator/README.md | 34 +- elevator/README2.md | 12 + elevator/elevator.js | 242 - elevator/elevator.ts | 75 +- elevator/functions.ts | 6 + elevator/output.ts | 26 + elevator/request.js | 21 - jest.config.cjs | 17 + elevator/main.js => main.js | 0 output.txt | 8 + package-lock.json | 6272 ++++++++++++++++++++ package.json | 6 + test/elevator.test.ts | 188 + 32 files changed, 8789 insertions(+), 312 deletions(-) create mode 100644 build/elevator/elevator.js create mode 100644 build/elevator/functions.js create mode 100644 build/elevator/main.js create mode 100644 build/elevator/output.js create mode 100644 build/elevator/request.js create mode 100644 build/elevator/types.js create mode 100644 build/test/elevator.test.js create mode 100644 coverage/clover.xml create mode 100644 coverage/coverage-final.json create mode 100644 coverage/lcov-report/base.css create mode 100644 coverage/lcov-report/block-navigation.js create mode 100644 coverage/lcov-report/elevator.ts.html create mode 100644 coverage/lcov-report/favicon.png create mode 100644 coverage/lcov-report/index.html create mode 100644 coverage/lcov-report/prettify.css create mode 100644 coverage/lcov-report/prettify.js create mode 100644 coverage/lcov-report/sort-arrow-sprite.png create mode 100644 coverage/lcov-report/sorter.js create mode 100644 coverage/lcov.info create mode 100644 elevator/README2.md delete mode 100644 elevator/elevator.js create mode 100644 elevator/output.ts delete mode 100644 elevator/request.js create mode 100644 jest.config.cjs rename elevator/main.js => main.js (100%) create mode 100644 output.txt create mode 100644 package-lock.json create mode 100644 test/elevator.test.ts diff --git a/build/elevator/elevator.js b/build/elevator/elevator.js new file mode 100644 index 0000000..d707f59 --- /dev/null +++ b/build/elevator/elevator.js @@ -0,0 +1,199 @@ +import Output from './output.js'; +const sum = (arr) => { + let sum = 0; + sum = arr.reduce((a, b) => a + b); + return sum; +}; +// internal request : buttons pressed from inside the elevator by passengers +// external requets : buttons pressed on floor N going U or D +class Elevator { + constructor(floors) { + this.floors = floors; + this.state = 'stopped'; + this.currentFloor = 0; + this.currentDirection = 1; + this.currentDestination = -1; + this.travelInterval = 3000; + this.stopInterval = 1000; + this.quit = false; + this.currentWeight = 0; + this.weightLimit = 50; + this.departureRequestMap = new Map(); + this.externalRequestObject = {}; + this.passengerRequestQueue = []; + this.boardingPassengers = []; + this.departingPassengers = []; + this.output = new Output('output.txt'); + } + move() { + this.move = this.move.bind(this); + if (this.quit && this.endProcess()) { + process.exit(); + } + // check if elevator is inside the correct boundary + if (this.currentFloor === 0) + this.currentDirection = 1; + else if (this.currentFloor === this.floors) + this.currentDirection = -1; + // if elevator is not moving and someone requests same floor to get on + if (this.state === 'stopped' && (this.currentDestination === -1 || this.currentDestination === this.currentFloor) + && this.externalRequestObject[this.currentFloor]) { + this.checkOn(); + // if elevator is not moving and has no requests - wait 1s and check for new reqeusts + } + else if (this.currentDestination === -1) { + setTimeout(this.move, this.stopInterval); + return; + // if we have reached the destination - check for new destination based on unserved requests + } + else if (this.currentDestination === this.currentFloor) { + this.setDestinationDecision(); + } + // check if anyone is getting on or off at current floor + if (this.boardingPassengers.length || this.departingPassengers.length) { + this.output.output('Stopped on floor: ' + this.currentFloor); + this.stop(); + return; + } + // if at or above weight limit : need to reset destination to only internal requests + if (this.currentWeight >= this.weightLimit) { + this.setDestinationDecision(); + } + // if there is no current destination : wait interval to see if there is a new request + if (this.currentDestination === -1) { + setTimeout(this.move, this.stopInterval); + return; + } + this.output.output('Passing floor: ' + this.currentFloor); + // increment / decrement current floor and change state to moving : check if any board / deboard next floor + this.currentFloor += this.currentDirection; + this.state = 'moving'; + this.checkOff(); + this.checkOn(); + setTimeout(this.move, this.travelInterval); + } + // if elevator is empty and there are still unserved requests -> elevator decides where to go here + // picks furthest away floor in opposite direction - either external floor request or internal elevator request + setDestinationDecision() { + const keys = this.departureRequestMap.size ? [Number(...Array.from(this.departureRequestMap.keys()))] : []; + //if we are at or above the weight limit don't consider external requests + if (this.currentWeight < this.weightLimit) { + if (Object.keys(this.externalRequestObject).length) + keys.push(Number(...Object.keys(this.externalRequestObject))); + } + // if there are no requests to serve + if (!keys.length) { + this.currentDestination = -1; + return; + } + if (this.currentDirection === 1) { + this.currentDestination = Number(Math.max(...keys)); + } + else if (this.currentDirection === -1) { + this.currentDestination = Number(Math.min(...keys)); + } + this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1; + } + // stops elevator and boards / deboards passengers depending on their request + stop() { + this.state = 'stopped'; + if (this.departingPassengers.length) { + this.output.output(this.departingPassengers.length + ' passenger(s) got off '); + } + if (this.boardingPassengers.length) { + this.passengerRequestQueue.push(...this.boardingPassengers); + this.output.output((this.boardingPassengers.length + ' passenger(s) got on ')); + } + this.departingPassengers = []; + this.boardingPassengers = []; + this.move = this.move.bind(this); + setTimeout(this.move, this.stopInterval); + } + // check who is getting off the elevator while it is in transit from floor n to floor n +/- 1 + // decrements weight of passengers getting off + checkOff() { + var _a; + if (this.departureRequestMap.get(this.currentFloor) !== undefined) { + this.departingPassengers.push(...(_a = this.departureRequestMap.get(this.currentFloor)) !== null && _a !== void 0 ? _a : []); + this.currentWeight -= sum(this.departingPassengers); + this.departureRequestMap.delete(this.currentFloor); + } + } + // checks who is getting on based on direction elevator is traveling and currentWeight of elevator + checkOn() { + if (this.externalRequestObject[this.currentFloor] !== undefined) { + // if elevator has reached destination floor it needs to change direction if the request is in the opposite direction + if (this.currentFloor === this.currentDestination && + !this.externalRequestObject[this.currentFloor][this.currentDirection].length) { + this.currentDirection = this.currentDirection === 1 ? -1 : 1; + } + const boardingArr = this.externalRequestObject[this.currentFloor][this.currentDirection]; + for (let i = boardingArr.length - 1; i >= 0; i--) { + let currentBoarder = boardingArr[i]; + if (currentBoarder + this.currentWeight <= this.weightLimit) { + this.boardingPassengers.push(currentBoarder); + boardingArr.pop(); + this.currentWeight += currentBoarder; + } + } + if (!boardingArr.length) + this.externalRequestObject[this.currentFloor][this.currentDirection] = []; + // clears request Obj of current floor if there aren't any more requests on this floor + if (!this.externalRequestObject[this.currentFloor][1].length && !this.externalRequestObject[this.currentFloor][-1].length) { + delete this.externalRequestObject[this.currentFloor]; + } + } + } + // internal floor request sets their destination in departureRequestMap + selectFloor(floor) { + this.output.output('Floor ' + floor + ' requested internally'); + const weight = this.passengerRequestQueue.shift(); + if (this.departureRequestMap.get(floor) === undefined) { + this.departureRequestMap.set(floor, []); + } + this.departureRequestMap.get(floor).push(weight); + this.setDestinationExternal(floor); + } + // if there is an external request where our currentDestination should change + setDestinationExternal(floor) { + if (this.currentDestination === -1) { + this.currentDestination = floor; + this.currentDirection = floor > this.currentFloor ? 1 : -1; + } + else if (this.currentDirection === 1) { + if (floor > this.currentDestination) + this.currentDestination = floor; + } + else if (this.currentDirection === -1) { + if (floor < this.currentDestination) + this.currentDestination = floor; + } + } + // handles external request + request(request) { + const { currentFloor, direction, weight } = request; + if (this.externalRequestObject[currentFloor] === undefined) { + this.externalRequestObject[currentFloor] = { + '1': [], + '-1': [] + }; + } + this.output.output('Floor ' + currentFloor + ' requested externally'); + this.externalRequestObject[currentFloor][direction].push(weight); + // if the destination needs to be changed based on current direction it will be set here if weight allows + if (this.currentWeight < this.weightLimit) + this.setDestinationExternal(currentFloor); + } + // when quit is typed into console + stopProcess() { + this.quit = true; + } + // will end when all requests have been served and all passengers are off the elevator + endProcess() { + return (!Object.keys(this.externalRequestObject).length && + !this.passengerRequestQueue.length && + !this.departureRequestMap.size && !this.boardingPassengers.length + && !this.departingPassengers.length); + } +} +export default Elevator; diff --git a/build/elevator/functions.js b/build/elevator/functions.js new file mode 100644 index 0000000..2d9f343 --- /dev/null +++ b/build/elevator/functions.js @@ -0,0 +1,10 @@ +import * as fs from 'fs'; +import * as os from 'os'; +export const output = (txt) => { + fs.appendFileSync('output.txt', txt + os.EOL); +}; +export const sum = (arr) => { + let sum = 0; + sum = arr.reduce((a, b) => a + b); + return sum; +}; diff --git a/build/elevator/main.js b/build/elevator/main.js new file mode 100644 index 0000000..384319c --- /dev/null +++ b/build/elevator/main.js @@ -0,0 +1,50 @@ +import Elevator from './elevator.js'; +import ElevatorRequest from './request.js'; +import * as fs from 'fs'; +import * as readline from 'readline'; +// Create an interface for reading from the command line +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout +}); +const elevator = new Elevator(15); +elevator.move(); +const question = () => { + if (elevator.quit) { + if (elevator.passengerRequestQueue.length || Object.keys(elevator.externalRequestObject)) { + rl.question('No more outside requests at this time. Please input which floor is your destination', (answer) => { + elevator.selectFloor(Number(answer)); + question(); + }); + } + else { + rl.close(); + } + } + rl.question('What floor are you on and which direction are you going, OR which floor do you want to request?', (answer) => { + if (!answer.length) + question(); + if (answer.at(-1).toLowerCase() === 'u') { + createRequest(answer.slice(0, -1), 1); + } + else if (answer.at(-1).toLowerCase() === 'd') { + createRequest(answer.slice(0, -1), -1); + } + else if (answer === 'quit') { + elevator.stopProcess(); + } + else { + if (elevator.passengerRequestQueue.length) { + elevator.selectFloor(Number(answer)); + } + } + question(); + }); +}; +// defaulting to weight of 25 +const createRequest = (floor, direction) => { + const req = new ElevatorRequest(Number(floor), direction, 25); + elevator.request(req); +}; +fs.writeFileSync('output.txt', ''); +question(); diff --git a/build/elevator/output.js b/build/elevator/output.js new file mode 100644 index 0000000..cab12a1 --- /dev/null +++ b/build/elevator/output.js @@ -0,0 +1,18 @@ +// to write to new files for output +import * as fs from 'fs'; +// to add EOL character to file output +import * as os from 'os'; +class Output { + constructor(filename) { + this.outputFileName = filename; + } + output(txt) { + const time = new Date(); + const hours = time.getHours(); + const minutes = time.getMinutes(); + const seconds = time.getSeconds(); + const outputString = `${hours}:${minutes}:${seconds} - ${txt}`; + fs.appendFileSync(this.outputFileName, outputString + os.EOL); + } +} +export default Output; diff --git a/build/elevator/request.js b/build/elevator/request.js new file mode 100644 index 0000000..87ddb6b --- /dev/null +++ b/build/elevator/request.js @@ -0,0 +1,8 @@ +class ElevatorRequest { + constructor(currentFloor, direction, weight) { + this.currentFloor = currentFloor; + this.direction = direction; + this.weight = weight !== undefined ? weight : 0; + } +} +export default ElevatorRequest; diff --git a/build/elevator/types.js b/build/elevator/types.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/build/elevator/types.js @@ -0,0 +1 @@ +export {}; diff --git a/build/test/elevator.test.js b/build/test/elevator.test.js new file mode 100644 index 0000000..85d278d --- /dev/null +++ b/build/test/elevator.test.js @@ -0,0 +1,138 @@ +// Import the Elevator class from your implementation file +import Elevator from '../elevator/elevator'; +// import Elevator from '../build/elevator/elevator.js'; +jest.useFakeTimers(); +describe('Elevator.move', () => { + let elevator; + beforeEach(() => { + // Create a new Elevator instance before each test + elevator = new Elevator(10); + }); + afterEach(() => { + jest.clearAllTimers(); + }); + it('should move the elevator to the next floor when the current direction is 1 and current destination > current floor', () => { + elevator.currentFloor = 0; + elevator.currentDirection = 1; + elevator.currentDestination = 1; + elevator.externalRequestObject = {}; + elevator.move(); + expect(elevator.currentFloor).toEqual(1); + expect(elevator.state).toEqual('moving'); + expect(elevator.currentDestination).toEqual(1); + expect(elevator.currentDirection).toEqual(1); + expect(elevator.boardingPassengers).toEqual([]); + expect(elevator.departingPassengers).toEqual([]); + }); + it('should stop the elevator and board passengers when there are external requests on the next floor', () => { + elevator.currentFloor = 2; + elevator.currentDirection = 1; + elevator.currentDestination = 3; + elevator.externalRequestObject = { 3: { + '1': [25], + '-1': [] + } }; + elevator.move(); + expect(elevator.currentFloor).toEqual(3); + expect(elevator.state).toEqual('moving'); + expect(elevator.currentDestination).toEqual(3); + expect(elevator.currentDirection).toEqual(1); + expect(elevator.boardingPassengers.length).toEqual(1); + expect(elevator.departingPassengers).toEqual([]); + }); + it('should stop the elevator and deboard/board passengers when there are passengers with a request to get off on the current floor', () => { + elevator.currentFloor = 5; + elevator.currentDirection = 1; + elevator.currentDestination = 5; + elevator.externalRequestObject = {}; + elevator.boardingPassengers = [10, 10, 10]; + elevator.departingPassengers = [10]; + elevator.move(); + expect(elevator.currentFloor).toEqual(5); + expect(elevator.state).toEqual('stopped'); + expect(elevator.currentDestination).toEqual(-1); + expect(elevator.currentDirection).toEqual(1); + expect(elevator.boardingPassengers).toEqual([]); + expect(elevator.departingPassengers).toEqual([]); + expect(elevator.passengerRequestQueue.length).toEqual(3); + }); + it('should not stop at next floor if there is a request to board but we are at the weight limit', () => { + elevator.currentFloor = 4; + elevator.currentWeight = 50; + elevator.currentDirection = 1; + elevator.departureRequestMap.set(8, [10]); + elevator.currentDestination = 8; + elevator.externalRequestObject = { 5: { + '1': [25], + '-1': [] + } }; + elevator.move(); + expect(elevator.currentFloor).toEqual(5); + expect(elevator.state).toEqual('moving'); + expect(elevator.currentDestination).toEqual(8); + expect(elevator.currentDirection).toEqual(1); + expect(elevator.boardingPassengers).toEqual([]); + expect(elevator.departingPassengers).toEqual([]); + }); + it('should properly track weight going on and off', () => { + elevator.currentFloor = 4; + elevator.currentWeight = 50; + elevator.currentDirection = 1; + elevator.currentDestination = 5; + elevator.externalRequestObject = { 5: { '1': [10, 10, 10], '-1': [] } }; + elevator.departureRequestMap.set(5, [10]); + elevator.currentWeight = 20; + elevator.move(); + expect(elevator.currentFloor).toEqual(5); + expect(elevator.state).toEqual('moving'); + expect(elevator.currentWeight).toEqual(40); + }); + it('should not stop program if elevator.stop is true, it should finish requests and then stop', () => { + elevator.quit = true; + elevator.currentFloor = 4; + elevator.currentDirection = 1; + elevator.currentDestination = 5; + elevator.departureRequestMap.set(5, [10]); + elevator.move(); + expect(elevator.currentFloor).toEqual(5); + expect(elevator.state).toEqual('moving'); + }); +}); +describe('Elevator.setDestinationExternal', () => { + let elevator; + beforeEach(() => { + // Create a new Elevator instance before each test + elevator = new Elevator(10); + }); + afterEach(() => { + jest.clearAllTimers(); + }); + it('should set destination to higher floor if moving up', () => { + elevator.currentFloor = 0; + elevator.currentDirection = 1; + elevator.currentDestination = 4; + elevator.setDestinationExternal(9); + expect(elevator.currentDestination).toEqual(9); + }); + it('should set destination to lower floor if moving down', () => { + elevator.currentFloor = 9; + elevator.currentDirection = -1; + elevator.currentDestination = 4; + elevator.setDestinationExternal(2); + expect(elevator.currentDestination).toEqual(2); + }); + it('should not change destination if moving up and currentDest > new request', () => { + elevator.currentFloor = 0; + elevator.currentDirection = 1; + elevator.currentDestination = 4; + elevator.setDestinationExternal(3); + expect(elevator.currentDestination).toEqual(4); + }); + it('should not change destination if moving down and currentDest < new request', () => { + elevator.currentFloor = 9; + elevator.currentDirection = -1; + elevator.currentDestination = 4; + elevator.setDestinationExternal(5); + expect(elevator.currentDestination).toEqual(4); + }); +}); diff --git a/coverage/clover.xml b/coverage/clover.xml new file mode 100644 index 0000000..e4dd495 --- /dev/null +++ b/coverage/clover.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json new file mode 100644 index 0000000..941977f --- /dev/null +++ b/coverage/coverage-final.json @@ -0,0 +1,2 @@ +{"/Users/shaysheller/Desktop/coding-challenge/elevator/elevator.ts": {"path":"/Users/shaysheller/Desktop/coding-challenge/elevator/elevator.ts","statementMap":{"0":{"start":{"line":2,"column":0},"end":{"line":2,"column":null}},"1":{"start":{"line":5,"column":0},"end":{"line":5,"column":null}},"2":{"start":{"line":11,"column":16},"end":{"line":13,"column":1}},"3":{"start":{"line":12,"column":2},"end":{"line":12,"column":null}},"4":{"start":{"line":14,"column":13},"end":{"line":18,"column":1}},"5":{"start":{"line":15,"column":12},"end":{"line":15,"column":13}},"6":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"7":{"start":{"line":16,"column":29},"end":{"line":16,"column":34}},"8":{"start":{"line":17,"column":2},"end":{"line":17,"column":null}},"9":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"10":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"11":{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},"12":{"start":{"line":46,"column":4},"end":{"line":46,"column":null}},"13":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"14":{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},"15":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"16":{"start":{"line":50,"column":4},"end":{"line":50,"column":null}},"17":{"start":{"line":51,"column":4},"end":{"line":51,"column":null}},"18":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"19":{"start":{"line":53,"column":4},"end":{"line":53,"column":null}},"20":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"21":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"22":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"23":{"start":{"line":57,"column":4},"end":{"line":57,"column":null}},"24":{"start":{"line":63,"column":4},"end":{"line":63,"column":null}},"25":{"start":{"line":64,"column":4},"end":{"line":64,"column":null}},"26":{"start":{"line":67,"column":6},"end":{"line":67,"column":null}},"27":{"start":{"line":71,"column":4},"end":{"line":72,"column":null}},"28":{"start":{"line":71,"column":32},"end":{"line":71,"column":58}},"29":{"start":{"line":72,"column":9},"end":{"line":72,"column":null}},"30":{"start":{"line":72,"column":47},"end":{"line":72,"column":null}},"31":{"start":{"line":78,"column":6},"end":{"line":78,"column":null}},"32":{"start":{"line":81,"column":6},"end":{"line":81,"column":null}},"33":{"start":{"line":82,"column":6},"end":{"line":82,"column":null}},"34":{"start":{"line":85,"column":8},"end":{"line":85,"column":null}},"35":{"start":{"line":90,"column":6},"end":{"line":90,"column":null}},"36":{"start":{"line":91,"column":6},"end":{"line":91,"column":null}},"37":{"start":{"line":92,"column":6},"end":{"line":92,"column":null}},"38":{"start":{"line":97,"column":6},"end":{"line":97,"column":null}},"39":{"start":{"line":102,"column":6},"end":{"line":102,"column":null}},"40":{"start":{"line":103,"column":6},"end":{"line":103,"column":null}},"41":{"start":{"line":107,"column":4},"end":{"line":107,"column":null}},"42":{"start":{"line":108,"column":4},"end":{"line":108,"column":null}},"43":{"start":{"line":109,"column":4},"end":{"line":109,"column":null}},"44":{"start":{"line":110,"column":4},"end":{"line":110,"column":null}},"45":{"start":{"line":113,"column":4},"end":{"line":113,"column":null}},"46":{"start":{"line":121,"column":17},"end":{"line":121,"column":110}},"47":{"start":{"line":124,"column":6},"end":{"line":124,"column":null}},"48":{"start":{"line":124,"column":57},"end":{"line":124,"column":null}},"49":{"start":{"line":129,"column":6},"end":{"line":129,"column":null}},"50":{"start":{"line":130,"column":6},"end":{"line":130,"column":null}},"51":{"start":{"line":134,"column":6},"end":{"line":134,"column":null}},"52":{"start":{"line":136,"column":6},"end":{"line":136,"column":null}},"53":{"start":{"line":140,"column":4},"end":{"line":140,"column":null}},"54":{"start":{"line":147,"column":4},"end":{"line":147,"column":null}},"55":{"start":{"line":150,"column":6},"end":{"line":150,"column":null}},"56":{"start":{"line":154,"column":6},"end":{"line":154,"column":null}},"57":{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},"58":{"start":{"line":158,"column":4},"end":{"line":158,"column":null}},"59":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"60":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"61":{"start":{"line":161,"column":4},"end":{"line":161,"column":null}},"62":{"start":{"line":169,"column":6},"end":{"line":169,"column":null}},"63":{"start":{"line":171,"column":6},"end":{"line":171,"column":null}},"64":{"start":{"line":173,"column":6},"end":{"line":173,"column":null}},"65":{"start":{"line":185,"column":10},"end":{"line":185,"column":null}},"66":{"start":{"line":188,"column":26},"end":{"line":188,"column":94}},"67":{"start":{"line":189,"column":18},"end":{"line":189,"column":40}},"68":{"start":{"line":190,"column":29},"end":{"line":190,"column":43}},"69":{"start":{"line":192,"column":10},"end":{"line":192,"column":null}},"70":{"start":{"line":193,"column":10},"end":{"line":193,"column":null}},"71":{"start":{"line":194,"column":10},"end":{"line":194,"column":null}},"72":{"start":{"line":197,"column":6},"end":{"line":197,"column":null}},"73":{"start":{"line":197,"column":30},"end":{"line":197,"column":null}},"74":{"start":{"line":202,"column":10},"end":{"line":202,"column":null}},"75":{"start":{"line":210,"column":19},"end":{"line":210,"column":54}},"76":{"start":{"line":212,"column":6},"end":{"line":212,"column":null}},"77":{"start":{"line":215,"column":4},"end":{"line":215,"column":null}},"78":{"start":{"line":216,"column":4},"end":{"line":216,"column":null}},"79":{"start":{"line":225,"column":6},"end":{"line":225,"column":null}},"80":{"start":{"line":226,"column":6},"end":{"line":226,"column":null}},"81":{"start":{"line":228,"column":6},"end":{"line":228,"column":null}},"82":{"start":{"line":228,"column":42},"end":{"line":228,"column":null}},"83":{"start":{"line":230,"column":6},"end":{"line":230,"column":null}},"84":{"start":{"line":230,"column":42},"end":{"line":230,"column":null}},"85":{"start":{"line":237,"column":46},"end":{"line":237,"column":53}},"86":{"start":{"line":239,"column":6},"end":{"line":242,"column":null}},"87":{"start":{"line":245,"column":4},"end":{"line":245,"column":null}},"88":{"start":{"line":248,"column":4},"end":{"line":248,"column":null}},"89":{"start":{"line":248,"column":46},"end":{"line":248,"column":null}},"90":{"start":{"line":254,"column":4},"end":{"line":254,"column":null}},"91":{"start":{"line":259,"column":4},"end":{"line":262,"column":null}},"92":{"start":{"line":267,"column":0},"end":{"line":267,"column":null}}},"fnMap":{"0":{"name":"(anonymous_6)","decl":{"start":{"line":11,"column":16},"end":{"line":11,"column":27}},"loc":{"start":{"line":11,"column":31},"end":{"line":13,"column":1}}},"1":{"name":"(anonymous_7)","decl":{"start":{"line":14,"column":13},"end":{"line":14,"column":26}},"loc":{"start":{"line":14,"column":30},"end":{"line":18,"column":1}}},"2":{"name":"(anonymous_8)","decl":{"start":{"line":16,"column":19},"end":{"line":16,"column":20}},"loc":{"start":{"line":16,"column":29},"end":{"line":16,"column":34}}},"3":{"name":"(anonymous_9)","decl":{"start":{"line":42,"column":2},"end":{"line":42,"column":14}},"loc":{"start":{"line":42,"column":28},"end":{"line":58,"column":null}}},"4":{"name":"(anonymous_10)","decl":{"start":{"line":61,"column":2},"end":{"line":61,"column":6}},"loc":{"start":{"line":61,"column":6},"end":{"line":114,"column":null}}},"5":{"name":"(anonymous_11)","decl":{"start":{"line":119,"column":2},"end":{"line":119,"column":24}},"loc":{"start":{"line":119,"column":24},"end":{"line":142,"column":null}}},"6":{"name":"(anonymous_12)","decl":{"start":{"line":145,"column":2},"end":{"line":145,"column":6}},"loc":{"start":{"line":145,"column":6},"end":{"line":162,"column":null}}},"7":{"name":"(anonymous_13)","decl":{"start":{"line":166,"column":2},"end":{"line":166,"column":10}},"loc":{"start":{"line":166,"column":10},"end":{"line":176,"column":null}}},"8":{"name":"(anonymous_14)","decl":{"start":{"line":179,"column":2},"end":{"line":179,"column":9}},"loc":{"start":{"line":179,"column":9},"end":{"line":206,"column":null}}},"9":{"name":"(anonymous_15)","decl":{"start":{"line":209,"column":2},"end":{"line":209,"column":13}},"loc":{"start":{"line":209,"column":27},"end":{"line":218,"column":null}}},"10":{"name":"(anonymous_16)","decl":{"start":{"line":222,"column":2},"end":{"line":222,"column":24}},"loc":{"start":{"line":222,"column":38},"end":{"line":232,"column":null}}},"11":{"name":"(anonymous_17)","decl":{"start":{"line":235,"column":2},"end":{"line":235,"column":9}},"loc":{"start":{"line":235,"column":34},"end":{"line":250,"column":null}}},"12":{"name":"(anonymous_18)","decl":{"start":{"line":253,"column":2},"end":{"line":253,"column":13}},"loc":{"start":{"line":253,"column":13},"end":{"line":255,"column":null}}},"13":{"name":"(anonymous_19)","decl":{"start":{"line":258,"column":2},"end":{"line":258,"column":12}},"loc":{"start":{"line":258,"column":12},"end":{"line":263,"column":null}}}},"branchMap":{"0":{"loc":{"start":{"line":66,"column":7},"end":{"line":66,"column":37}},"type":"binary-expr","locations":[{"start":{"line":66,"column":7},"end":{"line":66,"column":16}},{"start":{"line":66,"column":20},"end":{"line":66,"column":37}}]},"1":{"loc":{"start":{"line":71,"column":4},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":71,"column":4},"end":{"line":72,"column":null}},{"start":{"line":72,"column":9},"end":{"line":72,"column":null}}]},"2":{"loc":{"start":{"line":72,"column":9},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":9},"end":{"line":72,"column":null}}]},"3":{"loc":{"start":{"line":76,"column":7},"end":{"line":77,"column":52}},"type":"binary-expr","locations":[{"start":{"line":76,"column":7},"end":{"line":76,"column":31}},{"start":{"line":76,"column":36},"end":{"line":76,"column":66}},{"start":{"line":76,"column":70},"end":{"line":76,"column":115}},{"start":{"line":77,"column":7},"end":{"line":77,"column":52}}]},"4":{"loc":{"start":{"line":89,"column":7},"end":{"line":89,"column":72}},"type":"binary-expr","locations":[{"start":{"line":89,"column":7},"end":{"line":89,"column":37}},{"start":{"line":89,"column":41},"end":{"line":89,"column":72}}]},"5":{"loc":{"start":{"line":121,"column":17},"end":{"line":121,"column":110}},"type":"cond-expr","locations":[{"start":{"line":121,"column":49},"end":{"line":121,"column":105}},{"start":{"line":121,"column":108},"end":{"line":121,"column":110}}]},"6":{"loc":{"start":{"line":124,"column":6},"end":{"line":124,"column":null}},"type":"if","locations":[{"start":{"line":124,"column":6},"end":{"line":124,"column":null}}]},"7":{"loc":{"start":{"line":140,"column":28},"end":{"line":140,"column":80}},"type":"cond-expr","locations":[{"start":{"line":140,"column":74},"end":{"line":140,"column":75}},{"start":{"line":140,"column":78},"end":{"line":140,"column":80}}]},"8":{"loc":{"start":{"line":169,"column":39},"end":{"line":169,"column":92}},"type":"cond-expr","locations":[{"start":{"line":169,"column":86},"end":{"line":169,"column":90}},{"start":{"line":169,"column":90},"end":{"line":169,"column":92}}]},"9":{"loc":{"start":{"line":169,"column":39},"end":{"line":169,"column":90}},"type":"binary-expr","locations":[{"start":{"line":169,"column":39},"end":{"line":169,"column":90}},{"start":{"line":169,"column":86},"end":{"line":169,"column":90}}]},"10":{"loc":{"start":{"line":183,"column":9},"end":{"line":184,"column":84}},"type":"binary-expr","locations":[{"start":{"line":183,"column":9},"end":{"line":183,"column":54}},{"start":{"line":184,"column":8},"end":{"line":184,"column":84}}]},"11":{"loc":{"start":{"line":185,"column":34},"end":{"line":185,"column":70}},"type":"cond-expr","locations":[{"start":{"line":185,"column":64},"end":{"line":185,"column":66}},{"start":{"line":185,"column":69},"end":{"line":185,"column":70}}]},"12":{"loc":{"start":{"line":197,"column":6},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":197,"column":6},"end":{"line":197,"column":null}}]},"13":{"loc":{"start":{"line":201,"column":9},"end":{"line":201,"column":126}},"type":"binary-expr","locations":[{"start":{"line":201,"column":9},"end":{"line":201,"column":65}},{"start":{"line":201,"column":69},"end":{"line":201,"column":126}}]},"14":{"loc":{"start":{"line":226,"column":30},"end":{"line":226,"column":64}},"type":"cond-expr","locations":[{"start":{"line":226,"column":58},"end":{"line":226,"column":59}},{"start":{"line":226,"column":62},"end":{"line":226,"column":64}}]},"15":{"loc":{"start":{"line":228,"column":6},"end":{"line":228,"column":null}},"type":"if","locations":[{"start":{"line":228,"column":6},"end":{"line":228,"column":null}}]},"16":{"loc":{"start":{"line":230,"column":6},"end":{"line":230,"column":null}},"type":"if","locations":[{"start":{"line":230,"column":6},"end":{"line":230,"column":null}}]},"17":{"loc":{"start":{"line":248,"column":4},"end":{"line":248,"column":null}},"type":"if","locations":[{"start":{"line":248,"column":4},"end":{"line":248,"column":null}}]},"18":{"loc":{"start":{"line":259,"column":12},"end":{"line":262,"column":39}},"type":"binary-expr","locations":[{"start":{"line":259,"column":12},"end":{"line":259,"column":59}},{"start":{"line":260,"column":4},"end":{"line":260,"column":38}},{"start":{"line":261,"column":4},"end":{"line":261,"column":34}},{"start":{"line":261,"column":38},"end":{"line":261,"column":69}},{"start":{"line":262,"column":7},"end":{"line":262,"column":39}}]}},"s":{"0":1,"1":1,"2":1,"3":9,"4":1,"5":2,"6":2,"7":0,"8":2,"9":10,"10":10,"11":10,"12":10,"13":10,"14":10,"15":10,"16":10,"17":10,"18":10,"19":10,"20":10,"21":10,"22":10,"23":10,"24":6,"25":6,"26":0,"27":6,"28":1,"29":5,"30":0,"31":0,"32":0,"33":0,"34":1,"35":1,"36":1,"37":1,"38":1,"39":0,"40":0,"41":5,"42":5,"43":5,"44":5,"45":5,"46":2,"47":1,"48":0,"49":1,"50":1,"51":1,"52":0,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":2,"63":2,"64":2,"65":0,"66":3,"67":3,"68":5,"69":4,"70":4,"71":4,"72":3,"73":2,"74":2,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":2,"82":1,"83":2,"84":1,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":1,"92":1},"f":{"0":9,"1":2,"2":0,"3":10,"4":6,"5":2,"6":1,"7":5,"8":5,"9":0,"10":4,"11":0,"12":0,"13":1},"b":{"0":[6,1],"1":[1,5],"2":[0],"3":[6,6,6,1],"4":[6,5],"5":[1,1],"6":[0],"7":[1,0],"8":[2,0],"9":[2,2],"10":[3,2],"11":[0,0],"12":[2],"13":[3,2],"14":[0,0],"15":[1],"16":[1],"17":[0],"18":[1,1,1,0,0]}} +} diff --git a/coverage/lcov-report/base.css b/coverage/lcov-report/base.css new file mode 100644 index 0000000..f418035 --- /dev/null +++ b/coverage/lcov-report/base.css @@ -0,0 +1,224 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* yellow */ +.cbranch-no { background: yellow !important; color: #111; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +.highlighted, +.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ + background: #C21F39 !important; +} +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +.medium .chart { border:1px solid #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + +span.cline-neutral { background: #eaeaea; } + +.coverage-summary td.empty { + opacity: .5; + padding-top: 4px; + padding-bottom: 4px; + line-height: 1; + color: #888; +} + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/coverage/lcov-report/block-navigation.js b/coverage/lcov-report/block-navigation.js new file mode 100644 index 0000000..cc12130 --- /dev/null +++ b/coverage/lcov-report/block-navigation.js @@ -0,0 +1,87 @@ +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + + // Selecter that finds elements on the page to which we can jump + var selector = + fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + + var currentIndex; + + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + + makeCurrent(nextIndex); + } + + function goToNext() { + var nextIndex = 0; + + if ( + typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1 + ) { + nextIndex = currentIndex + 1; + } + + makeCurrent(nextIndex); + } + + return function jump(event) { + if ( + document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null + ) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/coverage/lcov-report/elevator.ts.html b/coverage/lcov-report/elevator.ts.html new file mode 100644 index 0000000..802910c --- /dev/null +++ b/coverage/lcov-report/elevator.ts.html @@ -0,0 +1,889 @@ + + + + + + Code coverage report for elevator.ts + + + + + + + + + +
+
+

All files elevator.ts

+
+ +
+ 75.26% + Statements + 70/93 +
+ + +
+ 70.27% + Branches + 26/37 +
+ + +
+ 71.42% + Functions + 10/14 +
+ + +
+ 77.64% + Lines + 66/85 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269  +1x +  +  +1x +  +  +  +  +  +1x +9x +  +1x +2x +2x +2x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +10x +  +  +  +  +  +6x +6x +  +  +  +  +  +  +6x +5x +  +  +  +  +  +  +  +  +  +  +  +  +1x +  +  +  +  +1x +1x +1x +  +  +  +  +1x +  +  +  +  +  +  +  +  +  +5x +5x +5x +5x +  +  +5x +  +  +  +  +  +  +  +2x +  +  +1x +  +  +  +  +1x +1x +  +  +  +1x +  +  +  +  +  +1x +  +  +  +  +  +  +1x +  +  +1x +  +  +  +1x +1x +  +  +1x +1x +1x +1x +  +  +  +  +  +  +  +2x +  +2x +  +2x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +3x +3x +5x +  +4x +4x +4x +  +  +3x +  +  +  +  +2x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +2x +  +2x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +  +  +  +  +  +  +  +1x +  + 
// to write to new files for output 
+import * as fs from 'fs'
+ 
+// to add EOL character to file output
+import * as os from 'os';
+ 
+import {ElevatorRequest, ExternalRequestObject, DirectionObject} from './types.js';
+ 
+// import {output, sum} from './functions.js'
+ 
+const output = (txt: string) => {
+  fs.appendFileSync('output.txt', txt + os.EOL);
+};
+const sum = (arr: number[]) => {
+  let sum = 0;
+  sum = arr.reduce((a, b) => a + b);
+  return sum;
+};
+ 
+ 
+// internal request : buttons pressed from inside the elevator by passengers
+// external requets : buttons pressed on floor N going U or D 
+ 
+class Elevator { 
+ 
+  floors: number;
+  state: 'stopped' | 'moving';
+  currentFloor: number;
+  currentDirection: 1 | -1;
+  currentDestination: number;
+  departureRequestMap: Map<number, number[]>;
+  externalRequestObject: ExternalRequestObject;
+  travelInterval: number;
+  stopInterval: number;
+  quit: boolean;
+  passengerRequestQueue: number[];
+  boardingPassengers: number[];
+  departingPassengers: number[];
+  currentWeight: number;
+  weightLimit: number;
+ 
+  constructor(floors: number) {
+    this.floors = floors;
+    this.state = 'stopped'
+    this.currentFloor = 0;
+    this.currentDirection = 1;
+    this.currentDestination = -1;
+    this.departureRequestMap = new Map(); 
+    this.externalRequestObject = {};
+    this.travelInterval = 3000;
+    this.stopInterval = 1000;
+    this.quit = false;
+    this.passengerRequestQueue = [];
+    this.boardingPassengers = [];
+    this.departingPassengers = [];
+    this.currentWeight = 0;
+    this.weightLimit = 50;
+  }
+ 
+ 
+  move() {
+ 
+    this.move = this.move.bind(this);
+    output('Current Floor: ' + this.currentFloor);
+ 
+    if(this.quit && this.endProcess()) {
+      process.exit();
+    }
+ 
+    // check if elevator is inside the correct boundary
+    if(this.currentFloor === 0) this.currentDirection = 1;
+    else Iif(this.currentFloor === this.floors) this.currentDirection = -1;
+ 
+    
+    // if elevator is not moving and someone requests same floor to get on
+    if(this.state === 'stopped' && (this.currentDestination === -1 || this.currentDestination === this.currentFloor)
+    && this.externalRequestObject[this.currentFloor]) {
+      this.checkOn();
+    // if elevator is not moving and has no requests - wait 1s and check for new reqeusts  
+    } else if(this.currentDestination === -1) {
+      setTimeout(this.move, this.stopInterval);
+      return;
+    // if we have reached the destination - check for new destination based on unserved requests
+    } else if(this.currentDestination === this.currentFloor) {
+        this.setDestinationDecision();
+    }
+     
+    // check if anyone is getting on or off at current floor
+    if(this.boardingPassengers.length || this.departingPassengers.length) {
+      output('we got on / off')
+      this.stop();
+      return;
+    }
+ 
+    // if at or above weight limit : need to reset destination to only internal requests
+    if(this.currentWeight >= this.weightLimit) {
+      this.setDestinationDecision(); 
+    }
+ 
+    // if there is no current destination : wait interval to see if there is a new request
+    if(this.currentDestination === -1) {
+      setTimeout(this.move, this.stopInterval);
+      return;
+    }
+   
+    // increment / decrement current floor and change state to moving : check if any board / deboard next floor
+    this.currentFloor += this.currentDirection;
+    this.state = 'moving';
+    this.checkOff();
+    this.checkOn();
+    
+    
+    setTimeout(this.move, this.travelInterval);
+  }
+ 
+ 
+  // if elevator is empty and there are still unserved requests -> elevator decides where to go here
+  // picks furthest away floor in opposite direction - either external floor request or internal elevator request
+  setDestinationDecision() {
+ 
+    const keys = this.departureRequestMap.size ? [Number(...Array.from(this.departureRequestMap.keys()))] : [];
+    //if we are at or above the weight limit don't consider external requests
+    if(this.currentWeight < this.weightLimit) {
+      Iif(Object.keys(this.externalRequestObject).length) keys.push(Number(...Object.keys(this.externalRequestObject))); 
+    }
+    
+    // if there are no requests to serve
+    if(!keys.length) {
+      this.currentDestination = -1; 
+      return;
+    }
+ 
+    if(this.currentDirection === 1) {
+      this.currentDestination = Number(Math.max(...keys));
+    } else if(this.currentDirection === -1) {
+      this.currentDestination = Number(Math.min(...keys));
+    }
+ 
+ 
+    this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1;
+ 
+  }
+ 
+  // stops elevator and boards / deboards passengers depending on their request
+  stop() {
+  
+    this.state = 'stopped';
+ 
+    if(this.departingPassengers.length) {
+      output(JSON.stringify(this.departingPassengers) + 'all got off ' + this.currentFloor);
+    }
+ 
+    if(this.boardingPassengers.length) {
+      this.passengerRequestQueue.push(...this.boardingPassengers);
+      output(JSON.stringify(this.boardingPassengers) + ' all got on ' + this.currentFloor)
+    }
+ 
+    this.departingPassengers = [];
+    this.boardingPassengers = [];
+    this.move = this.move.bind(this);
+    setTimeout(this.move, this.stopInterval);
+  }
+  
+  // check who is getting off the elevator while it is in transit from floor n to floor n +/- 1
+  // decrements weight of passengers getting off
+  checkOff() {
+ 
+    if(this.departureRequestMap.get(this.currentFloor) !== undefined) {
+      this.departingPassengers.push(...this.departureRequestMap.get(this.currentFloor) ?? []);
+      
+      this.currentWeight -= sum(this.departingPassengers);
+      
+      this.departureRequestMap.delete(this.currentFloor);
+      
+    }
+  }
+ 
+  // checks who is getting on based on direction elevator is traveling and currentWeight of elevator
+  checkOn() {
+    
+    if(this.externalRequestObject[this.currentFloor] !== undefined) {
+      // if elevator has reached destination floor it needs to change direction if the request is in the opposite direction
+      if(this.currentFloor === this.currentDestination && 
+        !this.externalRequestObject[this.currentFloor][this.currentDirection].length) {
+          this.currentDirection = this.currentDirection === 1 ? -1 : 1;
+      }
+ 
+      const boardingArr = this.externalRequestObject[this.currentFloor][this.currentDirection];
+      for(let i = boardingArr.length - 1; i >= 0; i--) {
+        let currentBoarder = boardingArr[i];
+        if(currentBoarder + this.currentWeight <= this.weightLimit) {
+          this.boardingPassengers.push(currentBoarder);
+          boardingArr.pop();
+          this.currentWeight += currentBoarder;
+        }
+      }
+      if(!boardingArr.length) this.externalRequestObject[this.currentFloor][this.currentDirection] = [];
+      
+ 
+      // clears request Obj of current floor if there aren't any more requests on this floor
+      if(!this.externalRequestObject[this.currentFloor][1].length && !this.externalRequestObject[this.currentFloor][-1].length) {
+          delete this.externalRequestObject[this.currentFloor];
+      }
+ 
+    }
+  }
+ 
+  // internal floor request sets their destination in departureRequestMap
+  selectFloor(floor: number) {
+    const weight = this.passengerRequestQueue.shift()!;
+    if(this.departureRequestMap.get(floor) === undefined) {
+      this.departureRequestMap.set(floor, []);
+    }
+ 
+    this.departureRequestMap.get(floor)!.push(weight);
+    this.setDestinationExternal(floor);
+    
+  }
+ 
+ 
+  // if there is an external request where our currentDestination should change 
+  setDestinationExternal(floor: number) {
+ 
+    if(this.currentDestination === -1) {
+      this.currentDestination = floor;
+      this.currentDirection = floor > this.currentFloor ? 1 : -1;
+    } else if(this.currentDirection === 1) {
+      if(floor > this.currentDestination) this.currentDestination = floor;
+    } else if(this.currentDirection === -1) {
+      if(floor < this.currentDestination) this.currentDestination = floor;
+    }
+  }
+ 
+  // handles external request
+  request(request: ElevatorRequest) {
+ 
+    const {currentFloor, direction, weight} = request;
+    if(this.externalRequestObject[currentFloor] === undefined) {
+      this.externalRequestObject[currentFloor] = {
+        '1': [],
+        '-1': []
+      };
+    }
+ 
+    this.externalRequestObject[currentFloor][direction].push(weight);
+    
+    // if the destination needs to be changed based on current direction it will be set here if weight allows
+    Iif(this.currentWeight < this.weightLimit) this.setDestinationExternal(currentFloor);
+ 
+  }
+ 
+  // when quit is typed into console
+  stopProcess() {
+    this.quit = true;
+  }
+ 
+  // will end when all requests have been served and all passengers are off the elevator
+  endProcess() {
+    return (!Object.keys(this.externalRequestObject).length && 
+    !this.passengerRequestQueue.length && 
+    !this.departureRequestMap.size && !this.boardingPassengers.length
+    && !this.departingPassengers.length)
+  }
+ 
+}
+ 
+export default Elevator;
+ 
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/favicon.png b/coverage/lcov-report/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..c1525b811a167671e9de1fa78aab9f5c0b61cef7 GIT binary patch literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> + + + + Code coverage report for All files + + + + + + + + + +
+
+

All files

+
+ +
+ 75.26% + Statements + 70/93 +
+ + +
+ 70.27% + Branches + 26/37 +
+ + +
+ 71.42% + Functions + 10/14 +
+ + +
+ 77.64% + Lines + 66/85 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
elevator.ts +
+
75.26%70/9370.27%26/3771.42%10/1477.64%66/85
+
+
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/prettify.css b/coverage/lcov-report/prettify.css new file mode 100644 index 0000000..b317a7c --- /dev/null +++ b/coverage/lcov-report/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/lcov-report/prettify.js b/coverage/lcov-report/prettify.js new file mode 100644 index 0000000..b322523 --- /dev/null +++ b/coverage/lcov-report/prettify.js @@ -0,0 +1,2 @@ +/* eslint-disable */ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/lcov-report/sort-arrow-sprite.png b/coverage/lcov-report/sort-arrow-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..6ed68316eb3f65dec9063332d2f69bf3093bbfab GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc literal 0 HcmV?d00001 diff --git a/coverage/lcov-report/sorter.js b/coverage/lcov-report/sorter.js new file mode 100644 index 0000000..2bb296a --- /dev/null +++ b/coverage/lcov-report/sorter.js @@ -0,0 +1,196 @@ +/* eslint-disable */ +var addSorting = (function() { + 'use strict'; + var cols, + currentSort = { + index: 0, + desc: false + }; + + // returns the summary table element + function getTable() { + return document.querySelector('.coverage-summary'); + } + // returns the thead element of the summary table + function getTableHeader() { + return getTable().querySelector('thead tr'); + } + // returns the tbody element of the summary table + function getTableBody() { + return getTable().querySelector('tbody'); + } + // returns the th element for nth column + function getNthColumn(n) { + return getTableHeader().querySelectorAll('th')[n]; + } + + function onFilterInput() { + const searchValue = document.getElementById('fileSearch').value; + const rows = document.getElementsByTagName('tbody')[0].children; + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + if ( + row.textContent + .toLowerCase() + .includes(searchValue.toLowerCase()) + ) { + row.style.display = ''; + } else { + row.style.display = 'none'; + } + } + } + + // loads the search box + function addSearchBox() { + var template = document.getElementById('filterTemplate'); + var templateClone = template.content.cloneNode(true); + templateClone.getElementById('fileSearch').oninput = onFilterInput; + template.parentElement.appendChild(templateClone); + } + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = + colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function(a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function(a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc + ? ' sorted-desc' + : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function() { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i = 0; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function() { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(); + addSearchBox(); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/coverage/lcov.info b/coverage/lcov.info new file mode 100644 index 0000000..43aa2ab --- /dev/null +++ b/coverage/lcov.info @@ -0,0 +1,159 @@ +TN: +SF:elevator/elevator.ts +FN:11,(anonymous_6) +FN:14,(anonymous_7) +FN:16,(anonymous_8) +FN:42,(anonymous_9) +FN:61,(anonymous_10) +FN:119,(anonymous_11) +FN:145,(anonymous_12) +FN:166,(anonymous_13) +FN:179,(anonymous_14) +FN:209,(anonymous_15) +FN:222,(anonymous_16) +FN:235,(anonymous_17) +FN:253,(anonymous_18) +FN:258,(anonymous_19) +FNF:14 +FNH:10 +FNDA:9,(anonymous_6) +FNDA:2,(anonymous_7) +FNDA:0,(anonymous_8) +FNDA:10,(anonymous_9) +FNDA:6,(anonymous_10) +FNDA:2,(anonymous_11) +FNDA:1,(anonymous_12) +FNDA:5,(anonymous_13) +FNDA:5,(anonymous_14) +FNDA:0,(anonymous_15) +FNDA:4,(anonymous_16) +FNDA:0,(anonymous_17) +FNDA:0,(anonymous_18) +FNDA:1,(anonymous_19) +DA:2,1 +DA:5,1 +DA:11,1 +DA:12,9 +DA:14,1 +DA:15,2 +DA:16,2 +DA:17,2 +DA:43,10 +DA:44,10 +DA:45,10 +DA:46,10 +DA:47,10 +DA:48,10 +DA:49,10 +DA:50,10 +DA:51,10 +DA:52,10 +DA:53,10 +DA:54,10 +DA:55,10 +DA:56,10 +DA:57,10 +DA:63,6 +DA:64,6 +DA:67,0 +DA:71,6 +DA:72,5 +DA:78,0 +DA:81,0 +DA:82,0 +DA:85,1 +DA:90,1 +DA:91,1 +DA:92,1 +DA:97,1 +DA:102,0 +DA:103,0 +DA:107,5 +DA:108,5 +DA:109,5 +DA:110,5 +DA:113,5 +DA:121,2 +DA:124,1 +DA:129,1 +DA:130,1 +DA:134,1 +DA:136,0 +DA:140,1 +DA:147,1 +DA:150,1 +DA:154,1 +DA:155,1 +DA:158,1 +DA:159,1 +DA:160,1 +DA:161,1 +DA:169,2 +DA:171,2 +DA:173,2 +DA:185,0 +DA:188,3 +DA:189,3 +DA:190,5 +DA:192,4 +DA:193,4 +DA:194,4 +DA:197,3 +DA:202,2 +DA:210,0 +DA:212,0 +DA:215,0 +DA:216,0 +DA:225,0 +DA:226,0 +DA:228,2 +DA:230,2 +DA:237,0 +DA:239,0 +DA:245,0 +DA:248,0 +DA:254,0 +DA:259,1 +DA:267,1 +LF:85 +LH:66 +BRDA:66,0,0,6 +BRDA:66,0,1,1 +BRDA:71,1,0,1 +BRDA:71,1,1,5 +BRDA:72,2,0,0 +BRDA:76,3,0,6 +BRDA:76,3,1,6 +BRDA:76,3,2,6 +BRDA:76,3,3,1 +BRDA:89,4,0,6 +BRDA:89,4,1,5 +BRDA:121,5,0,1 +BRDA:121,5,1,1 +BRDA:124,6,0,0 +BRDA:140,7,0,1 +BRDA:140,7,1,0 +BRDA:169,8,0,2 +BRDA:169,8,1,0 +BRDA:169,9,0,2 +BRDA:169,9,1,2 +BRDA:183,10,0,3 +BRDA:183,10,1,2 +BRDA:185,11,0,0 +BRDA:185,11,1,0 +BRDA:197,12,0,2 +BRDA:201,13,0,3 +BRDA:201,13,1,2 +BRDA:226,14,0,0 +BRDA:226,14,1,0 +BRDA:228,15,0,1 +BRDA:230,16,0,1 +BRDA:248,17,0,0 +BRDA:259,18,0,1 +BRDA:259,18,1,1 +BRDA:259,18,2,1 +BRDA:259,18,3,0 +BRDA:259,18,4,0 +BRF:37 +BRH:26 +end_of_record diff --git a/elevator/README.md b/elevator/README.md index e161796..79f0439 100644 --- a/elevator/README.md +++ b/elevator/README.md @@ -1,23 +1,27 @@ # Build an Elevator Coding Challenge! -## The Challenge +## The Challenge + Create an application that simulates the operation of a simple elevator. ## Requirements - - The elevator must travel in one direction at a time until it needs to go no further (**e.g.** keep going until the elevator has reached the top/bottom of the building, or no stop is requested on any floor ahead). - - Elevator floor request buttons can be pressed **asynchronously** from inside or outside the elevator while it is running. - - Elevator will stop at the closest floor first, in the direction of motion, then the next closest and so on. Any floors requested while the elevator is moving should be taken into account. - - Elevator will stop at all asynchronously requested floors, only if the request is made while the elevator is at least one floor away (**e.g.** if elevator is **between** 4th and 5th floor, going up, and the 5th floor is requested at that moment, elevator will not stop at the 5th floor while going up; it will stop there while going down). - - When elevator arrives at a requested floor, it waits for 1 second. It takes 3 seconds to travel between consecutive floors. - - A sensor tells the elevator its direction, next/current floor, state (stopped, moving) and if the elevator has reached its max weight limit. - - Use the sensor data plus the asynchronous floor request button data to work the elevator. - - Write meaningful **unit tests** that show the elevator works correctly, even if the application is not run. - - Log the following to a file, to verify elevator works well: - - Timestamp and asynchronous floor request, every time one occurs. - - Timestamp and floor, every time elevator **passes** a floor. - - Timestamp and floor, every time elevator **stops** at a floor. + +- The elevator must travel in one direction at a time until it needs to go no further (**e.g.** keep going until the elevator has reached the top/bottom of the building, or no stop is requested on any floor ahead). +- Elevator floor request buttons can be pressed **asynchronously** from inside or outside the elevator while it is running. +- Elevator will stop at the closest floor first, in the direction of motion, then the next closest and so on. Any floors requested while the elevator is moving should be taken into account. +- Elevator will stop at all asynchronously requested floors, only if the request is made while the elevator is at least one floor away (**e.g.** if elevator is **between** 4th and 5th floor, going up, and the 5th floor is requested at that moment, elevator will not stop at the 5th floor while going up; it will stop there while going down). +- When elevator arrives at a requested floor, it waits for 1 second. It takes 3 seconds to travel between consecutive floors. + \*\*\*\* should we allow new requests to board the elevator at this time to work? I think yes - problem for later +- A sensor tells the elevator its direction, next/current floor, state (stopped, moving) and if the elevator has reached its max weight limit. +- Use the sensor data plus the asynchronous floor request button data to work the elevator. +- Write meaningful **unit tests** that show the elevator works correctly, even if the application is not run. +- Log the following to a file, to verify elevator works well: + - Timestamp and asynchronous floor request, every time one occurs. + - Timestamp and floor, every time elevator **passes** a floor. + - Timestamp and floor, every time elevator **stops** at a floor. **Bonus Enhancement:** - - Enhance the application as follows: If the elevator has reached its weight limit, it should stop only at floors that were selected from inside the elevator (to let passengers out), until it is no longer at the max weight limit. -**Note:** For simplicity, the asynchronous request buttons can be entered by the application user via the console, by entering **"5U"** (request from 5th floor wanting to go Up) or **"8D"** (request from 8th floor wanting to go Down) or **"2"** (request from inside elevator wanting to stop at 2nd floor). When the user enters **"Q"** on the console, the application must end after visiting all floors entered before **"Q"**. \ No newline at end of file +- Enhance the application as follows: If the elevator has reached its weight limit, it should stop only at floors that were selected from inside the elevator (to let passengers out), until it is no longer at the max weight limit. + +**Note:** For simplicity, the asynchronous request buttons can be entered by the application user via the console, by entering **"5U"** (request from 5th floor wanting to go Up) or **"8D"** (request from 8th floor wanting to go Down) or **"2"** (request from inside elevator wanting to stop at 2nd floor). When the user enters **"Q"** on the console, the application must end after visiting all floors entered before **"Q"**. diff --git a/elevator/README2.md b/elevator/README2.md new file mode 100644 index 0000000..dccbd4d --- /dev/null +++ b/elevator/README2.md @@ -0,0 +1,12 @@ +# How to run application + +- clone to machine +- type: `npm install` into command line +- type: `tsc -w` into command line +- type: `node build/elevator/main.js` into command line +- Elevator instructions are the same as the initial README +- to run tests: `npm run test` into command line + +notes: + +- you can change max floors by changing line 14 in elevator/main.ts -> right now it's set to 15 diff --git a/elevator/elevator.js b/elevator/elevator.js deleted file mode 100644 index c5b2176..0000000 --- a/elevator/elevator.js +++ /dev/null @@ -1,242 +0,0 @@ -// to write to new files for output -const fs = require('fs'); - -// to add EOL character to file output -const os = require('os'); - -// to make output easier -const output = txt => { - fs.appendFileSync('output.txt', txt + os.EOL); -} - -// internal request : buttons pressed from inside the elevator by passengers -// external requets : buttons pressed on floor N going U or D - -const sum = arr => { - let sum = 0; - sum = arr.reduce((a,b) => a + b); - return sum; -} - -class Elevator { - constructor(floors) { - this.floors = floors; - this.state = 'stopped' - this.currentFloor = 0; - this.currentDirection = 1; - this.currentDestination = -1; - this.departureRequestMap = new Map(); - this.externalRequestObject = {}; - this.travelInterval = 1500; - this.stopInterval = 500; - this.quit = false; - this.passengerQueue = []; - this.boardingPassengers = []; - this.departingPassengers = []; - this.currentWeight = 0; - this.weightLimit = 50; - } - - - move() { - - this.move = this.move.bind(this); - output('Current Floor: ' + this.currentFloor); - - if(this.quit && this.endProcess()) { - process.exit(); - } - - // check if elevator is inside the correct boundary - if(this.currentFloor === 0) this.currentDirection = 1; - else if(this.currentFloor === this.floors) this.currentDirection = -1; - - - // if elevator is not moving and someone requests same floor to get on - if(this.state === 'stopped' && this.currentDestination === -1 && this.externalRequestObject[this.currentFloor]) { - this.checkOn(); - // if elevator is not moving and has no requests - wait 1s and check for new reqeusts - } else if(this.currentDestination === -1) { - setTimeout(this.move, this.stopInterval); - return; - // if we have reached the destination - check for new destination based on unserved requests - } else if(this.currentDestination === this.currentFloor) { - this.setDestinationDecision(); - } - - // check if anyone is getting on or off at current floor - if(this.boardingPassengers.length || this.departingPassengers.length) { - output('we got on / off') - this.stop(); - return; - } - - // if at or above weight limit : need to reset destination to only internal requests - if(this.currentWeight >= this.weightLimit) this.setDestinationDecision(); - - if(this.currentDestination === -1) { - setTimeout(this.move, this.stopInterval); - return; - } - - this.currentFloor += this.currentDirection; - this.state = 'moving'; - this.checkOff(); - this.checkOn(); - - - setTimeout(this.move, this.travelInterval); - } - - // if elevator is empty and there are still unserved requests -> elevator decides where to go here - // picks furthest away floor in opposite direction - either external floor request or internal elevator request - setDestinationDecision() { - - const keys = [...Array.from(this.departureRequestMap.keys())]; - - //if we are at or above the weight limit don't consider external requests - if(this.currentWeight < this.weightLimit) keys.push(...Object.keys(this.externalRequestObject)); - - // if there are no requests to serve => do nothing; - if(!keys.length) { - this.currentDestination = -1; - return; - } - - if(this.currentDirection === 1) { - this.currentDestination = Number(Math.max(...keys)); - } else if(this.currentDirection === -1) { - this.currentDestination = Number(Math.min(...keys)); - } - - - this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1; - - } - - // stops elevator and boards / deboards passengers depending on their request - stop() { - - this.state = 'stopped'; - - if(this.departingPassengers.length) { - output(JSON.stringify(this.departingPassengers) + 'all got off ' + this.currentFloor); - } - - if(this.boardingPassengers.length) { - this.passengerRequestQueue.push(...this.boardingPassengers); - output(JSON.stringify(this.boardingPassengers) + ' all got on ' + this.currentFloor) - } - output('current weight' + this.currentWeight); - - this.departingPassengers = []; - this.boardingPassengers = []; - this.move = this.move.bind(this); - setTimeout(this.move, this.stopInterval); - } - - // check who is getting off the elevator while it is in transit from floor n to floor n +/- 1 - // decrements weight of passengers getting off - checkOff() { - - if(this.departureRequestMap.get(this.currentFloor) !== undefined) { - this.departingPassengers.push(...this.departureRequestMap.get(this.currentFloor)); - - this.currentWeight -= sum(this.departingPassengers); - - this.departureRequestMap.delete(this.currentFloor); - } - } - - // checks who is getting on based on direction elevator is traveling and currentWeight of elevator - checkOn() { - - if(this.externalRequestObject[this.currentFloor] !== undefined) { - // if elevator has reached destination floor it needs to change direction if the request is in the opposite direction - if(this.currentFloor === this.currentDestination && !this.externalRequestObject[this.currentFloor][this.currentDirection].length) { - this.currentDirection = this.currentDirection === 1 ? -1 : 1; - } - - const boardingArr = this.externalRequestObject[this.currentFloor][this.currentDirection]; - for(let i = boardingArr.length - 1; i >= 0; i--) { - let currentBoarder = boardingArr[i]; - if(currentBoarder + this.currentWeight <= this.weightLimit) { - this.boardingPassengers.push(currentBoarder); - boardingArr.pop(); - this.currentWeight += currentBoarder; - - } else { - console.log('over weight limit ' + this.currentWeight) - } - } - if(!boardingArr.length) this.externalRequestObject[this.currentFloor][this.currentDirection] = []; - - - // clears request Obj of current floor if there aren't any more requests on this floor - if(!this.externalRequestObject[this.currentFloor][1].length && !this.externalRequestObject[this.currentFloor][-1].length) { - delete this.externalRequestObject[this.currentFloor]; - } - - } - } - - // internal floor request sets their destination in departMap - selectFloor(floor) { - const weight = this.passengerRequestQueue.shift(); - if(this.departureRequestMap.get(floor) === undefined) { - this.departureRequestMap.set(floor, []); - } - - this.departureRequestMap.get(floor).push(weight); - this.setDestinationExternal(floor); - - } - - - // if there is an external request where our currentDestination should change - setDestinationExternal(floor) { - - if(this.currentDestination === -1) { - this.currentDestination = floor; - this.currentDirection = floor > this.currentFloor ? 1 : -1; - } else if(this.currentDirection === 1) { - if(floor > this.currentDestination) this.currentDestination = floor; - } else if(this.currentDirection === -1) { - if(floor < this.currentDestination) this.currentDestination = floor; - } - } - - - // handles external request - request(request) { - - const {currentFloor, direction, weight} = request; - if(this.externalRequestObject[currentFloor] === undefined) { - this.externalRequestObject[currentFloor] = { - 1: [], - '-1': [] - } - } - - this.externalRequestObject[currentFloor][direction].push(weight); - - // if the destination needs to be changed based on current direction it will be set here if weight allows - if(this.currentWeight < this.weightLimit) this.setDestinationExternal(currentFloor); - - - } - - // when quit is typed into console - stopProcess() { - this.quit = true; - } - - // will end when all requests have been served and all passengers are off the elevator - endProcess() { - return (!Object.keys(this.externalRequestObject).length && !this.passengerRequestQueue.length && !this.departureRequestMap.size) - } - -} - -module.exports = {Elevator}; - diff --git a/elevator/elevator.ts b/elevator/elevator.ts index eaba97a..ca6877d 100644 --- a/elevator/elevator.ts +++ b/elevator/elevator.ts @@ -6,21 +6,20 @@ import * as os from 'os'; import {ElevatorRequest, ExternalRequestObject, DirectionObject} from './types.js'; -import {output} from './functions.js' +import Output from './output.js'; + -// internal request : buttons pressed from inside the elevator by passengers -// external requets : buttons pressed on floor N going U or D const sum = (arr: number[]) => { let sum = 0; - sum = arr.reduce((a,b) => a + b); + sum = arr.reduce((a, b) => a + b); return sum; -} - - +}; +// internal request : buttons pressed from inside the elevator by passengers +// external requets : buttons pressed on floor N going U or D class Elevator { @@ -29,16 +28,17 @@ class Elevator { currentFloor: number; currentDirection: 1 | -1; currentDestination: number; - departureRequestMap: Map; - externalRequestObject: ExternalRequestObject; travelInterval: number; stopInterval: number; quit: boolean; + currentWeight: number; + weightLimit: number; + departureRequestMap: Map; + externalRequestObject: ExternalRequestObject; passengerRequestQueue: number[]; boardingPassengers: number[]; departingPassengers: number[]; - currentWeight: number; - weightLimit: number; + output: Output; constructor(floors: number) { this.floors = floors; @@ -46,23 +46,25 @@ class Elevator { this.currentFloor = 0; this.currentDirection = 1; this.currentDestination = -1; + this.travelInterval = 3000; + this.stopInterval = 1000; + this.quit = false; + this.currentWeight = 0; + this.weightLimit = 50; this.departureRequestMap = new Map(); this.externalRequestObject = {}; - this.travelInterval = 1500; - this.stopInterval = 500; - this.quit = false; this.passengerRequestQueue = []; this.boardingPassengers = []; this.departingPassengers = []; - this.currentWeight = 0; - this.weightLimit = 50; + this.output = new Output('output.txt'); } + move() { this.move = this.move.bind(this); - output('Current Floor: ' + this.currentFloor); + if(this.quit && this.endProcess()) { process.exit(); @@ -74,7 +76,8 @@ class Elevator { // if elevator is not moving and someone requests same floor to get on - if(this.state === 'stopped' && this.currentDestination === -1 && this.externalRequestObject[this.currentFloor]) { + if(this.state === 'stopped' && (this.currentDestination === -1 || this.currentDestination === this.currentFloor) + && this.externalRequestObject[this.currentFloor]) { this.checkOn(); // if elevator is not moving and has no requests - wait 1s and check for new reqeusts } else if(this.currentDestination === -1) { @@ -87,23 +90,29 @@ class Elevator { // check if anyone is getting on or off at current floor if(this.boardingPassengers.length || this.departingPassengers.length) { - output('we got on / off') + this.output.output('Stopped on floor: ' + this.currentFloor); this.stop(); return; } + // if at or above weight limit : need to reset destination to only internal requests if(this.currentWeight >= this.weightLimit) { this.setDestinationDecision(); } - + + // if there is no current destination : wait interval to see if there is a new request if(this.currentDestination === -1) { setTimeout(this.move, this.stopInterval); return; } + this.output.output('Passing floor: ' + this.currentFloor); + + // increment / decrement current floor and change state to moving : check if any board / deboard next floor this.currentFloor += this.currentDirection; this.state = 'moving'; + this.checkOff(); this.checkOn(); @@ -111,6 +120,7 @@ class Elevator { setTimeout(this.move, this.travelInterval); } + // if elevator is empty and there are still unserved requests -> elevator decides where to go here // picks furthest away floor in opposite direction - either external floor request or internal elevator request setDestinationDecision() { @@ -121,7 +131,7 @@ class Elevator { if(Object.keys(this.externalRequestObject).length) keys.push(Number(...Object.keys(this.externalRequestObject))); } - // if there are no requests to serve => do nothing; + // if there are no requests to serve if(!keys.length) { this.currentDestination = -1; return; @@ -144,14 +154,13 @@ class Elevator { this.state = 'stopped'; if(this.departingPassengers.length) { - output(JSON.stringify(this.departingPassengers) + 'all got off ' + this.currentFloor); + this.output.output(this.departingPassengers.length + ' passenger(s) got off '); } if(this.boardingPassengers.length) { this.passengerRequestQueue.push(...this.boardingPassengers); - output(JSON.stringify(this.boardingPassengers) + ' all got on ' + this.currentFloor) + this.output.output((this.boardingPassengers.length + ' passenger(s) got on ')); } - output('current weight' + this.currentWeight); this.departingPassengers = []; this.boardingPassengers = []; @@ -178,8 +187,9 @@ class Elevator { if(this.externalRequestObject[this.currentFloor] !== undefined) { // if elevator has reached destination floor it needs to change direction if the request is in the opposite direction - if(this.currentFloor === this.currentDestination && !this.externalRequestObject[this.currentFloor][this.currentDirection].length) { - this.currentDirection = this.currentDirection === 1 ? -1 : 1; + if(this.currentFloor === this.currentDestination && + !this.externalRequestObject[this.currentFloor][this.currentDirection].length) { + this.currentDirection = this.currentDirection === 1 ? -1 : 1; } const boardingArr = this.externalRequestObject[this.currentFloor][this.currentDirection]; @@ -189,9 +199,6 @@ class Elevator { this.boardingPassengers.push(currentBoarder); boardingArr.pop(); this.currentWeight += currentBoarder; - - } else { - console.log('over weight limit ' + this.currentWeight) } } if(!boardingArr.length) this.externalRequestObject[this.currentFloor][this.currentDirection] = []; @@ -207,6 +214,7 @@ class Elevator { // internal floor request sets their destination in departureRequestMap selectFloor(floor: number) { + this.output.output('Floor ' + floor + ' requested internally'); const weight = this.passengerRequestQueue.shift()!; if(this.departureRequestMap.get(floor) === undefined) { this.departureRequestMap.set(floor, []); @@ -231,23 +239,22 @@ class Elevator { } } - // handles external request request(request: ElevatorRequest) { - + const {currentFloor, direction, weight} = request; if(this.externalRequestObject[currentFloor] === undefined) { this.externalRequestObject[currentFloor] = { '1': [], '-1': [] - } as DirectionObject; + }; } + this.output.output('Floor ' + currentFloor + ' requested externally'); this.externalRequestObject[currentFloor][direction].push(weight); // if the destination needs to be changed based on current direction it will be set here if weight allows if(this.currentWeight < this.weightLimit) this.setDestinationExternal(currentFloor); - } @@ -261,7 +268,7 @@ class Elevator { return (!Object.keys(this.externalRequestObject).length && !this.passengerRequestQueue.length && !this.departureRequestMap.size && !this.boardingPassengers.length - && this.departingPassengers.length) + && !this.departingPassengers.length) } } diff --git a/elevator/functions.ts b/elevator/functions.ts index c7e8b7b..c1fee66 100644 --- a/elevator/functions.ts +++ b/elevator/functions.ts @@ -5,3 +5,9 @@ import * as os from 'os'; export const output = (txt: string) => { fs.appendFileSync('output.txt', txt + os.EOL); } + +export const sum = (arr: number[]) => { + let sum = 0; + sum = arr.reduce((a,b) => a + b); + return sum; +} diff --git a/elevator/output.ts b/elevator/output.ts new file mode 100644 index 0000000..4cd7e99 --- /dev/null +++ b/elevator/output.ts @@ -0,0 +1,26 @@ +// to write to new files for output +import * as fs from 'fs' + +// to add EOL character to file output +import * as os from 'os'; + + +class Output { + outputFileName: string; + + constructor(filename: string) { + this.outputFileName = filename; + } + + output(txt:string) { + const time = new Date(); + const hours = time.getHours(); + const minutes = time.getMinutes(); + const seconds = time.getSeconds(); + const outputString = `${hours}:${minutes}:${seconds} - ${txt}`; + fs.appendFileSync(this.outputFileName, outputString + os.EOL); + } + +} + +export default Output; \ No newline at end of file diff --git a/elevator/request.js b/elevator/request.js deleted file mode 100644 index de34ae4..0000000 --- a/elevator/request.js +++ /dev/null @@ -1,21 +0,0 @@ -class Request { - constructor(currentFloor, direction, weight = 0) { - Object.assign(this, {currentFloor, direction, weight}) - this.destination = undefined; - } - - floorRequest(floor) { - if(this.destination === undefined) { - this.destination = floor; - } - } -} - -module.exports = {Request}; - - - - - - - diff --git a/jest.config.cjs b/jest.config.cjs new file mode 100644 index 0000000..ea8780b --- /dev/null +++ b/jest.config.cjs @@ -0,0 +1,17 @@ +module.exports = { + preset: 'ts-jest', + + transform: { + '^.+\\.ts?$': 'ts-jest', + '^.+\\.(js|jsx)$': 'babel-jest' + }, + testMatch: ['*/__tests__/**/*.ts?(x)', '**/?(*.)+(test).ts?(x)'], + + testTimeout: 5000, + globals: { + 'ts-jest': { + babelConfig: true + } + }, + modulePaths: ['/build/elevator/'] +}; \ No newline at end of file diff --git a/elevator/main.js b/main.js similarity index 100% rename from elevator/main.js rename to main.js diff --git a/output.txt b/output.txt new file mode 100644 index 0000000..6959d1b --- /dev/null +++ b/output.txt @@ -0,0 +1,8 @@ +1:40:24 - Floor 1 requested externally +1:40:25 - Floor 2 requested externally +1:40:25 - Passing floor: 0 +1:40:28 - Stopped on floor: 1 +1:40:28 - 1 passengers got on +1:40:29 - Passing floor: 1 +1:40:32 - Stopped on floor: 2 +1:40:32 - 1 passengers got on diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..8bf9d03 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6272 @@ +{ + "name": "coding-challenge", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "dependencies": { + "fs": "^0.0.1-security", + "os": "^0.1.2" + }, + "devDependencies": { + "@types/jest": "^29.5.0", + "@types/node": "^18.15.10", + "jest": "^29.5.0", + "ts-jest": "^29.0.5", + "typescript": "^5.0.2" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", + "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.3.tgz", + "integrity": "sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.21.3", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.21.2", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.3", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.3", + "@babel/types": "^7.21.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/@babel/generator": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.3.tgz", + "integrity": "sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.21.3", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", + "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.3.tgz", + "integrity": "sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.3.tgz", + "integrity": "sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.21.3", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.3", + "@babel/types": "^7.21.3", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz", + "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", + "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", + "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", + "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", + "dev": true, + "dependencies": { + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", + "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.4.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", + "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", + "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", + "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.25.16" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", + "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", + "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", + "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==", + "dev": true, + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/node": { + "version": "18.15.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.10.tgz", + "integrity": "sha512-9avDaQJczATcXgfmMAW3MIWArOO7A+m90vuCFLr8AotWf8igO/mRoYukrk2cqZVtv38tHs33retzHEilM7FpeQ==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/babel-jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", + "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.5.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.5.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001470", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001470.tgz", + "integrity": "sha512-065uNwY6QtHCBOExzbV6m236DDhYCCtPmQUCoQtwkVqzud8v5QPidoMr6CoMkC2nfp6nksjttqWQRRh75LqUmA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.341", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.341.tgz", + "integrity": "sha512-R4A8VfUBQY9WmAhuqY5tjHRf5fH2AAf6vqitBOE0y6u2PgHgqHSrhZmu78dIX3fVZtjqlwJNX1i2zwC3VpHtQQ==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", + "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", + "dev": true, + "dependencies": { + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", + "import-local": "^3.0.2", + "jest-cli": "^29.5.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", + "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", + "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", + "dev": true, + "dependencies": { + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", + "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", + "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", + "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", + "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.5.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", + "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", + "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", + "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", + "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", + "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.5.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/jest-util": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", + "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", + "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.5.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.5.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/os": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/os/-/os-0.1.2.tgz", + "integrity": "sha512-ZoXJkvAnljwvc56MbvhtKVWmSkzV712k42Is2mA0+0KTSRakq5XXuXpjZjgAt9ctzl51ojhQWakQQpmOvXWfjQ==" + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pure-rand": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", + "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-jest": { + "version": "29.0.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz", + "integrity": "sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=12.20" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.0.tgz", + "integrity": "sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==", + "dev": true + }, + "@babel/core": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.3.tgz", + "integrity": "sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.21.3", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.21.2", + "@babel/helpers": "^7.21.0", + "@babel/parser": "^7.21.3", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.3", + "@babel/types": "^7.21.3", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.3.tgz", + "integrity": "sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==", + "dev": true, + "requires": { + "@babel/types": "^7.21.3", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz", + "integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==", + "dev": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/types": "^7.21.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.21.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", + "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.2", + "@babel/types": "^7.21.2" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dev": true, + "requires": { + "@babel/types": "^7.20.2" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", + "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "dev": true + }, + "@babel/helpers": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", + "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", + "dev": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.21.0", + "@babel/types": "^7.21.0" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.3.tgz", + "integrity": "sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.19.0" + } + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.3.tgz", + "integrity": "sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.21.3", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.21.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.21.3", + "@babel/types": "^7.21.3", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.21.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.3.tgz", + "integrity": "sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jest/console": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", + "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", + "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", + "dev": true, + "requires": { + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", + "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", + "dev": true, + "requires": { + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0" + } + }, + "@jest/expect": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", + "dev": true, + "requires": { + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" + } + }, + "@jest/expect-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", + "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "dev": true, + "requires": { + "jest-get-type": "^29.4.3" + } + }, + "@jest/fake-timers": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", + "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + } + }, + "@jest/globals": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", + "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" + } + }, + "@jest/reporters": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", + "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + } + }, + "@jest/schemas": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.25.16" + } + }, + "@jest/source-map": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + } + }, + "@jest/test-result": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", + "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", + "dev": true, + "requires": { + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", + "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", + "dev": true, + "requires": { + "@jest/test-result": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "slash": "^3.0.0" + } + }, + "@jest/transform": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", + "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + } + }, + "@jest/types": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@sinclair/typebox": { + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "dev": true + }, + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0" + } + }, + "@types/babel__core": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==", + "dev": true, + "requires": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "@types/node": { + "version": "18.15.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.10.tgz", + "integrity": "sha512-9avDaQJczATcXgfmMAW3MIWArOO7A+m90vuCFLr8AotWf8igO/mRoYukrk2cqZVtv38tHs33retzHEilM7FpeQ==", + "dev": true + }, + "@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", + "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", + "dev": true, + "requires": { + "@jest/transform": "^29.5.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^29.5.0", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + } + }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001470", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001470.tgz", + "integrity": "sha512-065uNwY6QtHCBOExzbV6m236DDhYCCtPmQUCoQtwkVqzud8v5QPidoMr6CoMkC2nfp6nksjttqWQRRh75LqUmA==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true + }, + "cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.341", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.341.tgz", + "integrity": "sha512-R4A8VfUBQY9WmAhuqY5tjHRf5fH2AAf6vqitBOE0y6u2PgHgqHSrhZmu78dIX3fVZtjqlwJNX1i2zwC3VpHtQQ==", + "dev": true + }, + "emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true + }, + "expect": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", + "dev": true, + "requires": { + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs": { + "version": "0.0.1-security", + "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", + "integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", + "dev": true, + "requires": { + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", + "import-local": "^3.0.2", + "jest-cli": "^29.5.0" + } + }, + "jest-changed-files": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", + "dev": true, + "requires": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + } + }, + "jest-circus": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", + "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-cli": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", + "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", + "dev": true, + "requires": { + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + } + }, + "jest-config": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", + "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + } + }, + "jest-diff": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + } + }, + "jest-docblock": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", + "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" + } + }, + "jest-environment-node": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", + "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + } + }, + "jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "dev": true + }, + "jest-haste-map": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-leak-detector": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", + "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", + "dev": true, + "requires": { + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + } + }, + "jest-matcher-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + } + }, + "jest-message-util": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.5.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-mock": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", + "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-util": "^29.5.0" + } + }, + "jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "requires": {} + }, + "jest-regex-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "dev": true + }, + "jest-resolve": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", + "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", + "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", + "dev": true, + "requires": { + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" + } + }, + "jest-runner": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", + "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", + "dev": true, + "requires": { + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + } + }, + "jest-runtime": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", + "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + } + }, + "jest-snapshot": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.5.0", + "semver": "^7.3.5" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "jest-util": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", + "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.5.0" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", + "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", + "dev": true, + "requires": { + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.5.0", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.5.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "requires": { + "tmpl": "1.0.5" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "os": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/os/-/os-0.1.2.tgz", + "integrity": "sha512-ZoXJkvAnljwvc56MbvhtKVWmSkzV712k42Is2mA0+0KTSRakq5XXuXpjZjgAt9ctzl51ojhQWakQQpmOvXWfjQ==" + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + }, + "dependencies": { + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + } + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } + } + }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "pure-rand": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", + "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "dev": true + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "ts-jest": { + "version": "29.0.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz", + "integrity": "sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + }, + "typescript": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "v8-to-istanbul": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + } + } + }, + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "requires": { + "makeerror": "1.0.12" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json index 1c37334..3ceb083 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,14 @@ "fs": "^0.0.1-security", "os": "^0.1.2" }, + "scripts" : { + "test": "jest --config jest.config.cjs --verbose --coverage --detectOpenHandles" + }, "devDependencies": { + "@types/jest": "^29.5.0", "@types/node": "^18.15.10", + "jest": "^29.5.0", + "ts-jest": "^29.0.5", "typescript": "^5.0.2" }, "type": "module" diff --git a/test/elevator.test.ts b/test/elevator.test.ts new file mode 100644 index 0000000..9f4d57e --- /dev/null +++ b/test/elevator.test.ts @@ -0,0 +1,188 @@ +// Import the Elevator class from your implementation file +import Elevator from '../elevator/elevator' +// import Elevator from '../build/elevator/elevator.js'; + +jest.useFakeTimers(); + +describe('Elevator.move', () => { + let elevator: Elevator; + + beforeEach(() => { + // Create a new Elevator instance before each test + elevator = new Elevator(10); + }); + + afterEach(() => { + jest.clearAllTimers(); + }) + + it('should move the elevator to the next floor when the current direction is 1 and current destination > current floor', () => { + elevator.currentFloor = 0; + elevator.currentDirection = 1; + elevator.currentDestination = 1; + elevator.externalRequestObject = {}; + + elevator.move(); + + expect(elevator.currentFloor).toEqual(1); + expect(elevator.state).toEqual('moving'); + expect(elevator.currentDestination).toEqual(1); + expect(elevator.currentDirection).toEqual(1); + expect(elevator.boardingPassengers).toEqual([]); + expect(elevator.departingPassengers).toEqual([]); + }); + + it('should stop the elevator and board passengers when there are external requests on the next floor', () => { + + elevator.currentFloor = 2; + elevator.currentDirection = 1; + elevator.currentDestination = 3; + elevator.externalRequestObject = { 3: { + '1': [25], + '-1': [] + } }; + + elevator.move(); + + expect(elevator.currentFloor).toEqual(3); + expect(elevator.state).toEqual('moving'); + expect(elevator.currentDestination).toEqual(3); + expect(elevator.currentDirection).toEqual(1); + expect(elevator.boardingPassengers.length).toEqual(1); + expect(elevator.departingPassengers).toEqual([]); + }); + + it('should stop the elevator and deboard/board passengers when there are passengers with a request to get off on the current floor', () => { + + elevator.currentFloor = 5; + elevator.currentDirection = 1; + elevator.currentDestination = 5; + elevator.externalRequestObject = {}; + elevator.boardingPassengers = [10,10,10]; + elevator.departingPassengers = [10]; + + elevator.move(); + + expect(elevator.currentFloor).toEqual(5); + expect(elevator.state).toEqual('stopped'); + expect(elevator.currentDestination).toEqual(-1); + expect(elevator.currentDirection).toEqual(1); + expect(elevator.boardingPassengers).toEqual([]); + expect(elevator.departingPassengers).toEqual([]); + expect(elevator.passengerRequestQueue.length).toEqual(3); + }); + + it('should not stop at next floor if there is a request to board but we are at the weight limit', () => { + + elevator.currentFloor = 4; + elevator.currentWeight = 50; + elevator.currentDirection = 1; + elevator.departureRequestMap.set(8, [10]); + elevator.currentDestination = 8; + elevator.externalRequestObject = { 5: { + '1': [25], + '-1': [] + } }; + + elevator.move(); + + expect(elevator.currentFloor).toEqual(5); + expect(elevator.state).toEqual('moving'); + expect(elevator.currentDestination).toEqual(8); + expect(elevator.currentDirection).toEqual(1); + expect(elevator.boardingPassengers).toEqual([]); + expect(elevator.departingPassengers).toEqual([]); + }); + + it('should properly track weight going on and off', () => { + + elevator.currentFloor = 4; + elevator.currentWeight = 50; + elevator.currentDirection = 1; + elevator.currentDestination = 5; + elevator.externalRequestObject= {5: {'1': [10,10,10], '-1':[]}} + elevator.departureRequestMap.set(5, [10]); + elevator.currentWeight = 20; + + elevator.move(); + + expect(elevator.currentFloor).toEqual(5); + expect(elevator.state).toEqual('moving'); + expect(elevator.currentWeight).toEqual(40); + + }); + + it('should not stop program if elevator.stop is true, it should finish requests and then stop', () => { + elevator.quit = true; + elevator.currentFloor = 4; + elevator.currentDirection = 1; + elevator.currentDestination = 5; + elevator.departureRequestMap.set(5,[10]); + + elevator.move(); + + expect(elevator.currentFloor).toEqual(5); + expect(elevator.state).toEqual('moving'); + + }) + + +}); + + + + + +describe('Elevator.setDestinationExternal', () => { + let elevator: Elevator; + + beforeEach(() => { + // Create a new Elevator instance before each test + elevator = new Elevator(10); + }); + + afterEach(() => { + jest.clearAllTimers(); + }) + + it('should set destination to higher floor if moving up', () => { + elevator.currentFloor = 0; + elevator.currentDirection = 1; + elevator.currentDestination = 4; + + elevator.setDestinationExternal(9); + + expect(elevator.currentDestination).toEqual(9); + }); + + it('should set destination to lower floor if moving down', () => { + elevator.currentFloor = 9; + elevator.currentDirection = -1; + elevator.currentDestination = 4; + + elevator.setDestinationExternal(2); + + expect(elevator.currentDestination).toEqual(2); + }); + + it('should not change destination if moving up and currentDest > new request', () => { + elevator.currentFloor = 0; + elevator.currentDirection = 1; + elevator.currentDestination = 4; + + elevator.setDestinationExternal(3); + + expect(elevator.currentDestination).toEqual(4); + }); + + it('should not change destination if moving down and currentDest < new request', () => { + elevator.currentFloor = 9; + elevator.currentDirection = -1; + elevator.currentDestination = 4; + + elevator.setDestinationExternal(5); + + expect(elevator.currentDestination).toEqual(4); + }); + +}); \ No newline at end of file From 4a1c68a8cb9077d562845162a3a3f8b731cf0668 Mon Sep 17 00:00:00 2001 From: shaysheller <24629189+shaysheller@users.noreply.github.com> Date: Tue, 28 Mar 2023 01:57:57 -0700 Subject: [PATCH 13/22] Delete main.js --- main.js | 61 --------------------------------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 main.js diff --git a/main.js b/main.js deleted file mode 100644 index 4398eec..0000000 --- a/main.js +++ /dev/null @@ -1,61 +0,0 @@ -const {Elevator} = require('./elevator'); -const {Request} = require('./request'); -const fs = require('fs'); -const readline = require('readline'); -const os = require('os'); - -const output = txt => { - fs.appendFileSync('output.txt', txt + os.EOL); -} -// Create an interface for reading from the command line -const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout -}); - - -const elevator = new Elevator(15); -elevator.move(); - -const question = () => { - - if(elevator.quit) { - if(elevator.passengerQueue.length || Object.keys(elevator.requestObj)) { - rl.question('No more outside requests at this time. Please input which floor is your destination', (answer) => { - elevator.selectFloor(Number(answer)); - question() - }) - - } else { - rl.close(); - } - } - - rl.question('What floor are you on and which direction are you going, OR which floor do you want to request?', (answer) => { - if(answer.at(-1).toLowerCase() === 'u') { - createRequest(answer.slice(0,-1), 1); - } else if (answer.at(-1).toLowerCase() === 'd') { - createRequest(answer.slice(0,-1), -1); - } else if(answer === 'quit') { - elevator.stopProcess(); - } else { - if(elevator.passengerRequestQueue.length) { - elevator.selectFloor(Number(answer)); - } - - } - question()}); -} - -// defaulting to weight of 25 -const createRequest = (floor, direction) => { - const req = new Request(Number(floor), direction, 25); - elevator.request(req); -} - - -fs.writeFileSync('output.txt', ''); -question(); - - - From 436dc71962d4e5bb4604eaab2b5ce50f55e96786 Mon Sep 17 00:00:00 2001 From: shaysheller <24629189+shaysheller@users.noreply.github.com> Date: Tue, 28 Mar 2023 01:58:06 -0700 Subject: [PATCH 14/22] Delete output.txt --- output.txt | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 output.txt diff --git a/output.txt b/output.txt deleted file mode 100644 index 6959d1b..0000000 --- a/output.txt +++ /dev/null @@ -1,8 +0,0 @@ -1:40:24 - Floor 1 requested externally -1:40:25 - Floor 2 requested externally -1:40:25 - Passing floor: 0 -1:40:28 - Stopped on floor: 1 -1:40:28 - 1 passengers got on -1:40:29 - Passing floor: 1 -1:40:32 - Stopped on floor: 2 -1:40:32 - 1 passengers got on From a12e34883287ab0ccb3be3cb6506f9abd9c5073d Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Tue, 28 Mar 2023 02:00:04 -0700 Subject: [PATCH 15/22] Updated Readme --- elevator/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/elevator/README.md b/elevator/README.md index 79f0439..23390e9 100644 --- a/elevator/README.md +++ b/elevator/README.md @@ -11,7 +11,6 @@ Create an application that simulates the operation of a simple elevator. - Elevator will stop at the closest floor first, in the direction of motion, then the next closest and so on. Any floors requested while the elevator is moving should be taken into account. - Elevator will stop at all asynchronously requested floors, only if the request is made while the elevator is at least one floor away (**e.g.** if elevator is **between** 4th and 5th floor, going up, and the 5th floor is requested at that moment, elevator will not stop at the 5th floor while going up; it will stop there while going down). - When elevator arrives at a requested floor, it waits for 1 second. It takes 3 seconds to travel between consecutive floors. - \*\*\*\* should we allow new requests to board the elevator at this time to work? I think yes - problem for later - A sensor tells the elevator its direction, next/current floor, state (stopped, moving) and if the elevator has reached its max weight limit. - Use the sensor data plus the asynchronous floor request button data to work the elevator. - Write meaningful **unit tests** that show the elevator works correctly, even if the application is not run. From 7b584ae39e2082b3163eae15215d5876dd226b0a Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Tue, 28 Mar 2023 02:05:54 -0700 Subject: [PATCH 16/22] changed quit entry from quit to q --- elevator/main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elevator/main.ts b/elevator/main.ts index 22a786e..fc1664a 100644 --- a/elevator/main.ts +++ b/elevator/main.ts @@ -34,7 +34,7 @@ const question = () => { createRequest(answer.slice(0,-1), 1); } else if (answer.at(-1)!.toLowerCase() === 'd') { createRequest(answer.slice(0,-1), -1); - } else if(answer === 'quit') { + } else if(answer.toLowerCase() === 'q') { elevator.stopProcess(); } else { if(elevator.passengerRequestQueue.length) { From 93c25eb74930609ee628963c9c8d503bb341994c Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Wed, 29 Mar 2023 22:32:50 -0700 Subject: [PATCH 17/22] Refactoring move function to make logic more clear --- build/elevator/elevator.js | 60 +++++++++++++-------------- build/elevator/main.js | 2 +- build/elevator/request.js | 13 +++++- build/test/elevator.test.js | 2 +- elevator/elevator.ts | 81 +++++++++++++++++++------------------ elevator/elevatorQueue.ts | 46 +++++++++++++++++++++ elevator/main.ts | 3 +- elevator/request.ts | 49 ++++++++++++++++++++-- elevator/types.ts | 7 +++- output.txt | 9 +++++ package-lock.json | 27 +++++++++++++ package.json | 3 +- test/elevator.test.ts | 2 +- tsconfig.json | 2 +- 14 files changed, 223 insertions(+), 83 deletions(-) create mode 100644 elevator/elevatorQueue.ts create mode 100644 output.txt diff --git a/build/elevator/elevator.js b/build/elevator/elevator.js index d707f59..189604d 100644 --- a/build/elevator/elevator.js +++ b/build/elevator/elevator.js @@ -1,4 +1,7 @@ import Output from './output.js'; +// I think that in order to limit inefficient destination checks we should use a priority queue only for departureMap. +// this way we can keep track of the max or min value depending on direction and peek it in constant time instead of creating +// a whole new array and using O(n) to find the min or max. const sum = (arr) => { let sum = 0; sum = arr.reduce((a, b) => a + b); @@ -18,7 +21,7 @@ class Elevator { this.quit = false; this.currentWeight = 0; this.weightLimit = 50; - this.departureRequestMap = new Map(); + this.departureRequestMap = new Map(); // maybe it makes sense to have this be a priority queue? this.externalRequestObject = {}; this.passengerRequestQueue = []; this.boardingPassengers = []; @@ -27,6 +30,21 @@ class Elevator { } move() { this.move = this.move.bind(this); + this.newFloorChecks(); + // if at or above weight limit : need to reset destination to only internal requests + // * can we limit this in any way? + if (this.currentWeight >= this.weightLimit) { + this.setDestinationDecision(); + } + this.output.output('Passing floor: ' + this.currentFloor); + // increment / decrement current floor and change state to moving : check if any board / deboard next floor + this.currentFloor += this.currentDirection; + this.state = 'moving'; + this.checkOff(); + this.checkOn(); + setTimeout(this.move, this.travelInterval); + } + newFloorChecks() { if (this.quit && this.endProcess()) { process.exit(); } @@ -39,47 +57,25 @@ class Elevator { if (this.state === 'stopped' && (this.currentDestination === -1 || this.currentDestination === this.currentFloor) && this.externalRequestObject[this.currentFloor]) { this.checkOn(); - // if elevator is not moving and has no requests - wait 1s and check for new reqeusts - } - else if (this.currentDestination === -1) { - setTimeout(this.move, this.stopInterval); - return; - // if we have reached the destination - check for new destination based on unserved requests - } - else if (this.currentDestination === this.currentFloor) { - this.setDestinationDecision(); } // check if anyone is getting on or off at current floor if (this.boardingPassengers.length || this.departingPassengers.length) { this.output.output('Stopped on floor: ' + this.currentFloor); - this.stop(); + this.stopAndBoard(); return; } - // if at or above weight limit : need to reset destination to only internal requests - if (this.currentWeight >= this.weightLimit) { - this.setDestinationDecision(); - } - // if there is no current destination : wait interval to see if there is a new request - if (this.currentDestination === -1) { + else if (this.currentDestination === -1) { setTimeout(this.move, this.stopInterval); return; } - this.output.output('Passing floor: ' + this.currentFloor); - // increment / decrement current floor and change state to moving : check if any board / deboard next floor - this.currentFloor += this.currentDirection; - this.state = 'moving'; - this.checkOff(); - this.checkOn(); - setTimeout(this.move, this.travelInterval); } - // if elevator is empty and there are still unserved requests -> elevator decides where to go here - // picks furthest away floor in opposite direction - either external floor request or internal elevator request + // *** use a priority queue here *** + // pick destination if elevator reached current destination or elevator reached weight limit setDestinationDecision() { - const keys = this.departureRequestMap.size ? [Number(...Array.from(this.departureRequestMap.keys()))] : []; + const keys = Array.from(this.departureRequestMap.keys()); //if we are at or above the weight limit don't consider external requests if (this.currentWeight < this.weightLimit) { - if (Object.keys(this.externalRequestObject).length) - keys.push(Number(...Object.keys(this.externalRequestObject))); + keys.push(Number(...Object.keys(this.externalRequestObject))); } // if there are no requests to serve if (!keys.length) { @@ -95,7 +91,8 @@ class Elevator { this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1; } // stops elevator and boards / deboards passengers depending on their request - stop() { + // ** maybe should add functionality to see if people made the request just too late for initial check + stopAndBoard() { this.state = 'stopped'; if (this.departingPassengers.length) { this.output.output(this.departingPassengers.length + ' passenger(s) got off '); @@ -106,7 +103,6 @@ class Elevator { } this.departingPassengers = []; this.boardingPassengers = []; - this.move = this.move.bind(this); setTimeout(this.move, this.stopInterval); } // check who is getting off the elevator while it is in transit from floor n to floor n +/- 1 @@ -156,6 +152,8 @@ class Elevator { } // if there is an external request where our currentDestination should change setDestinationExternal(floor) { + if (this.currentWeight >= this.weightLimit) + return; if (this.currentDestination === -1) { this.currentDestination = floor; this.currentDirection = floor > this.currentFloor ? 1 : -1; diff --git a/build/elevator/main.js b/build/elevator/main.js index 384319c..8a1dbdb 100644 --- a/build/elevator/main.js +++ b/build/elevator/main.js @@ -30,7 +30,7 @@ const question = () => { else if (answer.at(-1).toLowerCase() === 'd') { createRequest(answer.slice(0, -1), -1); } - else if (answer === 'quit') { + else if (answer.toLowerCase() === 'q') { elevator.stopProcess(); } else { diff --git a/build/elevator/request.js b/build/elevator/request.js index 87ddb6b..d104520 100644 --- a/build/elevator/request.js +++ b/build/elevator/request.js @@ -1,8 +1,19 @@ +// class ElevatorRequest { +// currentFloor: number; +// direction: number; +// weight: number; +// destinationFloor: undefined | number; class ElevatorRequest { constructor(currentFloor, direction, weight) { this.currentFloor = currentFloor; this.direction = direction; - this.weight = weight !== undefined ? weight : 0; + this.weight = weight; + this.destination = undefined; + } + setDestination(floor) { + if (this.destination === undefined) { + this.destination = floor; + } } } export default ElevatorRequest; diff --git a/build/test/elevator.test.js b/build/test/elevator.test.js index 85d278d..865ac7f 100644 --- a/build/test/elevator.test.js +++ b/build/test/elevator.test.js @@ -1,5 +1,5 @@ // Import the Elevator class from your implementation file -import Elevator from '../elevator/elevator'; +import Elevator from '../elevator/elevator.js'; // import Elevator from '../build/elevator/elevator.js'; jest.useFakeTimers(); describe('Elevator.move', () => { diff --git a/elevator/elevator.ts b/elevator/elevator.ts index ca6877d..589e311 100644 --- a/elevator/elevator.ts +++ b/elevator/elevator.ts @@ -4,11 +4,13 @@ import * as fs from 'fs' // to add EOL character to file output import * as os from 'os'; -import {ElevatorRequest, ExternalRequestObject, DirectionObject} from './types.js'; +import {ElevatorRequest, ExternalRequestObject, direction} from './types.js'; import Output from './output.js'; - +// I think that in order to limit inefficient destination checks we should use a priority queue only for departureMap. +// this way we can keep track of the max or min value depending on direction and peek it in constant time instead of creating +// a whole new array and using O(n) to find the min or max. const sum = (arr: number[]) => { @@ -26,7 +28,7 @@ class Elevator { floors: number; state: 'stopped' | 'moving'; currentFloor: number; - currentDirection: 1 | -1; + currentDirection: direction; currentDestination: number; travelInterval: number; stopInterval: number; @@ -51,7 +53,7 @@ class Elevator { this.quit = false; this.currentWeight = 0; this.weightLimit = 50; - this.departureRequestMap = new Map(); + this.departureRequestMap = new Map(); // maybe it makes sense to have this be a priority queue? this.externalRequestObject = {}; this.passengerRequestQueue = []; this.boardingPassengers = []; @@ -65,7 +67,29 @@ class Elevator { this.move = this.move.bind(this); + this.newFloorChecks(); + + // if at or above weight limit : need to reset destination to only internal requests + // * can we limit this in any way? + if(this.currentWeight >= this.weightLimit) { + this.setDestinationDecision(); + } + + + this.output.output('Passing floor: ' + this.currentFloor); + + // increment / decrement current floor and change state to moving : check if any board / deboard next floor + this.currentFloor += this.currentDirection; + this.state = 'moving'; + this.checkOff(); + this.checkOn(); + + + setTimeout(this.move, this.travelInterval); + } + + newFloorChecks() { if(this.quit && this.endProcess()) { process.exit(); } @@ -74,61 +98,35 @@ class Elevator { if(this.currentFloor === 0) this.currentDirection = 1; else if(this.currentFloor === this.floors) this.currentDirection = -1; - // if elevator is not moving and someone requests same floor to get on if(this.state === 'stopped' && (this.currentDestination === -1 || this.currentDestination === this.currentFloor) && this.externalRequestObject[this.currentFloor]) { this.checkOn(); - // if elevator is not moving and has no requests - wait 1s and check for new reqeusts - } else if(this.currentDestination === -1) { - setTimeout(this.move, this.stopInterval); - return; - // if we have reached the destination - check for new destination based on unserved requests - } else if(this.currentDestination === this.currentFloor) { - this.setDestinationDecision(); - } + } // check if anyone is getting on or off at current floor if(this.boardingPassengers.length || this.departingPassengers.length) { this.output.output('Stopped on floor: ' + this.currentFloor); - this.stop(); + this.stopAndBoard(); return; - } - - - // if at or above weight limit : need to reset destination to only internal requests - if(this.currentWeight >= this.weightLimit) { - this.setDestinationDecision(); - } - - // if there is no current destination : wait interval to see if there is a new request - if(this.currentDestination === -1) { + } else if(this.currentDestination === -1) { setTimeout(this.move, this.stopInterval); return; } - - this.output.output('Passing floor: ' + this.currentFloor); - - // increment / decrement current floor and change state to moving : check if any board / deboard next floor - this.currentFloor += this.currentDirection; - this.state = 'moving'; - this.checkOff(); - this.checkOn(); - - setTimeout(this.move, this.travelInterval); } - // if elevator is empty and there are still unserved requests -> elevator decides where to go here - // picks furthest away floor in opposite direction - either external floor request or internal elevator request + // *** use a priority queue here *** + + // pick destination if elevator reached current destination or elevator reached weight limit setDestinationDecision() { - const keys = this.departureRequestMap.size ? [Number(...Array.from(this.departureRequestMap.keys()))] : []; + const keys = Array.from(this.departureRequestMap.keys()); //if we are at or above the weight limit don't consider external requests if(this.currentWeight < this.weightLimit) { - if(Object.keys(this.externalRequestObject).length) keys.push(Number(...Object.keys(this.externalRequestObject))); + keys.push(Number(...Object.keys(this.externalRequestObject))); } // if there are no requests to serve @@ -149,7 +147,8 @@ class Elevator { } // stops elevator and boards / deboards passengers depending on their request - stop() { + // ** maybe should add functionality to see if people made the request just too late for initial check + stopAndBoard() { this.state = 'stopped'; @@ -164,7 +163,6 @@ class Elevator { this.departingPassengers = []; this.boardingPassengers = []; - this.move = this.move.bind(this); setTimeout(this.move, this.stopInterval); } @@ -229,6 +227,8 @@ class Elevator { // if there is an external request where our currentDestination should change setDestinationExternal(floor: number) { + if(this.currentWeight >= this.weightLimit) return; + if(this.currentDestination === -1) { this.currentDestination = floor; this.currentDirection = floor > this.currentFloor ? 1 : -1; @@ -275,3 +275,4 @@ class Elevator { export default Elevator; + diff --git a/elevator/elevatorQueue.ts b/elevator/elevatorQueue.ts new file mode 100644 index 0000000..0acd827 --- /dev/null +++ b/elevator/elevatorQueue.ts @@ -0,0 +1,46 @@ + +import { + PriorityQueue, + MinPriorityQueue, + MaxPriorityQueue, + ICompare, + IGetCompareValue, +} from '@datastructures-js/priority-queue'; + +import Request from './request.js'; +import {ElevatorRequest} from './types.js' + + + +class ElevatorQueue { + queue: PriorityQueue + + + constructor(minMax: 'min' | 'max') { + this.queue = this.buildQueue(minMax); + } + + buildQueue(minMax: 'min' | 'max') { + if(minMax === 'min') { + return new MinPriorityQueue(this.compare); + } + return new MaxPriorityQueue(this.compare); + } + + compare (request: ElevatorRequest) { + if(request.destination === undefined) { + return request.currentFloor; + } + return request.destination; + } + + + + + + + +} + +export default ElevatorQueue; + diff --git a/elevator/main.ts b/elevator/main.ts index fc1664a..627be6a 100644 --- a/elevator/main.ts +++ b/elevator/main.ts @@ -2,6 +2,7 @@ import Elevator from './elevator.js'; import ElevatorRequest from './request.js'; import * as fs from 'fs'; import * as readline from 'readline'; +import {direction} from './types.js' // Create an interface for reading from the command line @@ -46,7 +47,7 @@ const question = () => { } // defaulting to weight of 25 -const createRequest = (floor: string, direction: number) => { +const createRequest = (floor: string, direction: direction) => { const req = new ElevatorRequest(Number(floor), direction, 25); elevator.request(req); } diff --git a/elevator/request.ts b/elevator/request.ts index 283e8d9..935aec6 100644 --- a/elevator/request.ts +++ b/elevator/request.ts @@ -1,15 +1,56 @@ -class ElevatorRequest { +// class ElevatorRequest { +// currentFloor: number; +// direction: number; +// weight: number; +// destinationFloor: undefined | number; + +// constructor(currentFloor: number, direction: number, weight?:number) { +// this.currentFloor = currentFloor; +// this.direction = direction; +// this.weight = weight !== undefined ? weight : 0; +// this.destinationFloor = undefined; +// } + +// setDestination(floor: number) { +// if(this.destinationFloor === undefined) { +// this.destinationFloor = floor; +// } +// } + + +// } + +import {direction} from './types.js'; + +class ElevatorRequest { + currentFloor: number; - direction: number; + direction: direction; weight: number; + destination: undefined | number; + - constructor(currentFloor: number, direction: number, weight?:number) { + constructor(currentFloor: number, direction: direction, weight:number) { this.currentFloor = currentFloor; this.direction = direction; - this.weight = weight !== undefined ? weight : 0; + this.weight = weight; + this.destination = undefined; + } + + setDestination(floor: number) { + if(this.destination === undefined) { + this.destination = floor; + } } + + } + + + + + export default ElevatorRequest; diff --git a/elevator/types.ts b/elevator/types.ts index f75a5d4..134afab 100644 --- a/elevator/types.ts +++ b/elevator/types.ts @@ -29,6 +29,11 @@ export type DirectionObject = { export type ElevatorRequest = { currentFloor: number; - direction: number; + direction: direction; weight: number; + destination: undefined | number; + } + + +export type direction = 1 | -1; diff --git a/output.txt b/output.txt new file mode 100644 index 0000000..a6fdb54 --- /dev/null +++ b/output.txt @@ -0,0 +1,9 @@ +21:10:43 - Floor 1 requested externally +21:10:43 - Floor 2 requested externally +21:10:43 - Passing floor: 0 +21:10:43 - Floor 3 requested externally +21:10:46 - Stopped on floor: 1 +21:10:46 - 1 passenger(s) got on +21:10:47 - Passing floor: 1 +21:10:50 - Stopped on floor: 2 +21:10:50 - 1 passenger(s) got on diff --git a/package-lock.json b/package-lock.json index 8bf9d03..c4c6a8e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "packages": { "": { "dependencies": { + "@datastructures-js/priority-queue": "^6.2.0", "fs": "^0.0.1-security", "os": "^0.1.2" }, @@ -602,6 +603,19 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@datastructures-js/heap": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@datastructures-js/heap/-/heap-4.3.1.tgz", + "integrity": "sha512-au4fYa4fprREES58FnMOTFjg8lCYpSenF5tBu8C/iweMaj02rAOZUqlLUCqR3HIWzNfgTeCmAiyRHdjJVHrsIQ==" + }, + "node_modules/@datastructures-js/priority-queue": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@datastructures-js/priority-queue/-/priority-queue-6.2.0.tgz", + "integrity": "sha512-z4Nikrb3PqlYn1+2bF+LArm2kWC5kvm13E1h+HYm0exGuUEp2Av0S31tDG+h8hVIbg+FlJIzWiF/T38XIexs5w==", + "dependencies": { + "@datastructures-js/heap": "^4.3.1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -4029,6 +4043,19 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@datastructures-js/heap": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@datastructures-js/heap/-/heap-4.3.1.tgz", + "integrity": "sha512-au4fYa4fprREES58FnMOTFjg8lCYpSenF5tBu8C/iweMaj02rAOZUqlLUCqR3HIWzNfgTeCmAiyRHdjJVHrsIQ==" + }, + "@datastructures-js/priority-queue": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@datastructures-js/priority-queue/-/priority-queue-6.2.0.tgz", + "integrity": "sha512-z4Nikrb3PqlYn1+2bF+LArm2kWC5kvm13E1h+HYm0exGuUEp2Av0S31tDG+h8hVIbg+FlJIzWiF/T38XIexs5w==", + "requires": { + "@datastructures-js/heap": "^4.3.1" + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", diff --git a/package.json b/package.json index 3ceb083..472ea91 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,10 @@ { "dependencies": { + "@datastructures-js/priority-queue": "^6.2.0", "fs": "^0.0.1-security", "os": "^0.1.2" }, - "scripts" : { + "scripts": { "test": "jest --config jest.config.cjs --verbose --coverage --detectOpenHandles" }, "devDependencies": { diff --git a/test/elevator.test.ts b/test/elevator.test.ts index 9f4d57e..88bf1df 100644 --- a/test/elevator.test.ts +++ b/test/elevator.test.ts @@ -1,5 +1,5 @@ // Import the Elevator class from your implementation file -import Elevator from '../elevator/elevator' +import Elevator from '../elevator/elevator.js' // import Elevator from '../build/elevator/elevator.js'; jest.useFakeTimers(); diff --git a/tsconfig.json b/tsconfig.json index 685e6a0..7964128 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,7 +27,7 @@ /* Modules */ "module": "ESnext", /* Specify what module code is generated. */ // "rootDir": "./", /* Specify the root folder within your source files. */ - // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "nodenext", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ From 438a276192ffc53e5ed90574bde2abac40d2e523 Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Sun, 2 Apr 2023 17:11:56 -0700 Subject: [PATCH 18/22] Working on testing for elevator. Moving test folder from root to build directory --- build/elevator/elevator.js | 132 +++----- build/elevator/functions.js | 10 - build/elevator/main.js | 2 +- build/elevator/request.js | 6 - build/elevator/requestMap.js | 42 +++ build/jest.config.cjs | 11 + build/test/elevator.test.js | 232 ++++++------- build/test/requestMap.test.js | 61 ++++ coverage/clover.xml | 94 +----- coverage/coverage-final.json | 3 +- coverage/lcov-report/elevator.ts.html | 432 +++++++++--------------- coverage/lcov-report/index.html | 35 +- coverage/lcov-report/output.ts.html | 160 +++++++++ coverage/lcov-report/requestMap.ts.html | 262 ++++++++++++++ coverage/lcov.info | 159 --------- elevator/elevator.ts | 179 ++++------ elevator/elevatorQueue.ts | 46 --- elevator/functions.ts | 13 - elevator/main.ts | 2 +- elevator/request.ts | 15 +- elevator/requestMap.ts | 57 ++++ elevator/types.ts | 21 +- jest.config.cjs | 8 +- output.txt | 9 - package-lock.json | 30 +- package.json | 4 +- test/elevator.test.ts | 260 +++++++------- test/requestMap.test.ts | 61 ++++ 28 files changed, 1223 insertions(+), 1123 deletions(-) delete mode 100644 build/elevator/functions.js create mode 100644 build/elevator/requestMap.js create mode 100644 build/jest.config.cjs create mode 100644 build/test/requestMap.test.js create mode 100644 coverage/lcov-report/output.ts.html create mode 100644 coverage/lcov-report/requestMap.ts.html delete mode 100644 elevator/elevatorQueue.ts delete mode 100644 elevator/functions.ts create mode 100644 elevator/requestMap.ts create mode 100644 test/requestMap.test.ts diff --git a/build/elevator/elevator.js b/build/elevator/elevator.js index 189604d..cf87e85 100644 --- a/build/elevator/elevator.js +++ b/build/elevator/elevator.js @@ -1,7 +1,5 @@ +import RequestMap from './requestMap.js'; import Output from './output.js'; -// I think that in order to limit inefficient destination checks we should use a priority queue only for departureMap. -// this way we can keep track of the max or min value depending on direction and peek it in constant time instead of creating -// a whole new array and using O(n) to find the min or max. const sum = (arr) => { let sum = 0; sum = arr.reduce((a, b) => a + b); @@ -21,8 +19,8 @@ class Elevator { this.quit = false; this.currentWeight = 0; this.weightLimit = 50; - this.departureRequestMap = new Map(); // maybe it makes sense to have this be a priority queue? - this.externalRequestObject = {}; + this.departureRequestMap = new RequestMap(); // maybe it makes sense to have this be a priority queue? + this.externalRequestMap = new RequestMap(); this.passengerRequestQueue = []; this.boardingPassengers = []; this.departingPassengers = []; @@ -30,68 +28,59 @@ class Elevator { } move() { this.move = this.move.bind(this); - this.newFloorChecks(); - // if at or above weight limit : need to reset destination to only internal requests - // * can we limit this in any way? - if (this.currentWeight >= this.weightLimit) { - this.setDestinationDecision(); - } - this.output.output('Passing floor: ' + this.currentFloor); - // increment / decrement current floor and change state to moving : check if any board / deboard next floor - this.currentFloor += this.currentDirection; - this.state = 'moving'; - this.checkOff(); - this.checkOn(); - setTimeout(this.move, this.travelInterval); - } - newFloorChecks() { if (this.quit && this.endProcess()) { process.exit(); } - // check if elevator is inside the correct boundary - if (this.currentFloor === 0) - this.currentDirection = 1; - else if (this.currentFloor === this.floors) - this.currentDirection = -1; - // if elevator is not moving and someone requests same floor to get on - if (this.state === 'stopped' && (this.currentDestination === -1 || this.currentDestination === this.currentFloor) - && this.externalRequestObject[this.currentFloor]) { - this.checkOn(); - } // check if anyone is getting on or off at current floor if (this.boardingPassengers.length || this.departingPassengers.length) { this.output.output('Stopped on floor: ' + this.currentFloor); this.stopAndBoard(); return; } - else if (this.currentDestination === -1) { + if (this.state === 'moving') { + this.output.output('Passing floor: ' + this.currentFloor); + } + this.checkDestination(); + // increment / decrement current floor and change state to moving if there is a current destination + if (this.currentDestination !== -1) { + this.currentFloor += this.currentDirection; + this.state = 'moving'; + } + // check if anyone is getting on / off at upcoming floor + this.checkOff(); + this.checkOn(); + if (this.state === 'moving') { + setTimeout(this.move, this.travelInterval); + } + else { setTimeout(this.move, this.stopInterval); - return; } } - // *** use a priority queue here *** - // pick destination if elevator reached current destination or elevator reached weight limit - setDestinationDecision() { - const keys = Array.from(this.departureRequestMap.keys()); + // need to chagne it so we aren't taking min of -1 and another number + checkDestination() { + let min = this.departureRequestMap.min; + let max = this.departureRequestMap.max; //if we are at or above the weight limit don't consider external requests if (this.currentWeight < this.weightLimit) { - keys.push(Number(...Object.keys(this.externalRequestObject))); + if (min === -1) + min = this.externalRequestMap.min; + else if (this.externalRequestMap.min !== -1) + min = Math.min(this.externalRequestMap.min, min); + max = Math.max(this.externalRequestMap.max, max); } - // if there are no requests to serve - if (!keys.length) { + if (min === -1 && max === -1) { this.currentDestination = -1; return; } if (this.currentDirection === 1) { - this.currentDestination = Number(Math.max(...keys)); + this.currentDestination = max; } else if (this.currentDirection === -1) { - this.currentDestination = Number(Math.min(...keys)); + this.currentDestination = min; } this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1; } // stops elevator and boards / deboards passengers depending on their request - // ** maybe should add functionality to see if people made the request just too late for initial check stopAndBoard() { this.state = 'stopped'; if (this.departingPassengers.length) { @@ -103,27 +92,30 @@ class Elevator { } this.departingPassengers = []; this.boardingPassengers = []; + if (this.currentFloor === this.currentDestination) { + this.checkDestination(); + } setTimeout(this.move, this.stopInterval); } // check who is getting off the elevator while it is in transit from floor n to floor n +/- 1 // decrements weight of passengers getting off checkOff() { var _a; - if (this.departureRequestMap.get(this.currentFloor) !== undefined) { - this.departingPassengers.push(...(_a = this.departureRequestMap.get(this.currentFloor)) !== null && _a !== void 0 ? _a : []); + if (this.departureRequestMap.map.get(this.currentFloor) !== undefined) { + this.departingPassengers.push(...(_a = this.departureRequestMap.map.get(this.currentFloor)) !== null && _a !== void 0 ? _a : []); this.currentWeight -= sum(this.departingPassengers); this.departureRequestMap.delete(this.currentFloor); } } // checks who is getting on based on direction elevator is traveling and currentWeight of elevator checkOn() { - if (this.externalRequestObject[this.currentFloor] !== undefined) { + if (this.externalRequestMap.map.get(this.currentFloor) !== undefined) { // if elevator has reached destination floor it needs to change direction if the request is in the opposite direction if (this.currentFloor === this.currentDestination && - !this.externalRequestObject[this.currentFloor][this.currentDirection].length) { + !this.externalRequestMap.map.get(this.currentFloor)[this.currentDirection].length) { this.currentDirection = this.currentDirection === 1 ? -1 : 1; } - const boardingArr = this.externalRequestObject[this.currentFloor][this.currentDirection]; + const boardingArr = this.externalRequestMap.map.get(this.currentFloor)[this.currentDirection]; for (let i = boardingArr.length - 1; i >= 0; i--) { let currentBoarder = boardingArr[i]; if (currentBoarder + this.currentWeight <= this.weightLimit) { @@ -133,54 +125,35 @@ class Elevator { } } if (!boardingArr.length) - this.externalRequestObject[this.currentFloor][this.currentDirection] = []; + this.externalRequestMap.map.get(this.currentFloor)[this.currentDirection] = []; // clears request Obj of current floor if there aren't any more requests on this floor - if (!this.externalRequestObject[this.currentFloor][1].length && !this.externalRequestObject[this.currentFloor][-1].length) { - delete this.externalRequestObject[this.currentFloor]; + if (!this.externalRequestMap.map.get(this.currentFloor)[1].length && !this.externalRequestMap.map.get(this.currentFloor)[-1].length) { + this.externalRequestMap.delete(this.currentFloor); } } } // internal floor request sets their destination in departureRequestMap selectFloor(floor) { this.output.output('Floor ' + floor + ' requested internally'); + if (!this.passengerRequestQueue.length) + return; const weight = this.passengerRequestQueue.shift(); - if (this.departureRequestMap.get(floor) === undefined) { + if (this.departureRequestMap.map.get(floor) === undefined) { this.departureRequestMap.set(floor, []); } - this.departureRequestMap.get(floor).push(weight); - this.setDestinationExternal(floor); - } - // if there is an external request where our currentDestination should change - setDestinationExternal(floor) { - if (this.currentWeight >= this.weightLimit) - return; - if (this.currentDestination === -1) { - this.currentDestination = floor; - this.currentDirection = floor > this.currentFloor ? 1 : -1; - } - else if (this.currentDirection === 1) { - if (floor > this.currentDestination) - this.currentDestination = floor; - } - else if (this.currentDirection === -1) { - if (floor < this.currentDestination) - this.currentDestination = floor; - } + this.departureRequestMap.map.get(floor).push(weight); } // handles external request request(request) { const { currentFloor, direction, weight } = request; - if (this.externalRequestObject[currentFloor] === undefined) { - this.externalRequestObject[currentFloor] = { + if (this.externalRequestMap.map.get(currentFloor) === undefined) { + this.externalRequestMap.set(currentFloor, { '1': [], '-1': [] - }; + }); } + this.externalRequestMap.map.get(currentFloor)[direction].push(weight); this.output.output('Floor ' + currentFloor + ' requested externally'); - this.externalRequestObject[currentFloor][direction].push(weight); - // if the destination needs to be changed based on current direction it will be set here if weight allows - if (this.currentWeight < this.weightLimit) - this.setDestinationExternal(currentFloor); } // when quit is typed into console stopProcess() { @@ -188,10 +161,11 @@ class Elevator { } // will end when all requests have been served and all passengers are off the elevator endProcess() { - return (!Object.keys(this.externalRequestObject).length && + return (!this.externalRequestMap.map.size && !this.passengerRequestQueue.length && - !this.departureRequestMap.size && !this.boardingPassengers.length + !this.departureRequestMap.map.size && !this.boardingPassengers.length && !this.departingPassengers.length); } } export default Elevator; +// testMatch: ['*/__tests__/**/*.ts?(x)', '**/?(*.)+(test).ts?(x)'], diff --git a/build/elevator/functions.js b/build/elevator/functions.js deleted file mode 100644 index 2d9f343..0000000 --- a/build/elevator/functions.js +++ /dev/null @@ -1,10 +0,0 @@ -import * as fs from 'fs'; -import * as os from 'os'; -export const output = (txt) => { - fs.appendFileSync('output.txt', txt + os.EOL); -}; -export const sum = (arr) => { - let sum = 0; - sum = arr.reduce((a, b) => a + b); - return sum; -}; diff --git a/build/elevator/main.js b/build/elevator/main.js index 8a1dbdb..8ff28b3 100644 --- a/build/elevator/main.js +++ b/build/elevator/main.js @@ -11,7 +11,7 @@ const elevator = new Elevator(15); elevator.move(); const question = () => { if (elevator.quit) { - if (elevator.passengerRequestQueue.length || Object.keys(elevator.externalRequestObject)) { + if (elevator.passengerRequestQueue.length || Object.keys(elevator.externalRequestMap)) { rl.question('No more outside requests at this time. Please input which floor is your destination', (answer) => { elevator.selectFloor(Number(answer)); question(); diff --git a/build/elevator/request.js b/build/elevator/request.js index d104520..9fb417a 100644 --- a/build/elevator/request.js +++ b/build/elevator/request.js @@ -8,12 +8,6 @@ class ElevatorRequest { this.currentFloor = currentFloor; this.direction = direction; this.weight = weight; - this.destination = undefined; - } - setDestination(floor) { - if (this.destination === undefined) { - this.destination = floor; - } } } export default ElevatorRequest; diff --git a/build/elevator/requestMap.js b/build/elevator/requestMap.js new file mode 100644 index 0000000..99426af --- /dev/null +++ b/build/elevator/requestMap.js @@ -0,0 +1,42 @@ +// keep track of max / min +// be a normal object +class RequestMap { + constructor() { + this.map = new Map(); + this.max = -1; + this.min = -1; + } + set(key, value) { + this.map.set(key, value); + if (this.map.size === 0) { + this.min = key; + this.max = key; + } + if (key > this.max) + this.max = key; + if (key < this.min || this.min === -1) + this.min = key; + } + delete(key) { + this.map.delete(key); + if (key === this.min) + this.setMin(); + if (key === this.max) + this.setMax(); + } + setMin() { + if (!this.map.size) { + this.min = -1; + return; + } + this.min = Math.min(...Array.from(this.map.keys())); + } + setMax() { + if (!this.map.size) { + this.max = -1; + return; + } + this.max = Math.max(...Array.from(this.map.keys())); + } +} +export default RequestMap; diff --git a/build/jest.config.cjs b/build/jest.config.cjs new file mode 100644 index 0000000..d742761 --- /dev/null +++ b/build/jest.config.cjs @@ -0,0 +1,11 @@ +module.exports = { + preset: 'ts-jest', + transform: { + '^.+\\.ts?$': 'ts-jest', + '^.+\\.(js|jsx)$': 'babel-jest' + }, + testMatch: ['*/__tests__/**/*.ts?(x)', '**/?(*.)+(test).ts?(x)'], + testTimeout: 5000, + modulePaths: [''] +}; +export {}; diff --git a/build/test/elevator.test.js b/build/test/elevator.test.js index 865ac7f..11d243b 100644 --- a/build/test/elevator.test.js +++ b/build/test/elevator.test.js @@ -1,12 +1,11 @@ -// Import the Elevator class from your implementation file -import Elevator from '../elevator/elevator.js'; +// import RequestMap from '../elevator/requestMap' // import Elevator from '../build/elevator/elevator.js'; jest.useFakeTimers(); describe('Elevator.move', () => { let elevator; beforeEach(() => { // Create a new Elevator instance before each test - elevator = new Elevator(10); + elevator = new Elevator(15); }); afterEach(() => { jest.clearAllTimers(); @@ -14,8 +13,8 @@ describe('Elevator.move', () => { it('should move the elevator to the next floor when the current direction is 1 and current destination > current floor', () => { elevator.currentFloor = 0; elevator.currentDirection = 1; - elevator.currentDestination = 1; - elevator.externalRequestObject = {}; + elevator.currentDestination = 4; + // elevator.externalRequestMap.set(); elevator.move(); expect(elevator.currentFloor).toEqual(1); expect(elevator.state).toEqual('moving'); @@ -24,115 +23,116 @@ describe('Elevator.move', () => { expect(elevator.boardingPassengers).toEqual([]); expect(elevator.departingPassengers).toEqual([]); }); - it('should stop the elevator and board passengers when there are external requests on the next floor', () => { - elevator.currentFloor = 2; - elevator.currentDirection = 1; - elevator.currentDestination = 3; - elevator.externalRequestObject = { 3: { - '1': [25], - '-1': [] - } }; - elevator.move(); - expect(elevator.currentFloor).toEqual(3); - expect(elevator.state).toEqual('moving'); - expect(elevator.currentDestination).toEqual(3); - expect(elevator.currentDirection).toEqual(1); - expect(elevator.boardingPassengers.length).toEqual(1); - expect(elevator.departingPassengers).toEqual([]); - }); - it('should stop the elevator and deboard/board passengers when there are passengers with a request to get off on the current floor', () => { - elevator.currentFloor = 5; - elevator.currentDirection = 1; - elevator.currentDestination = 5; - elevator.externalRequestObject = {}; - elevator.boardingPassengers = [10, 10, 10]; - elevator.departingPassengers = [10]; - elevator.move(); - expect(elevator.currentFloor).toEqual(5); - expect(elevator.state).toEqual('stopped'); - expect(elevator.currentDestination).toEqual(-1); - expect(elevator.currentDirection).toEqual(1); - expect(elevator.boardingPassengers).toEqual([]); - expect(elevator.departingPassengers).toEqual([]); - expect(elevator.passengerRequestQueue.length).toEqual(3); - }); - it('should not stop at next floor if there is a request to board but we are at the weight limit', () => { - elevator.currentFloor = 4; - elevator.currentWeight = 50; - elevator.currentDirection = 1; - elevator.departureRequestMap.set(8, [10]); - elevator.currentDestination = 8; - elevator.externalRequestObject = { 5: { - '1': [25], - '-1': [] - } }; - elevator.move(); - expect(elevator.currentFloor).toEqual(5); - expect(elevator.state).toEqual('moving'); - expect(elevator.currentDestination).toEqual(8); - expect(elevator.currentDirection).toEqual(1); - expect(elevator.boardingPassengers).toEqual([]); - expect(elevator.departingPassengers).toEqual([]); - }); - it('should properly track weight going on and off', () => { - elevator.currentFloor = 4; - elevator.currentWeight = 50; - elevator.currentDirection = 1; - elevator.currentDestination = 5; - elevator.externalRequestObject = { 5: { '1': [10, 10, 10], '-1': [] } }; - elevator.departureRequestMap.set(5, [10]); - elevator.currentWeight = 20; - elevator.move(); - expect(elevator.currentFloor).toEqual(5); - expect(elevator.state).toEqual('moving'); - expect(elevator.currentWeight).toEqual(40); - }); - it('should not stop program if elevator.stop is true, it should finish requests and then stop', () => { - elevator.quit = true; - elevator.currentFloor = 4; - elevator.currentDirection = 1; - elevator.currentDestination = 5; - elevator.departureRequestMap.set(5, [10]); - elevator.move(); - expect(elevator.currentFloor).toEqual(5); - expect(elevator.state).toEqual('moving'); - }); -}); -describe('Elevator.setDestinationExternal', () => { - let elevator; - beforeEach(() => { - // Create a new Elevator instance before each test - elevator = new Elevator(10); - }); - afterEach(() => { - jest.clearAllTimers(); - }); - it('should set destination to higher floor if moving up', () => { - elevator.currentFloor = 0; - elevator.currentDirection = 1; - elevator.currentDestination = 4; - elevator.setDestinationExternal(9); - expect(elevator.currentDestination).toEqual(9); - }); - it('should set destination to lower floor if moving down', () => { - elevator.currentFloor = 9; - elevator.currentDirection = -1; - elevator.currentDestination = 4; - elevator.setDestinationExternal(2); - expect(elevator.currentDestination).toEqual(2); - }); - it('should not change destination if moving up and currentDest > new request', () => { - elevator.currentFloor = 0; - elevator.currentDirection = 1; - elevator.currentDestination = 4; - elevator.setDestinationExternal(3); - expect(elevator.currentDestination).toEqual(4); - }); - it('should not change destination if moving down and currentDest < new request', () => { - elevator.currentFloor = 9; - elevator.currentDirection = -1; - elevator.currentDestination = 4; - elevator.setDestinationExternal(5); - expect(elevator.currentDestination).toEqual(4); - }); + // it('should stop the elevator and board passengers when there are external requests on the next floor', () => { + // elevator.currentFloor = 2; + // elevator.currentDirection = 1; + // elevator.currentDestination = 3; + // elevator.externalRequestObject = { 3: { + // '1': [25], + // '-1': [] + // } }; + // elevator.move(); + // expect(elevator.currentFloor).toEqual(3); + // expect(elevator.state).toEqual('moving'); + // expect(elevator.currentDestination).toEqual(3); + // expect(elevator.currentDirection).toEqual(1); + // expect(elevator.boardingPassengers.length).toEqual(1); + // expect(elevator.departingPassengers).toEqual([]); + // }); + // it('should stop the elevator and deboard/board passengers when there are passengers with a request to get off on the current floor', () => { + // elevator.currentFloor = 5; + // elevator.currentDirection = 1; + // elevator.currentDestination = 5; + // elevator.externalRequestObject = {}; + // elevator.boardingPassengers = [10,10,10]; + // elevator.departingPassengers = [10]; + // elevator.move(); + // expect(elevator.currentFloor).toEqual(5); + // expect(elevator.state).toEqual('stopped'); + // expect(elevator.currentDestination).toEqual(-1); + // expect(elevator.currentDirection).toEqual(1); + // expect(elevator.boardingPassengers).toEqual([]); + // expect(elevator.departingPassengers).toEqual([]); + // expect(elevator.passengerRequestQueue.length).toEqual(3); + // }); + // it('should not stop at next floor if there is a request to board but we are at the weight limit', () => { + // elevator.currentFloor = 4; + // elevator.currentWeight = 50; + // elevator.currentDirection = 1; + // elevator.departureRequestMap.set(8, [10]); + // elevator.currentDestination = 8; + // elevator.externalRequestObject = { 5: { + // '1': [25], + // '-1': [] + // } }; + // elevator.move(); + // expect(elevator.currentFloor).toEqual(5); + // expect(elevator.state).toEqual('moving'); + // expect(elevator.currentDestination).toEqual(8); + // expect(elevator.currentDirection).toEqual(1); + // expect(elevator.boardingPassengers).toEqual([]); + // expect(elevator.departingPassengers).toEqual([]); + // }); + // it('should properly track weight going on and off', () => { + // elevator.currentFloor = 4; + // elevator.currentWeight = 50; + // elevator.currentDirection = 1; + // elevator.currentDestination = 5; + // elevator.externalRequestObject= {5: {'1': [10,10,10], '-1':[]}} + // elevator.departureRequestMap.set(5, [10]); + // elevator.currentWeight = 20; + // elevator.move(); + // expect(elevator.currentFloor).toEqual(5); + // expect(elevator.state).toEqual('moving'); + // expect(elevator.currentWeight).toEqual(40); + // }); + // it('should not stop program if elevator.stop is true, it should finish requests and then stop', () => { + // elevator.quit = true; + // elevator.currentFloor = 4; + // elevator.currentDirection = 1; + // elevator.currentDestination = 5; + // elevator.departureRequestMap.set(5,[10]); + // elevator.move(); + // expect(elevator.currentFloor).toEqual(5); + // expect(elevator.state).toEqual('moving'); + // }) + // }); + // describe('Elevator.setDestinationExternal', () => { + // let elevator: Elevator; + // beforeEach(() => { + // // Create a new Elevator instance before each test + // elevator = new Elevator(10); + // }); + // afterEach(() => { + // jest.clearAllTimers(); + // }) + // it('should set destination to higher floor if moving up', () => { + // elevator.currentFloor = 0; + // elevator.currentDirection = 1; + // elevator.currentDestination = 4; + // elevator.setDestinationExternal(9); + // expect(elevator.currentDestination).toEqual(9); + // }); + // it('should set destination to lower floor if moving down', () => { + // elevator.currentFloor = 9; + // elevator.currentDirection = -1; + // elevator.currentDestination = 4; + // elevator.setDestinationExternal(2); + // expect(elevator.currentDestination).toEqual(2); + // }); + // it('should not change destination if moving up and currentDest > new request', () => { + // elevator.currentFloor = 0; + // elevator.currentDirection = 1; + // elevator.currentDestination = 4; + // elevator.setDestinationExternal(3); + // expect(elevator.currentDestination).toEqual(4); + // }); + // it('should not change destination if moving down and currentDest < new request', () => { + // elevator.currentFloor = 9; + // elevator.currentDirection = -1; + // elevator.currentDestination = 4; + // elevator.setDestinationExternal(5); + // expect(elevator.currentDestination).toEqual(4); + // }); }); +export {}; diff --git a/build/test/requestMap.test.js b/build/test/requestMap.test.js new file mode 100644 index 0000000..980c64e --- /dev/null +++ b/build/test/requestMap.test.js @@ -0,0 +1,61 @@ +import RequestMap from '../elevator/requestMap.js' + + +describe('RequestMap', () => { + let requestMap = new RequestMap(); + beforeEach(() => { + // Create a new Elevator instance before each test + let requestMap = new RequestMap(); + }); + + it('both max and min should be -1 if there requestMap.map size = 0', () => { + expect(requestMap.map.size).toBe(0); + expect(requestMap.min).toBe(-1) + expect(requestMap.max).toBe(-1) + }); + + it('both max and min should be -1 if item is removed to make size = 0', () => { + requestMap.set(1,1); + requestMap.delete(1); + expect(requestMap.min).toBe(-1) + expect(requestMap.max).toBe(-1) + }); + + it('should correctly set max/min when a higher number is added', () => { + requestMap.set(1,1); + requestMap.set(2,1); + + expect(requestMap.max).toEqual(2); + expect(requestMap.min).toEqual(1); + + }) + + it('should correctly set min/min when a lower number is added', () => { + requestMap.set(4,1); + requestMap.set(3,1); + + expect(requestMap.min).toEqual(3); + expect(requestMap.max).toEqual(4); + + }) + + it('min should be reset to correct number if current min is deleted and size !== 0', () => { + requestMap.set(1,1); + requestMap.set(2,1) + requestMap.delete(1); + expect(requestMap.min).toBe(2) + expect(requestMap.max).toBe(2) + }); + + it('max should be reset to correct number if current max is removed and size !== 0', () => { + requestMap.set(1,1); + requestMap.set(2,1) + requestMap.delete(2); + expect(requestMap.min).toBe(1) + expect(requestMap.max).toBe(1) + }); + + + + +}); \ No newline at end of file diff --git a/coverage/clover.xml b/coverage/clover.xml index e4dd495..9c5f27a 100644 --- a/coverage/clover.xml +++ b/coverage/clover.xml @@ -1,94 +1,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json index 941977f..0967ef4 100644 --- a/coverage/coverage-final.json +++ b/coverage/coverage-final.json @@ -1,2 +1 @@ -{"/Users/shaysheller/Desktop/coding-challenge/elevator/elevator.ts": {"path":"/Users/shaysheller/Desktop/coding-challenge/elevator/elevator.ts","statementMap":{"0":{"start":{"line":2,"column":0},"end":{"line":2,"column":null}},"1":{"start":{"line":5,"column":0},"end":{"line":5,"column":null}},"2":{"start":{"line":11,"column":16},"end":{"line":13,"column":1}},"3":{"start":{"line":12,"column":2},"end":{"line":12,"column":null}},"4":{"start":{"line":14,"column":13},"end":{"line":18,"column":1}},"5":{"start":{"line":15,"column":12},"end":{"line":15,"column":13}},"6":{"start":{"line":16,"column":2},"end":{"line":16,"column":null}},"7":{"start":{"line":16,"column":29},"end":{"line":16,"column":34}},"8":{"start":{"line":17,"column":2},"end":{"line":17,"column":null}},"9":{"start":{"line":43,"column":4},"end":{"line":43,"column":null}},"10":{"start":{"line":44,"column":4},"end":{"line":44,"column":null}},"11":{"start":{"line":45,"column":4},"end":{"line":45,"column":null}},"12":{"start":{"line":46,"column":4},"end":{"line":46,"column":null}},"13":{"start":{"line":47,"column":4},"end":{"line":47,"column":null}},"14":{"start":{"line":48,"column":4},"end":{"line":48,"column":null}},"15":{"start":{"line":49,"column":4},"end":{"line":49,"column":null}},"16":{"start":{"line":50,"column":4},"end":{"line":50,"column":null}},"17":{"start":{"line":51,"column":4},"end":{"line":51,"column":null}},"18":{"start":{"line":52,"column":4},"end":{"line":52,"column":null}},"19":{"start":{"line":53,"column":4},"end":{"line":53,"column":null}},"20":{"start":{"line":54,"column":4},"end":{"line":54,"column":null}},"21":{"start":{"line":55,"column":4},"end":{"line":55,"column":null}},"22":{"start":{"line":56,"column":4},"end":{"line":56,"column":null}},"23":{"start":{"line":57,"column":4},"end":{"line":57,"column":null}},"24":{"start":{"line":63,"column":4},"end":{"line":63,"column":null}},"25":{"start":{"line":64,"column":4},"end":{"line":64,"column":null}},"26":{"start":{"line":67,"column":6},"end":{"line":67,"column":null}},"27":{"start":{"line":71,"column":4},"end":{"line":72,"column":null}},"28":{"start":{"line":71,"column":32},"end":{"line":71,"column":58}},"29":{"start":{"line":72,"column":9},"end":{"line":72,"column":null}},"30":{"start":{"line":72,"column":47},"end":{"line":72,"column":null}},"31":{"start":{"line":78,"column":6},"end":{"line":78,"column":null}},"32":{"start":{"line":81,"column":6},"end":{"line":81,"column":null}},"33":{"start":{"line":82,"column":6},"end":{"line":82,"column":null}},"34":{"start":{"line":85,"column":8},"end":{"line":85,"column":null}},"35":{"start":{"line":90,"column":6},"end":{"line":90,"column":null}},"36":{"start":{"line":91,"column":6},"end":{"line":91,"column":null}},"37":{"start":{"line":92,"column":6},"end":{"line":92,"column":null}},"38":{"start":{"line":97,"column":6},"end":{"line":97,"column":null}},"39":{"start":{"line":102,"column":6},"end":{"line":102,"column":null}},"40":{"start":{"line":103,"column":6},"end":{"line":103,"column":null}},"41":{"start":{"line":107,"column":4},"end":{"line":107,"column":null}},"42":{"start":{"line":108,"column":4},"end":{"line":108,"column":null}},"43":{"start":{"line":109,"column":4},"end":{"line":109,"column":null}},"44":{"start":{"line":110,"column":4},"end":{"line":110,"column":null}},"45":{"start":{"line":113,"column":4},"end":{"line":113,"column":null}},"46":{"start":{"line":121,"column":17},"end":{"line":121,"column":110}},"47":{"start":{"line":124,"column":6},"end":{"line":124,"column":null}},"48":{"start":{"line":124,"column":57},"end":{"line":124,"column":null}},"49":{"start":{"line":129,"column":6},"end":{"line":129,"column":null}},"50":{"start":{"line":130,"column":6},"end":{"line":130,"column":null}},"51":{"start":{"line":134,"column":6},"end":{"line":134,"column":null}},"52":{"start":{"line":136,"column":6},"end":{"line":136,"column":null}},"53":{"start":{"line":140,"column":4},"end":{"line":140,"column":null}},"54":{"start":{"line":147,"column":4},"end":{"line":147,"column":null}},"55":{"start":{"line":150,"column":6},"end":{"line":150,"column":null}},"56":{"start":{"line":154,"column":6},"end":{"line":154,"column":null}},"57":{"start":{"line":155,"column":6},"end":{"line":155,"column":null}},"58":{"start":{"line":158,"column":4},"end":{"line":158,"column":null}},"59":{"start":{"line":159,"column":4},"end":{"line":159,"column":null}},"60":{"start":{"line":160,"column":4},"end":{"line":160,"column":null}},"61":{"start":{"line":161,"column":4},"end":{"line":161,"column":null}},"62":{"start":{"line":169,"column":6},"end":{"line":169,"column":null}},"63":{"start":{"line":171,"column":6},"end":{"line":171,"column":null}},"64":{"start":{"line":173,"column":6},"end":{"line":173,"column":null}},"65":{"start":{"line":185,"column":10},"end":{"line":185,"column":null}},"66":{"start":{"line":188,"column":26},"end":{"line":188,"column":94}},"67":{"start":{"line":189,"column":18},"end":{"line":189,"column":40}},"68":{"start":{"line":190,"column":29},"end":{"line":190,"column":43}},"69":{"start":{"line":192,"column":10},"end":{"line":192,"column":null}},"70":{"start":{"line":193,"column":10},"end":{"line":193,"column":null}},"71":{"start":{"line":194,"column":10},"end":{"line":194,"column":null}},"72":{"start":{"line":197,"column":6},"end":{"line":197,"column":null}},"73":{"start":{"line":197,"column":30},"end":{"line":197,"column":null}},"74":{"start":{"line":202,"column":10},"end":{"line":202,"column":null}},"75":{"start":{"line":210,"column":19},"end":{"line":210,"column":54}},"76":{"start":{"line":212,"column":6},"end":{"line":212,"column":null}},"77":{"start":{"line":215,"column":4},"end":{"line":215,"column":null}},"78":{"start":{"line":216,"column":4},"end":{"line":216,"column":null}},"79":{"start":{"line":225,"column":6},"end":{"line":225,"column":null}},"80":{"start":{"line":226,"column":6},"end":{"line":226,"column":null}},"81":{"start":{"line":228,"column":6},"end":{"line":228,"column":null}},"82":{"start":{"line":228,"column":42},"end":{"line":228,"column":null}},"83":{"start":{"line":230,"column":6},"end":{"line":230,"column":null}},"84":{"start":{"line":230,"column":42},"end":{"line":230,"column":null}},"85":{"start":{"line":237,"column":46},"end":{"line":237,"column":53}},"86":{"start":{"line":239,"column":6},"end":{"line":242,"column":null}},"87":{"start":{"line":245,"column":4},"end":{"line":245,"column":null}},"88":{"start":{"line":248,"column":4},"end":{"line":248,"column":null}},"89":{"start":{"line":248,"column":46},"end":{"line":248,"column":null}},"90":{"start":{"line":254,"column":4},"end":{"line":254,"column":null}},"91":{"start":{"line":259,"column":4},"end":{"line":262,"column":null}},"92":{"start":{"line":267,"column":0},"end":{"line":267,"column":null}}},"fnMap":{"0":{"name":"(anonymous_6)","decl":{"start":{"line":11,"column":16},"end":{"line":11,"column":27}},"loc":{"start":{"line":11,"column":31},"end":{"line":13,"column":1}}},"1":{"name":"(anonymous_7)","decl":{"start":{"line":14,"column":13},"end":{"line":14,"column":26}},"loc":{"start":{"line":14,"column":30},"end":{"line":18,"column":1}}},"2":{"name":"(anonymous_8)","decl":{"start":{"line":16,"column":19},"end":{"line":16,"column":20}},"loc":{"start":{"line":16,"column":29},"end":{"line":16,"column":34}}},"3":{"name":"(anonymous_9)","decl":{"start":{"line":42,"column":2},"end":{"line":42,"column":14}},"loc":{"start":{"line":42,"column":28},"end":{"line":58,"column":null}}},"4":{"name":"(anonymous_10)","decl":{"start":{"line":61,"column":2},"end":{"line":61,"column":6}},"loc":{"start":{"line":61,"column":6},"end":{"line":114,"column":null}}},"5":{"name":"(anonymous_11)","decl":{"start":{"line":119,"column":2},"end":{"line":119,"column":24}},"loc":{"start":{"line":119,"column":24},"end":{"line":142,"column":null}}},"6":{"name":"(anonymous_12)","decl":{"start":{"line":145,"column":2},"end":{"line":145,"column":6}},"loc":{"start":{"line":145,"column":6},"end":{"line":162,"column":null}}},"7":{"name":"(anonymous_13)","decl":{"start":{"line":166,"column":2},"end":{"line":166,"column":10}},"loc":{"start":{"line":166,"column":10},"end":{"line":176,"column":null}}},"8":{"name":"(anonymous_14)","decl":{"start":{"line":179,"column":2},"end":{"line":179,"column":9}},"loc":{"start":{"line":179,"column":9},"end":{"line":206,"column":null}}},"9":{"name":"(anonymous_15)","decl":{"start":{"line":209,"column":2},"end":{"line":209,"column":13}},"loc":{"start":{"line":209,"column":27},"end":{"line":218,"column":null}}},"10":{"name":"(anonymous_16)","decl":{"start":{"line":222,"column":2},"end":{"line":222,"column":24}},"loc":{"start":{"line":222,"column":38},"end":{"line":232,"column":null}}},"11":{"name":"(anonymous_17)","decl":{"start":{"line":235,"column":2},"end":{"line":235,"column":9}},"loc":{"start":{"line":235,"column":34},"end":{"line":250,"column":null}}},"12":{"name":"(anonymous_18)","decl":{"start":{"line":253,"column":2},"end":{"line":253,"column":13}},"loc":{"start":{"line":253,"column":13},"end":{"line":255,"column":null}}},"13":{"name":"(anonymous_19)","decl":{"start":{"line":258,"column":2},"end":{"line":258,"column":12}},"loc":{"start":{"line":258,"column":12},"end":{"line":263,"column":null}}}},"branchMap":{"0":{"loc":{"start":{"line":66,"column":7},"end":{"line":66,"column":37}},"type":"binary-expr","locations":[{"start":{"line":66,"column":7},"end":{"line":66,"column":16}},{"start":{"line":66,"column":20},"end":{"line":66,"column":37}}]},"1":{"loc":{"start":{"line":71,"column":4},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":71,"column":4},"end":{"line":72,"column":null}},{"start":{"line":72,"column":9},"end":{"line":72,"column":null}}]},"2":{"loc":{"start":{"line":72,"column":9},"end":{"line":72,"column":null}},"type":"if","locations":[{"start":{"line":72,"column":9},"end":{"line":72,"column":null}}]},"3":{"loc":{"start":{"line":76,"column":7},"end":{"line":77,"column":52}},"type":"binary-expr","locations":[{"start":{"line":76,"column":7},"end":{"line":76,"column":31}},{"start":{"line":76,"column":36},"end":{"line":76,"column":66}},{"start":{"line":76,"column":70},"end":{"line":76,"column":115}},{"start":{"line":77,"column":7},"end":{"line":77,"column":52}}]},"4":{"loc":{"start":{"line":89,"column":7},"end":{"line":89,"column":72}},"type":"binary-expr","locations":[{"start":{"line":89,"column":7},"end":{"line":89,"column":37}},{"start":{"line":89,"column":41},"end":{"line":89,"column":72}}]},"5":{"loc":{"start":{"line":121,"column":17},"end":{"line":121,"column":110}},"type":"cond-expr","locations":[{"start":{"line":121,"column":49},"end":{"line":121,"column":105}},{"start":{"line":121,"column":108},"end":{"line":121,"column":110}}]},"6":{"loc":{"start":{"line":124,"column":6},"end":{"line":124,"column":null}},"type":"if","locations":[{"start":{"line":124,"column":6},"end":{"line":124,"column":null}}]},"7":{"loc":{"start":{"line":140,"column":28},"end":{"line":140,"column":80}},"type":"cond-expr","locations":[{"start":{"line":140,"column":74},"end":{"line":140,"column":75}},{"start":{"line":140,"column":78},"end":{"line":140,"column":80}}]},"8":{"loc":{"start":{"line":169,"column":39},"end":{"line":169,"column":92}},"type":"cond-expr","locations":[{"start":{"line":169,"column":86},"end":{"line":169,"column":90}},{"start":{"line":169,"column":90},"end":{"line":169,"column":92}}]},"9":{"loc":{"start":{"line":169,"column":39},"end":{"line":169,"column":90}},"type":"binary-expr","locations":[{"start":{"line":169,"column":39},"end":{"line":169,"column":90}},{"start":{"line":169,"column":86},"end":{"line":169,"column":90}}]},"10":{"loc":{"start":{"line":183,"column":9},"end":{"line":184,"column":84}},"type":"binary-expr","locations":[{"start":{"line":183,"column":9},"end":{"line":183,"column":54}},{"start":{"line":184,"column":8},"end":{"line":184,"column":84}}]},"11":{"loc":{"start":{"line":185,"column":34},"end":{"line":185,"column":70}},"type":"cond-expr","locations":[{"start":{"line":185,"column":64},"end":{"line":185,"column":66}},{"start":{"line":185,"column":69},"end":{"line":185,"column":70}}]},"12":{"loc":{"start":{"line":197,"column":6},"end":{"line":197,"column":null}},"type":"if","locations":[{"start":{"line":197,"column":6},"end":{"line":197,"column":null}}]},"13":{"loc":{"start":{"line":201,"column":9},"end":{"line":201,"column":126}},"type":"binary-expr","locations":[{"start":{"line":201,"column":9},"end":{"line":201,"column":65}},{"start":{"line":201,"column":69},"end":{"line":201,"column":126}}]},"14":{"loc":{"start":{"line":226,"column":30},"end":{"line":226,"column":64}},"type":"cond-expr","locations":[{"start":{"line":226,"column":58},"end":{"line":226,"column":59}},{"start":{"line":226,"column":62},"end":{"line":226,"column":64}}]},"15":{"loc":{"start":{"line":228,"column":6},"end":{"line":228,"column":null}},"type":"if","locations":[{"start":{"line":228,"column":6},"end":{"line":228,"column":null}}]},"16":{"loc":{"start":{"line":230,"column":6},"end":{"line":230,"column":null}},"type":"if","locations":[{"start":{"line":230,"column":6},"end":{"line":230,"column":null}}]},"17":{"loc":{"start":{"line":248,"column":4},"end":{"line":248,"column":null}},"type":"if","locations":[{"start":{"line":248,"column":4},"end":{"line":248,"column":null}}]},"18":{"loc":{"start":{"line":259,"column":12},"end":{"line":262,"column":39}},"type":"binary-expr","locations":[{"start":{"line":259,"column":12},"end":{"line":259,"column":59}},{"start":{"line":260,"column":4},"end":{"line":260,"column":38}},{"start":{"line":261,"column":4},"end":{"line":261,"column":34}},{"start":{"line":261,"column":38},"end":{"line":261,"column":69}},{"start":{"line":262,"column":7},"end":{"line":262,"column":39}}]}},"s":{"0":1,"1":1,"2":1,"3":9,"4":1,"5":2,"6":2,"7":0,"8":2,"9":10,"10":10,"11":10,"12":10,"13":10,"14":10,"15":10,"16":10,"17":10,"18":10,"19":10,"20":10,"21":10,"22":10,"23":10,"24":6,"25":6,"26":0,"27":6,"28":1,"29":5,"30":0,"31":0,"32":0,"33":0,"34":1,"35":1,"36":1,"37":1,"38":1,"39":0,"40":0,"41":5,"42":5,"43":5,"44":5,"45":5,"46":2,"47":1,"48":0,"49":1,"50":1,"51":1,"52":0,"53":1,"54":1,"55":1,"56":1,"57":1,"58":1,"59":1,"60":1,"61":1,"62":2,"63":2,"64":2,"65":0,"66":3,"67":3,"68":5,"69":4,"70":4,"71":4,"72":3,"73":2,"74":2,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":2,"82":1,"83":2,"84":1,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":1,"92":1},"f":{"0":9,"1":2,"2":0,"3":10,"4":6,"5":2,"6":1,"7":5,"8":5,"9":0,"10":4,"11":0,"12":0,"13":1},"b":{"0":[6,1],"1":[1,5],"2":[0],"3":[6,6,6,1],"4":[6,5],"5":[1,1],"6":[0],"7":[1,0],"8":[2,0],"9":[2,2],"10":[3,2],"11":[0,0],"12":[2],"13":[3,2],"14":[0,0],"15":[1],"16":[1],"17":[0],"18":[1,1,1,0,0]}} -} +{} diff --git a/coverage/lcov-report/elevator.ts.html b/coverage/lcov-report/elevator.ts.html index 802910c..f298086 100644 --- a/coverage/lcov-report/elevator.ts.html +++ b/coverage/lcov-report/elevator.ts.html @@ -23,30 +23,30 @@

All files elevator.ts

- 75.26% + 39.02% Statements - 70/93 + 32/82
- 70.27% + 21.42% Branches - 26/37 + 6/28
- 71.42% + 41.66% Functions - 10/14 + 5/12
- 77.64% + 40.25% Lines - 66/85 + 31/77
@@ -61,7 +61,7 @@

All files elevator.ts

-
+
1 2 @@ -297,57 +297,14 @@

All files elevator.ts

232 233 234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269
  +235  1x -  -  -1x -  -  -  -  -  1x -9x   1x -2x -2x -2x +  +  +        @@ -373,88 +330,65 @@

All files elevator.ts

      -10x -10x -10x -10x -10x -10x -10x -10x -10x -10x -10x -10x -10x -10x -10x   +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x         -6x -6x +1x             -6x -5x -  -  -  -      -  -          -1x -  -  -  -  -1x -1x -1x -    +      1x       -            -5x -5x -5x -5x -  -  -5x -  +1x +1x       +    +1x     -2x     -1x       @@ -465,49 +399,47 @@

All files elevator.ts

    1x -    -  -  -  1x       +1x +1x       -1x +    +    -1x   +      -1x -1x     -1x -1x -1x -1x     +      +        -2x +  +    -2x   -2x +  +      +      +        @@ -516,37 +448,35 @@

All files elevator.ts

      +  +      -3x -3x -5x -  -4x -4x -4x     -3x         -2x     +      +  +  +    +  +  +          -        -        @@ -554,31 +484,32 @@

All files elevator.ts

      +      +      -2x +    -2x   +            -          +        -  -      +        @@ -589,7 +520,7 @@

All files elevator.ts

      -1x +        @@ -599,23 +530,15 @@

All files elevator.ts

  1x   - 
// to write to new files for output 
-import * as fs from 'fs'
- 
-// to add EOL character to file output
-import * as os from 'os';
- 
-import {ElevatorRequest, ExternalRequestObject, DirectionObject} from './types.js';
- 
-// import {output, sum} from './functions.js'
+ 
+ 
import {ElevatorRequest, DirectionObject, direction} from './types';
+import RequestMap from './requestMap';
+import Output from './output';
  
-const output = (txt: string) => {
-  fs.appendFileSync('output.txt', txt + os.EOL);
-};
-const sum = (arr: number[]) => {
-  let sum = 0;
-  sum = arr.reduce((a, b) => a + b);
-  return sum;
+const sum = (arr: number[]) => {
+  let sum = 0;
+  sum = arr.reduce((a, b) => a + b);
+  return sum;
 };
  
  
@@ -627,18 +550,19 @@ 

All files elevator.ts

floors: number; state: 'stopped' | 'moving'; currentFloor: number; - currentDirection: 1 | -1; + currentDirection: direction; currentDestination: number; - departureRequestMap: Map<number, number[]>; - externalRequestObject: ExternalRequestObject; travelInterval: number; stopInterval: number; quit: boolean; + currentWeight: number; + weightLimit: number; + departureRequestMap: RequestMap<number[]>; + externalRequestMap: RequestMap<DirectionObject>; passengerRequestQueue: number[]; boardingPassengers: number[]; departingPassengers: number[]; - currentWeight: number; - weightLimit: number; + output: Output;   constructor(floors: number) { this.floors = floors; @@ -646,161 +570,147 @@

All files elevator.ts

this.currentFloor = 0; this.currentDirection = 1; this.currentDestination = -1; - this.departureRequestMap = new Map(); - this.externalRequestObject = {}; this.travelInterval = 3000; this.stopInterval = 1000; this.quit = false; + this.currentWeight = 0; + this.weightLimit = 50; + this.departureRequestMap = new RequestMap<number[]>();// maybe it makes sense to have this be a priority queue? + this.externalRequestMap = new RequestMap<DirectionObject>(); this.passengerRequestQueue = []; this.boardingPassengers = []; this.departingPassengers = []; - this.currentWeight = 0; - this.weightLimit = 50; + this.output = new Output('output.txt'); } -    move() {   this.move = this.move.bind(this); - output('Current Floor: ' + this.currentFloor);   - if(this.quit && this.endProcess()) { + if(this.quit && this.endProcess()) { process.exit(); } -  - // check if elevator is inside the correct boundary - if(this.currentFloor === 0) this.currentDirection = 1; - else Iif(this.currentFloor === this.floors) this.currentDirection = -1; -  - // if elevator is not moving and someone requests same floor to get on - if(this.state === 'stopped' && (this.currentDestination === -1 || this.currentDestination === this.currentFloor) - && this.externalRequestObject[this.currentFloor]) { - this.checkOn(); - // if elevator is not moving and has no requests - wait 1s and check for new reqeusts - } else if(this.currentDestination === -1) { - setTimeout(this.move, this.stopInterval); - return; - // if we have reached the destination - check for new destination based on unserved requests - } else if(this.currentDestination === this.currentFloor) { - this.setDestinationDecision(); - } - // check if anyone is getting on or off at current floor if(this.boardingPassengers.length || this.departingPassengers.length) { - output('we got on / off') - this.stop(); - return; - } + this.output.output('Stopped on floor: ' + this.currentFloor); + this.stopAndBoard(); + return; + }   - // if at or above weight limit : need to reset destination to only internal requests - if(this.currentWeight >= this.weightLimit) { - this.setDestinationDecision(); + if(this.state === 'moving') { + this.output.output('Passing floor: ' + this.currentFloor); }   - // if there is no current destination : wait interval to see if there is a new request - if(this.currentDestination === -1) { - setTimeout(this.move, this.stopInterval); - return; + this.checkDestination(); + + // increment / decrement current floor and change state to moving if there is a current destination + if(this.currentDestination !== -1) { + this.currentFloor += this.currentDirection; + this.state = 'moving'; } - - // increment / decrement current floor and change state to moving : check if any board / deboard next floor - this.currentFloor += this.currentDirection; - this.state = 'moving'; +  + // check if anyone is getting on / off at upcoming floor this.checkOff(); this.checkOn(); +  + if(this.state === 'moving') { + setTimeout(this.move, this.travelInterval); + } else { + setTimeout(this.move, this.stopInterval); + } - setTimeout(this.move, this.travelInterval); }     - // if elevator is empty and there are still unserved requests -> elevator decides where to go here - // picks furthest away floor in opposite direction - either external floor request or internal elevator request - setDestinationDecision() { + // need to chagne it so we aren't taking min of -1 and another number + checkDestination() {   - const keys = this.departureRequestMap.size ? [Number(...Array.from(this.departureRequestMap.keys()))] : []; + let min = this.departureRequestMap.min; + let max = this.departureRequestMap.max; + //if we are at or above the weight limit don't consider external requests if(this.currentWeight < this.weightLimit) { - Iif(Object.keys(this.externalRequestObject).length) keys.push(Number(...Object.keys(this.externalRequestObject))); + if(min === -1) min = this.externalRequestMap.min; + else IEif (this.externalRequestMap.min !== -1) min = Math.min(this.externalRequestMap.min, min); + max = Math.max(this.externalRequestMap.max, max); } - - // if there are no requests to serve - if(!keys.length) { - this.currentDestination = -1; +  + if(min === -1 && max === -1) { + this.currentDestination = -1; return; }   if(this.currentDirection === 1) { - this.currentDestination = Number(Math.max(...keys)); + this.currentDestination = max; } else if(this.currentDirection === -1) { - this.currentDestination = Number(Math.min(...keys)); + this.currentDestination = min; }   -  - this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1; + this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1;   }   // stops elevator and boards / deboards passengers depending on their request - stop() { + stopAndBoard() { - this.state = 'stopped'; + this.state = 'stopped';   if(this.departingPassengers.length) { - output(JSON.stringify(this.departingPassengers) + 'all got off ' + this.currentFloor); + this.output.output(this.departingPassengers.length + ' passenger(s) got off '); }   if(this.boardingPassengers.length) { - this.passengerRequestQueue.push(...this.boardingPassengers); - output(JSON.stringify(this.boardingPassengers) + ' all got on ' + this.currentFloor) + this.passengerRequestQueue.push(...this.boardingPassengers); + this.output.output((this.boardingPassengers.length + ' passenger(s) got on ')); }   - this.departingPassengers = []; - this.boardingPassengers = []; - this.move = this.move.bind(this); - setTimeout(this.move, this.stopInterval); + this.departingPassengers = []; + this.boardingPassengers = []; +  + if(this.currentFloor === this.currentDestination){ + this.checkDestination(); + } +  + setTimeout(this.move, this.stopInterval); } // check who is getting off the elevator while it is in transit from floor n to floor n +/- 1 // decrements weight of passengers getting off checkOff() {   - if(this.departureRequestMap.get(this.currentFloor) !== undefined) { - this.departingPassengers.push(...this.departureRequestMap.get(this.currentFloor) ?? []); - - this.currentWeight -= sum(this.departingPassengers); - - this.departureRequestMap.delete(this.currentFloor); - + if(this.departureRequestMap.map.get(this.currentFloor) !== undefined) { + this.departingPassengers.push(...this.departureRequestMap.map.get(this.currentFloor) ?? []); + this.currentWeight -= sum(this.departingPassengers); + this.departureRequestMap.delete(this.currentFloor); } }   // checks who is getting on based on direction elevator is traveling and currentWeight of elevator checkOn() { - if(this.externalRequestObject[this.currentFloor] !== undefined) { + if(this.externalRequestMap.map.get(this.currentFloor) !== undefined) { // if elevator has reached destination floor it needs to change direction if the request is in the opposite direction if(this.currentFloor === this.currentDestination && - !this.externalRequestObject[this.currentFloor][this.currentDirection].length) { + !this.externalRequestMap.map.get(this.currentFloor)![this.currentDirection].length) { this.currentDirection = this.currentDirection === 1 ? -1 : 1; }   - const boardingArr = this.externalRequestObject[this.currentFloor][this.currentDirection]; - for(let i = boardingArr.length - 1; i >= 0; i--) { - let currentBoarder = boardingArr[i]; + const boardingArr = this.externalRequestMap.map.get(this.currentFloor)![this.currentDirection]; + for(let i = boardingArr.length - 1; i >= 0; i--) { + let currentBoarder = boardingArr[i]; if(currentBoarder + this.currentWeight <= this.weightLimit) { - this.boardingPassengers.push(currentBoarder); - boardingArr.pop(); - this.currentWeight += currentBoarder; + this.boardingPassengers.push(currentBoarder); + boardingArr.pop(); + this.currentWeight += currentBoarder; } } - if(!boardingArr.length) this.externalRequestObject[this.currentFloor][this.currentDirection] = []; + Iif(!boardingArr.length) this.externalRequestMap.map.get(this.currentFloor)![this.currentDirection] = []; -  // clears request Obj of current floor if there aren't any more requests on this floor - if(!this.externalRequestObject[this.currentFloor][1].length && !this.externalRequestObject[this.currentFloor][-1].length) { - delete this.externalRequestObject[this.currentFloor]; + if(!this.externalRequestMap.map.get(this.currentFloor)![1].length && !this.externalRequestMap.map.get(this.currentFloor)![-1].length) { + this.externalRequestMap.delete(this.currentFloor); }   } @@ -808,45 +718,32 @@

All files elevator.ts

  // internal floor request sets their destination in departureRequestMap selectFloor(floor: number) { + this.output.output('Floor ' + floor + ' requested internally'); +  + Iif(!this.passengerRequestQueue.length) return; +  const weight = this.passengerRequestQueue.shift()!; - if(this.departureRequestMap.get(floor) === undefined) { + if(this.departureRequestMap.map.get(floor) === undefined) { this.departureRequestMap.set(floor, []); }   - this.departureRequestMap.get(floor)!.push(weight); - this.setDestinationExternal(floor); + this.departureRequestMap.map.get(floor)!.push(weight); } -  -  - // if there is an external request where our currentDestination should change - setDestinationExternal(floor: number) { -  - if(this.currentDestination === -1) { - this.currentDestination = floor; - this.currentDirection = floor > this.currentFloor ? 1 : -1; - } else if(this.currentDirection === 1) { - if(floor > this.currentDestination) this.currentDestination = floor; - } else if(this.currentDirection === -1) { - if(floor < this.currentDestination) this.currentDestination = floor; - } - }   // handles external request request(request: ElevatorRequest) { -  + const {currentFloor, direction, weight} = request; - if(this.externalRequestObject[currentFloor] === undefined) { - this.externalRequestObject[currentFloor] = { +  + if(this.externalRequestMap.map.get(currentFloor) === undefined) { + this.externalRequestMap.set(currentFloor, { '1': [], '-1': [] - }; + }) } -  - this.externalRequestObject[currentFloor][direction].push(weight); - - // if the destination needs to be changed based on current direction it will be set here if weight allows - Iif(this.currentWeight < this.weightLimit) this.setDestinationExternal(currentFloor); + this.externalRequestMap.map.get(currentFloor)![direction].push(weight); + this.output.output('Floor ' + currentFloor + ' requested externally');   }   @@ -856,17 +753,18 @@

All files elevator.ts

}   // will end when all requests have been served and all passengers are off the elevator - endProcess() { - return (!Object.keys(this.externalRequestObject).length && + endProcess() { + return (!this.externalRequestMap.map.size && !this.passengerRequestQueue.length && - !this.departureRequestMap.size && !this.boardingPassengers.length - && !this.departingPassengers.length) + !this.departureRequestMap.map.size && !this.boardingPassengers.length + && !this.departingPassengers.length) }   }   export default Elevator;   +   
@@ -874,7 +772,7 @@

All files elevator.ts

+ + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/requestMap.ts.html b/coverage/lcov-report/requestMap.ts.html new file mode 100644 index 0000000..c6a2ce7 --- /dev/null +++ b/coverage/lcov-report/requestMap.ts.html @@ -0,0 +1,262 @@ + + + + + + Code coverage report for requestMap.ts + + + + + + + + + +
+
+

All files requestMap.ts

+
+ +
+ 90.9% + Statements + 20/22 +
+ + +
+ 100% + Branches + 6/6 +
+ + +
+ 100% + Functions + 5/5 +
+ + +
+ 88.88% + Lines + 16/18 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60  +  +  +  +  +  +  +  +  +  +  +6x +6x +6x +  +  +  +9x +  +  +  +  +9x +9x +  +  +  +3x +  +3x +3x +  +  +  +  +  +1x +1x +  +1x +  +  +  +  +  +1x +1x +  +1x +  +  +  +  +  +  +  +  +  +  +1x
// keep track of max / min 
+// be a normal object
+ 
+ 
+ 
+ 
+class RequestMap<T> {
+  map: Map<number, T>;
+  min: number;
+  max: number;
+  constructor() {
+    this.map = new Map<number, T>();
+    this.max = -1;
+    this.min = -1;
+  }
+ 
+  set(key: number, value: T) {
+    this.map.set(key, value);
+    if(this.map.size === 0) {
+      this.min = key;
+      this.max = key;
+    }
+    if(key > this.max) this.max = key;
+    if(key < this.min || this.min === -1) this.min = key;
+  }
+ 
+  delete(key: number) {
+    this.map.delete(key);
+ 
+    if(key === this.min) this.setMin();
+    if(key === this.max) this.setMax();
+ 
+  }  
+ 
+  setMin() {
+    if(!this.map.size) {
+      this.min = -1;
+      return;
+    }
+    this.min = Math.min(...Array.from(this.map.keys()));
+ 
+  }
+ 
+  setMax() {
+    if(!this.map.size) {
+      this.max = -1;
+      return;
+    }
+    this.max = Math.max(...Array.from(this.map.keys()));
+  }
+ 
+ 
+ 
+ 
+ 
+}
+ 
+ 
+ 
+export default RequestMap;
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov.info b/coverage/lcov.info index 43aa2ab..e69de29 100644 --- a/coverage/lcov.info +++ b/coverage/lcov.info @@ -1,159 +0,0 @@ -TN: -SF:elevator/elevator.ts -FN:11,(anonymous_6) -FN:14,(anonymous_7) -FN:16,(anonymous_8) -FN:42,(anonymous_9) -FN:61,(anonymous_10) -FN:119,(anonymous_11) -FN:145,(anonymous_12) -FN:166,(anonymous_13) -FN:179,(anonymous_14) -FN:209,(anonymous_15) -FN:222,(anonymous_16) -FN:235,(anonymous_17) -FN:253,(anonymous_18) -FN:258,(anonymous_19) -FNF:14 -FNH:10 -FNDA:9,(anonymous_6) -FNDA:2,(anonymous_7) -FNDA:0,(anonymous_8) -FNDA:10,(anonymous_9) -FNDA:6,(anonymous_10) -FNDA:2,(anonymous_11) -FNDA:1,(anonymous_12) -FNDA:5,(anonymous_13) -FNDA:5,(anonymous_14) -FNDA:0,(anonymous_15) -FNDA:4,(anonymous_16) -FNDA:0,(anonymous_17) -FNDA:0,(anonymous_18) -FNDA:1,(anonymous_19) -DA:2,1 -DA:5,1 -DA:11,1 -DA:12,9 -DA:14,1 -DA:15,2 -DA:16,2 -DA:17,2 -DA:43,10 -DA:44,10 -DA:45,10 -DA:46,10 -DA:47,10 -DA:48,10 -DA:49,10 -DA:50,10 -DA:51,10 -DA:52,10 -DA:53,10 -DA:54,10 -DA:55,10 -DA:56,10 -DA:57,10 -DA:63,6 -DA:64,6 -DA:67,0 -DA:71,6 -DA:72,5 -DA:78,0 -DA:81,0 -DA:82,0 -DA:85,1 -DA:90,1 -DA:91,1 -DA:92,1 -DA:97,1 -DA:102,0 -DA:103,0 -DA:107,5 -DA:108,5 -DA:109,5 -DA:110,5 -DA:113,5 -DA:121,2 -DA:124,1 -DA:129,1 -DA:130,1 -DA:134,1 -DA:136,0 -DA:140,1 -DA:147,1 -DA:150,1 -DA:154,1 -DA:155,1 -DA:158,1 -DA:159,1 -DA:160,1 -DA:161,1 -DA:169,2 -DA:171,2 -DA:173,2 -DA:185,0 -DA:188,3 -DA:189,3 -DA:190,5 -DA:192,4 -DA:193,4 -DA:194,4 -DA:197,3 -DA:202,2 -DA:210,0 -DA:212,0 -DA:215,0 -DA:216,0 -DA:225,0 -DA:226,0 -DA:228,2 -DA:230,2 -DA:237,0 -DA:239,0 -DA:245,0 -DA:248,0 -DA:254,0 -DA:259,1 -DA:267,1 -LF:85 -LH:66 -BRDA:66,0,0,6 -BRDA:66,0,1,1 -BRDA:71,1,0,1 -BRDA:71,1,1,5 -BRDA:72,2,0,0 -BRDA:76,3,0,6 -BRDA:76,3,1,6 -BRDA:76,3,2,6 -BRDA:76,3,3,1 -BRDA:89,4,0,6 -BRDA:89,4,1,5 -BRDA:121,5,0,1 -BRDA:121,5,1,1 -BRDA:124,6,0,0 -BRDA:140,7,0,1 -BRDA:140,7,1,0 -BRDA:169,8,0,2 -BRDA:169,8,1,0 -BRDA:169,9,0,2 -BRDA:169,9,1,2 -BRDA:183,10,0,3 -BRDA:183,10,1,2 -BRDA:185,11,0,0 -BRDA:185,11,1,0 -BRDA:197,12,0,2 -BRDA:201,13,0,3 -BRDA:201,13,1,2 -BRDA:226,14,0,0 -BRDA:226,14,1,0 -BRDA:228,15,0,1 -BRDA:230,16,0,1 -BRDA:248,17,0,0 -BRDA:259,18,0,1 -BRDA:259,18,1,1 -BRDA:259,18,2,1 -BRDA:259,18,3,0 -BRDA:259,18,4,0 -BRF:37 -BRH:26 -end_of_record diff --git a/elevator/elevator.ts b/elevator/elevator.ts index 589e311..ab65b63 100644 --- a/elevator/elevator.ts +++ b/elevator/elevator.ts @@ -1,18 +1,7 @@ -// to write to new files for output -import * as fs from 'fs' - -// to add EOL character to file output -import * as os from 'os'; - -import {ElevatorRequest, ExternalRequestObject, direction} from './types.js'; - +import {ElevatorRequest, DirectionObject, direction} from './types.js'; +import RequestMap from './requestMap.js'; import Output from './output.js'; -// I think that in order to limit inefficient destination checks we should use a priority queue only for departureMap. -// this way we can keep track of the max or min value depending on direction and peek it in constant time instead of creating -// a whole new array and using O(n) to find the min or max. - - const sum = (arr: number[]) => { let sum = 0; sum = arr.reduce((a, b) => a + b); @@ -35,8 +24,8 @@ class Elevator { quit: boolean; currentWeight: number; weightLimit: number; - departureRequestMap: Map; - externalRequestObject: ExternalRequestObject; + departureRequestMap: RequestMap; + externalRequestMap: RequestMap; passengerRequestQueue: number[]; boardingPassengers: number[]; departingPassengers: number[]; @@ -53,101 +42,84 @@ class Elevator { this.quit = false; this.currentWeight = 0; this.weightLimit = 50; - this.departureRequestMap = new Map(); // maybe it makes sense to have this be a priority queue? - this.externalRequestObject = {}; + this.departureRequestMap = new RequestMap();// maybe it makes sense to have this be a priority queue? + this.externalRequestMap = new RequestMap(); this.passengerRequestQueue = []; this.boardingPassengers = []; this.departingPassengers = []; this.output = new Output('output.txt'); } - - move() { this.move = this.move.bind(this); - - this.newFloorChecks(); - - // if at or above weight limit : need to reset destination to only internal requests - // * can we limit this in any way? - if(this.currentWeight >= this.weightLimit) { - this.setDestinationDecision(); - } - - - this.output.output('Passing floor: ' + this.currentFloor); - - // increment / decrement current floor and change state to moving : check if any board / deboard next floor - this.currentFloor += this.currentDirection; - this.state = 'moving'; - - this.checkOff(); - this.checkOn(); - - - setTimeout(this.move, this.travelInterval); - } - newFloorChecks() { if(this.quit && this.endProcess()) { process.exit(); } - - // check if elevator is inside the correct boundary - if(this.currentFloor === 0) this.currentDirection = 1; - else if(this.currentFloor === this.floors) this.currentDirection = -1; - - // if elevator is not moving and someone requests same floor to get on - if(this.state === 'stopped' && (this.currentDestination === -1 || this.currentDestination === this.currentFloor) - && this.externalRequestObject[this.currentFloor]) { - this.checkOn(); - } - + // check if anyone is getting on or off at current floor if(this.boardingPassengers.length || this.departingPassengers.length) { this.output.output('Stopped on floor: ' + this.currentFloor); this.stopAndBoard(); return; - } else if(this.currentDestination === -1) { - setTimeout(this.move, this.stopInterval); - return; + } + + if(this.state === 'moving') { + this.output.output('Passing floor: ' + this.currentFloor); } + this.checkDestination(); - } + // increment / decrement current floor and change state to moving if there is a current destination + if(this.currentDestination !== -1) { + this.currentFloor += this.currentDirection; + this.state = 'moving'; + } + // check if anyone is getting on / off at upcoming floor + this.checkOff(); + this.checkOn(); + + + if(this.state === 'moving') { + setTimeout(this.move, this.travelInterval); + } else { + setTimeout(this.move, this.stopInterval); + } + + } - // *** use a priority queue here *** - // pick destination if elevator reached current destination or elevator reached weight limit - setDestinationDecision() { + // need to chagne it so we aren't taking min of -1 and another number + checkDestination() { - const keys = Array.from(this.departureRequestMap.keys()); + let min = this.departureRequestMap.min; + let max = this.departureRequestMap.max; + //if we are at or above the weight limit don't consider external requests if(this.currentWeight < this.weightLimit) { - keys.push(Number(...Object.keys(this.externalRequestObject))); + if(min === -1) min = this.externalRequestMap.min; + else if (this.externalRequestMap.min !== -1) min = Math.min(this.externalRequestMap.min, min); + max = Math.max(this.externalRequestMap.max, max); } - - // if there are no requests to serve - if(!keys.length) { - this.currentDestination = -1; + + if(min === -1 && max === -1) { + this.currentDestination = -1; return; } if(this.currentDirection === 1) { - this.currentDestination = Number(Math.max(...keys)); + this.currentDestination = max; } else if(this.currentDirection === -1) { - this.currentDestination = Number(Math.min(...keys)); + this.currentDestination = min; } - this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1; } // stops elevator and boards / deboards passengers depending on their request - // ** maybe should add functionality to see if people made the request just too late for initial check stopAndBoard() { this.state = 'stopped'; @@ -163,6 +135,11 @@ class Elevator { this.departingPassengers = []; this.boardingPassengers = []; + + if(this.currentFloor === this.currentDestination){ + this.checkDestination(); + } + setTimeout(this.move, this.stopInterval); } @@ -170,27 +147,24 @@ class Elevator { // decrements weight of passengers getting off checkOff() { - if(this.departureRequestMap.get(this.currentFloor) !== undefined) { - this.departingPassengers.push(...this.departureRequestMap.get(this.currentFloor) ?? []); - + if(this.departureRequestMap.map.get(this.currentFloor) !== undefined) { + this.departingPassengers.push(...this.departureRequestMap.map.get(this.currentFloor) ?? []); this.currentWeight -= sum(this.departingPassengers); - this.departureRequestMap.delete(this.currentFloor); - } } // checks who is getting on based on direction elevator is traveling and currentWeight of elevator checkOn() { - if(this.externalRequestObject[this.currentFloor] !== undefined) { + if(this.externalRequestMap.map.get(this.currentFloor) !== undefined) { // if elevator has reached destination floor it needs to change direction if the request is in the opposite direction if(this.currentFloor === this.currentDestination && - !this.externalRequestObject[this.currentFloor][this.currentDirection].length) { + !this.externalRequestMap.map.get(this.currentFloor)![this.currentDirection].length) { this.currentDirection = this.currentDirection === 1 ? -1 : 1; } - const boardingArr = this.externalRequestObject[this.currentFloor][this.currentDirection]; + const boardingArr = this.externalRequestMap.map.get(this.currentFloor)![this.currentDirection]; for(let i = boardingArr.length - 1; i >= 0; i--) { let currentBoarder = boardingArr[i]; if(currentBoarder + this.currentWeight <= this.weightLimit) { @@ -199,12 +173,11 @@ class Elevator { this.currentWeight += currentBoarder; } } - if(!boardingArr.length) this.externalRequestObject[this.currentFloor][this.currentDirection] = []; + if(!boardingArr.length) this.externalRequestMap.map.get(this.currentFloor)![this.currentDirection] = []; - // clears request Obj of current floor if there aren't any more requests on this floor - if(!this.externalRequestObject[this.currentFloor][1].length && !this.externalRequestObject[this.currentFloor][-1].length) { - delete this.externalRequestObject[this.currentFloor]; + if(!this.externalRequestMap.map.get(this.currentFloor)![1].length && !this.externalRequestMap.map.get(this.currentFloor)![-1].length) { + this.externalRequestMap.delete(this.currentFloor); } } @@ -213,49 +186,32 @@ class Elevator { // internal floor request sets their destination in departureRequestMap selectFloor(floor: number) { this.output.output('Floor ' + floor + ' requested internally'); + + if(!this.passengerRequestQueue.length) return; + const weight = this.passengerRequestQueue.shift()!; - if(this.departureRequestMap.get(floor) === undefined) { + if(this.departureRequestMap.map.get(floor) === undefined) { this.departureRequestMap.set(floor, []); } - this.departureRequestMap.get(floor)!.push(weight); - this.setDestinationExternal(floor); + this.departureRequestMap.map.get(floor)!.push(weight); } - - // if there is an external request where our currentDestination should change - setDestinationExternal(floor: number) { - - if(this.currentWeight >= this.weightLimit) return; - - if(this.currentDestination === -1) { - this.currentDestination = floor; - this.currentDirection = floor > this.currentFloor ? 1 : -1; - } else if(this.currentDirection === 1) { - if(floor > this.currentDestination) this.currentDestination = floor; - } else if(this.currentDirection === -1) { - if(floor < this.currentDestination) this.currentDestination = floor; - } - } - // handles external request request(request: ElevatorRequest) { const {currentFloor, direction, weight} = request; - if(this.externalRequestObject[currentFloor] === undefined) { - this.externalRequestObject[currentFloor] = { + + if(this.externalRequestMap.map.get(currentFloor) === undefined) { + this.externalRequestMap.set(currentFloor, { '1': [], '-1': [] - }; + }) } + this.externalRequestMap.map.get(currentFloor)![direction].push(weight); this.output.output('Floor ' + currentFloor + ' requested externally'); - this.externalRequestObject[currentFloor][direction].push(weight); - - // if the destination needs to be changed based on current direction it will be set here if weight allows - if(this.currentWeight < this.weightLimit) this.setDestinationExternal(currentFloor); - } // when quit is typed into console @@ -265,9 +221,9 @@ class Elevator { // will end when all requests have been served and all passengers are off the elevator endProcess() { - return (!Object.keys(this.externalRequestObject).length && + return (!this.externalRequestMap.map.size && !this.passengerRequestQueue.length && - !this.departureRequestMap.size && !this.boardingPassengers.length + !this.departureRequestMap.map.size && !this.boardingPassengers.length && !this.departingPassengers.length) } @@ -276,3 +232,4 @@ class Elevator { export default Elevator; +// testMatch: ['*/__tests__/**/*.ts?(x)', '**/?(*.)+(test).ts?(x)'], \ No newline at end of file diff --git a/elevator/elevatorQueue.ts b/elevator/elevatorQueue.ts deleted file mode 100644 index 0acd827..0000000 --- a/elevator/elevatorQueue.ts +++ /dev/null @@ -1,46 +0,0 @@ - -import { - PriorityQueue, - MinPriorityQueue, - MaxPriorityQueue, - ICompare, - IGetCompareValue, -} from '@datastructures-js/priority-queue'; - -import Request from './request.js'; -import {ElevatorRequest} from './types.js' - - - -class ElevatorQueue { - queue: PriorityQueue - - - constructor(minMax: 'min' | 'max') { - this.queue = this.buildQueue(minMax); - } - - buildQueue(minMax: 'min' | 'max') { - if(minMax === 'min') { - return new MinPriorityQueue(this.compare); - } - return new MaxPriorityQueue(this.compare); - } - - compare (request: ElevatorRequest) { - if(request.destination === undefined) { - return request.currentFloor; - } - return request.destination; - } - - - - - - - -} - -export default ElevatorQueue; - diff --git a/elevator/functions.ts b/elevator/functions.ts deleted file mode 100644 index c1fee66..0000000 --- a/elevator/functions.ts +++ /dev/null @@ -1,13 +0,0 @@ -import * as fs from 'fs'; -import * as os from 'os'; - - -export const output = (txt: string) => { - fs.appendFileSync('output.txt', txt + os.EOL); -} - -export const sum = (arr: number[]) => { - let sum = 0; - sum = arr.reduce((a,b) => a + b); - return sum; -} diff --git a/elevator/main.ts b/elevator/main.ts index 627be6a..2422dba 100644 --- a/elevator/main.ts +++ b/elevator/main.ts @@ -18,7 +18,7 @@ elevator.move(); const question = () => { if(elevator.quit) { - if(elevator.passengerRequestQueue.length || Object.keys(elevator.externalRequestObject)) { + if(elevator.passengerRequestQueue.length || Object.keys(elevator.externalRequestMap)) { rl.question('No more outside requests at this time. Please input which floor is your destination', (answer) => { elevator.selectFloor(Number(answer)); question() diff --git a/elevator/request.ts b/elevator/request.ts index 935aec6..5407cb3 100644 --- a/elevator/request.ts +++ b/elevator/request.ts @@ -27,30 +27,17 @@ class ElevatorRequest { currentFloor: number; direction: direction; weight: number; - destination: undefined | number; + constructor(currentFloor: number, direction: direction, weight:number) { this.currentFloor = currentFloor; this.direction = direction; this.weight = weight; - this.destination = undefined; - } - setDestination(floor: number) { - if(this.destination === undefined) { - this.destination = floor; - } } - - } - - - - - export default ElevatorRequest; diff --git a/elevator/requestMap.ts b/elevator/requestMap.ts new file mode 100644 index 0000000..f55deaf --- /dev/null +++ b/elevator/requestMap.ts @@ -0,0 +1,57 @@ +// keep track of max / min +// be a normal object + + + + +class RequestMap { + map: Map; + min: number; + max: number; + constructor() { + this.map = new Map(); + this.max = -1; + this.min = -1; + } + + set(key: number, value: T) { + this.map.set(key, value); + if(this.map.size === 0) { + this.min = key; + this.max = key; + } + if(key > this.max) this.max = key; + if(key < this.min || this.min === -1) this.min = key; + } + + delete(key: number) { + this.map.delete(key); + + if(key === this.min) this.setMin(); + if(key === this.max) this.setMax(); + + } + + setMin() { + if(!this.map.size) { + this.min = -1; + return; + } + this.min = Math.min(...Array.from(this.map.keys())); + + } + + setMax() { + if(!this.map.size) { + this.max = -1; + return; + } + this.max = Math.max(...Array.from(this.map.keys())); + } + +} + + + + +export default RequestMap; \ No newline at end of file diff --git a/elevator/types.ts b/elevator/types.ts index 134afab..d985a3d 100644 --- a/elevator/types.ts +++ b/elevator/types.ts @@ -1,22 +1,4 @@ -export type Elevator = { - floors: number; - state: 'stopped' | 'moving'; - currentFloor: number; - currentDirection: 1 | -1; - currentDestination: number; - departureRequestMap: Map; - externalRequestObject: ExternalRequestObject; - travelInterval: number; - stopInterval: number; - quit: boolean; - passengerRequestQueue: number[]; - boardingPassengers: number[]; - departingPassengers: number[]; - currentWeight: number; - weightLimit: number; -} - export type ExternalRequestObject = { [key: number | string] : DirectionObject } @@ -24,14 +6,13 @@ export type ExternalRequestObject = { export type DirectionObject = { '1': number[], '-1': number[]; - [key: number]: number[]; + [key: string|number]: number[]; } export type ElevatorRequest = { currentFloor: number; direction: direction; weight: number; - destination: undefined | number; } diff --git a/jest.config.cjs b/jest.config.cjs index ea8780b..a4162dd 100644 --- a/jest.config.cjs +++ b/jest.config.cjs @@ -1,6 +1,5 @@ module.exports = { preset: 'ts-jest', - transform: { '^.+\\.ts?$': 'ts-jest', '^.+\\.(js|jsx)$': 'babel-jest' @@ -8,10 +7,5 @@ module.exports = { testMatch: ['*/__tests__/**/*.ts?(x)', '**/?(*.)+(test).ts?(x)'], testTimeout: 5000, - globals: { - 'ts-jest': { - babelConfig: true - } - }, - modulePaths: ['/build/elevator/'] + modulePaths: [''] }; \ No newline at end of file diff --git a/output.txt b/output.txt index a6fdb54..e69de29 100644 --- a/output.txt +++ b/output.txt @@ -1,9 +0,0 @@ -21:10:43 - Floor 1 requested externally -21:10:43 - Floor 2 requested externally -21:10:43 - Passing floor: 0 -21:10:43 - Floor 3 requested externally -21:10:46 - Stopped on floor: 1 -21:10:46 - 1 passenger(s) got on -21:10:47 - Passing floor: 1 -21:10:50 - Stopped on floor: 2 -21:10:50 - 1 passenger(s) got on diff --git a/package-lock.json b/package-lock.json index c4c6a8e..5741b7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,10 +11,10 @@ }, "devDependencies": { "@types/jest": "^29.5.0", - "@types/node": "^18.15.10", + "@types/node": "^18.15.11", "jest": "^29.5.0", "ts-jest": "^29.0.5", - "typescript": "^5.0.2" + "typescript": "^4.3.0" } }, "node_modules/@ampproject/remapping": { @@ -1075,9 +1075,9 @@ } }, "node_modules/@types/node": { - "version": "18.15.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.10.tgz", - "integrity": "sha512-9avDaQJczATcXgfmMAW3MIWArOO7A+m90vuCFLr8AotWf8igO/mRoYukrk2cqZVtv38tHs33retzHEilM7FpeQ==", + "version": "18.15.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", "dev": true }, "node_modules/@types/prettier": { @@ -3425,16 +3425,16 @@ } }, "node_modules/typescript": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", - "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=12.20" + "node": ">=4.2.0" } }, "node_modules/update-browserslist-db": { @@ -4442,9 +4442,9 @@ } }, "@types/node": { - "version": "18.15.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.10.tgz", - "integrity": "sha512-9avDaQJczATcXgfmMAW3MIWArOO7A+m90vuCFLr8AotWf8igO/mRoYukrk2cqZVtv38tHs33retzHEilM7FpeQ==", + "version": "18.15.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", + "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==", "dev": true }, "@types/prettier": { @@ -6177,9 +6177,9 @@ "dev": true }, "typescript": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", - "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, "update-browserslist-db": { diff --git a/package.json b/package.json index 472ea91..c0443f8 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,10 @@ }, "devDependencies": { "@types/jest": "^29.5.0", - "@types/node": "^18.15.10", + "@types/node": "^18.15.11", "jest": "^29.5.0", "ts-jest": "^29.0.5", - "typescript": "^5.0.2" + "typescript": "^4.3.0" }, "type": "module" } diff --git a/test/elevator.test.ts b/test/elevator.test.ts index 88bf1df..fce7daa 100644 --- a/test/elevator.test.ts +++ b/test/elevator.test.ts @@ -1,5 +1,6 @@ // Import the Elevator class from your implementation file -import Elevator from '../elevator/elevator.js' +import Elevat from '../build/elevator/elevator.js' +// import RequestMap from '../elevator/requestMap' // import Elevator from '../build/elevator/elevator.js'; jest.useFakeTimers(); @@ -9,7 +10,7 @@ describe('Elevator.move', () => { beforeEach(() => { // Create a new Elevator instance before each test - elevator = new Elevator(10); + elevator = new Elevator(15); }); afterEach(() => { @@ -18,9 +19,10 @@ describe('Elevator.move', () => { it('should move the elevator to the next floor when the current direction is 1 and current destination > current floor', () => { elevator.currentFloor = 0; + elevator.currentDirection = 1; - elevator.currentDestination = 1; - elevator.externalRequestObject = {}; + elevator.currentDestination = 4; + // elevator.externalRequestMap.set(); elevator.move(); @@ -32,157 +34,157 @@ describe('Elevator.move', () => { expect(elevator.departingPassengers).toEqual([]); }); - it('should stop the elevator and board passengers when there are external requests on the next floor', () => { +// it('should stop the elevator and board passengers when there are external requests on the next floor', () => { - elevator.currentFloor = 2; - elevator.currentDirection = 1; - elevator.currentDestination = 3; - elevator.externalRequestObject = { 3: { - '1': [25], - '-1': [] - } }; +// elevator.currentFloor = 2; +// elevator.currentDirection = 1; +// elevator.currentDestination = 3; +// elevator.externalRequestObject = { 3: { +// '1': [25], +// '-1': [] +// } }; - elevator.move(); - - expect(elevator.currentFloor).toEqual(3); - expect(elevator.state).toEqual('moving'); - expect(elevator.currentDestination).toEqual(3); - expect(elevator.currentDirection).toEqual(1); - expect(elevator.boardingPassengers.length).toEqual(1); - expect(elevator.departingPassengers).toEqual([]); - }); - - it('should stop the elevator and deboard/board passengers when there are passengers with a request to get off on the current floor', () => { - - elevator.currentFloor = 5; - elevator.currentDirection = 1; - elevator.currentDestination = 5; - elevator.externalRequestObject = {}; - elevator.boardingPassengers = [10,10,10]; - elevator.departingPassengers = [10]; - - elevator.move(); - - expect(elevator.currentFloor).toEqual(5); - expect(elevator.state).toEqual('stopped'); - expect(elevator.currentDestination).toEqual(-1); - expect(elevator.currentDirection).toEqual(1); - expect(elevator.boardingPassengers).toEqual([]); - expect(elevator.departingPassengers).toEqual([]); - expect(elevator.passengerRequestQueue.length).toEqual(3); - }); - - it('should not stop at next floor if there is a request to board but we are at the weight limit', () => { - - elevator.currentFloor = 4; - elevator.currentWeight = 50; - elevator.currentDirection = 1; - elevator.departureRequestMap.set(8, [10]); - elevator.currentDestination = 8; - elevator.externalRequestObject = { 5: { - '1': [25], - '-1': [] - } }; - - elevator.move(); - - expect(elevator.currentFloor).toEqual(5); - expect(elevator.state).toEqual('moving'); - expect(elevator.currentDestination).toEqual(8); - expect(elevator.currentDirection).toEqual(1); - expect(elevator.boardingPassengers).toEqual([]); - expect(elevator.departingPassengers).toEqual([]); - }); - - it('should properly track weight going on and off', () => { - - elevator.currentFloor = 4; - elevator.currentWeight = 50; - elevator.currentDirection = 1; - elevator.currentDestination = 5; - elevator.externalRequestObject= {5: {'1': [10,10,10], '-1':[]}} - elevator.departureRequestMap.set(5, [10]); - elevator.currentWeight = 20; - - elevator.move(); - - expect(elevator.currentFloor).toEqual(5); - expect(elevator.state).toEqual('moving'); - expect(elevator.currentWeight).toEqual(40); +// elevator.move(); + +// expect(elevator.currentFloor).toEqual(3); +// expect(elevator.state).toEqual('moving'); +// expect(elevator.currentDestination).toEqual(3); +// expect(elevator.currentDirection).toEqual(1); +// expect(elevator.boardingPassengers.length).toEqual(1); +// expect(elevator.departingPassengers).toEqual([]); +// }); + +// it('should stop the elevator and deboard/board passengers when there are passengers with a request to get off on the current floor', () => { + +// elevator.currentFloor = 5; +// elevator.currentDirection = 1; +// elevator.currentDestination = 5; +// elevator.externalRequestObject = {}; +// elevator.boardingPassengers = [10,10,10]; +// elevator.departingPassengers = [10]; + +// elevator.move(); + +// expect(elevator.currentFloor).toEqual(5); +// expect(elevator.state).toEqual('stopped'); +// expect(elevator.currentDestination).toEqual(-1); +// expect(elevator.currentDirection).toEqual(1); +// expect(elevator.boardingPassengers).toEqual([]); +// expect(elevator.departingPassengers).toEqual([]); +// expect(elevator.passengerRequestQueue.length).toEqual(3); +// }); + +// it('should not stop at next floor if there is a request to board but we are at the weight limit', () => { + +// elevator.currentFloor = 4; +// elevator.currentWeight = 50; +// elevator.currentDirection = 1; +// elevator.departureRequestMap.set(8, [10]); +// elevator.currentDestination = 8; +// elevator.externalRequestObject = { 5: { +// '1': [25], +// '-1': [] +// } }; + +// elevator.move(); + +// expect(elevator.currentFloor).toEqual(5); +// expect(elevator.state).toEqual('moving'); +// expect(elevator.currentDestination).toEqual(8); +// expect(elevator.currentDirection).toEqual(1); +// expect(elevator.boardingPassengers).toEqual([]); +// expect(elevator.departingPassengers).toEqual([]); +// }); + +// it('should properly track weight going on and off', () => { + +// elevator.currentFloor = 4; +// elevator.currentWeight = 50; +// elevator.currentDirection = 1; +// elevator.currentDestination = 5; +// elevator.externalRequestObject= {5: {'1': [10,10,10], '-1':[]}} +// elevator.departureRequestMap.set(5, [10]); +// elevator.currentWeight = 20; + +// elevator.move(); + +// expect(elevator.currentFloor).toEqual(5); +// expect(elevator.state).toEqual('moving'); +// expect(elevator.currentWeight).toEqual(40); - }); - - it('should not stop program if elevator.stop is true, it should finish requests and then stop', () => { - elevator.quit = true; - elevator.currentFloor = 4; - elevator.currentDirection = 1; - elevator.currentDestination = 5; - elevator.departureRequestMap.set(5,[10]); +// }); + +// it('should not stop program if elevator.stop is true, it should finish requests and then stop', () => { +// elevator.quit = true; +// elevator.currentFloor = 4; +// elevator.currentDirection = 1; +// elevator.currentDestination = 5; +// elevator.departureRequestMap.set(5,[10]); - elevator.move(); +// elevator.move(); - expect(elevator.currentFloor).toEqual(5); - expect(elevator.state).toEqual('moving'); +// expect(elevator.currentFloor).toEqual(5); +// expect(elevator.state).toEqual('moving'); - }) +// }) -}); +// }); -describe('Elevator.setDestinationExternal', () => { - let elevator: Elevator; +// describe('Elevator.setDestinationExternal', () => { +// let elevator: Elevator; - beforeEach(() => { - // Create a new Elevator instance before each test - elevator = new Elevator(10); - }); +// beforeEach(() => { +// // Create a new Elevator instance before each test +// elevator = new Elevator(10); +// }); - afterEach(() => { - jest.clearAllTimers(); - }) +// afterEach(() => { +// jest.clearAllTimers(); +// }) - it('should set destination to higher floor if moving up', () => { - elevator.currentFloor = 0; - elevator.currentDirection = 1; - elevator.currentDestination = 4; +// it('should set destination to higher floor if moving up', () => { +// elevator.currentFloor = 0; +// elevator.currentDirection = 1; +// elevator.currentDestination = 4; - elevator.setDestinationExternal(9); +// elevator.setDestinationExternal(9); - expect(elevator.currentDestination).toEqual(9); - }); +// expect(elevator.currentDestination).toEqual(9); +// }); - it('should set destination to lower floor if moving down', () => { - elevator.currentFloor = 9; - elevator.currentDirection = -1; - elevator.currentDestination = 4; +// it('should set destination to lower floor if moving down', () => { +// elevator.currentFloor = 9; +// elevator.currentDirection = -1; +// elevator.currentDestination = 4; - elevator.setDestinationExternal(2); +// elevator.setDestinationExternal(2); - expect(elevator.currentDestination).toEqual(2); - }); +// expect(elevator.currentDestination).toEqual(2); +// }); - it('should not change destination if moving up and currentDest > new request', () => { - elevator.currentFloor = 0; - elevator.currentDirection = 1; - elevator.currentDestination = 4; +// it('should not change destination if moving up and currentDest > new request', () => { +// elevator.currentFloor = 0; +// elevator.currentDirection = 1; +// elevator.currentDestination = 4; - elevator.setDestinationExternal(3); +// elevator.setDestinationExternal(3); - expect(elevator.currentDestination).toEqual(4); - }); +// expect(elevator.currentDestination).toEqual(4); +// }); - it('should not change destination if moving down and currentDest < new request', () => { - elevator.currentFloor = 9; - elevator.currentDirection = -1; - elevator.currentDestination = 4; +// it('should not change destination if moving down and currentDest < new request', () => { +// elevator.currentFloor = 9; +// elevator.currentDirection = -1; +// elevator.currentDestination = 4; - elevator.setDestinationExternal(5); +// elevator.setDestinationExternal(5); - expect(elevator.currentDestination).toEqual(4); - }); +// expect(elevator.currentDestination).toEqual(4); +// }); }); \ No newline at end of file diff --git a/test/requestMap.test.ts b/test/requestMap.test.ts new file mode 100644 index 0000000..0f119ae --- /dev/null +++ b/test/requestMap.test.ts @@ -0,0 +1,61 @@ +import RequestMap from '../build/elevator/requestMap.js' + + +describe('RequestMap', () => { + let requestMap = new RequestMap(); + beforeEach(() => { + // Create a new Elevator instance before each test + let requestMap = new RequestMap(); + }); + + it('both max and min should be -1 if there requestMap.map size = 0', () => { + expect(requestMap.map.size).toBe(0); + expect(requestMap.min).toBe(-1) + expect(requestMap.max).toBe(-1) + }); + + it('both max and min should be -1 if item is removed to make size = 0', () => { + requestMap.set(1,1); + requestMap.delete(1); + expect(requestMap.min).toBe(-1) + expect(requestMap.max).toBe(-1) + }); + + it('should correctly set max/min when a higher number is added', () => { + requestMap.set(1,1); + requestMap.set(2,1); + + expect(requestMap.max).toEqual(2); + expect(requestMap.min).toEqual(1); + + }) + + it('should correctly set min/min when a lower number is added', () => { + requestMap.set(4,1); + requestMap.set(3,1); + + expect(requestMap.min).toEqual(3); + expect(requestMap.max).toEqual(4); + + }) + + it('min should be reset to correct number if current min is deleted and size !== 0', () => { + requestMap.set(1,1); + requestMap.set(2,1) + requestMap.delete(1); + expect(requestMap.min).toBe(2) + expect(requestMap.max).toBe(2) + }); + + it('max should be reset to correct number if current max is removed and size !== 0', () => { + requestMap.set(1,1); + requestMap.set(2,1) + requestMap.delete(2); + expect(requestMap.min).toBe(1) + expect(requestMap.max).toBe(1) + }); + + + + +}); \ No newline at end of file From b508879efb047f2f1bed160a88ad7a20dd9cfdd3 Mon Sep 17 00:00:00 2001 From: Shay Sheller Date: Sun, 2 Apr 2023 23:03:12 -0700 Subject: [PATCH 19/22] Finished unit tests for both elevator and request class. --- .../coverage/lcov-report/block-navigation.js | 70 ++ build/coverage/lcov-report/prettify.js | 477 +++++++++++++ build/coverage/lcov-report/sorter.js | 163 +++++ build/elevator/__tests__/elevator.test.js | 204 ++++++ build/elevator/__tests__/requestMap.test.js | 51 ++ build/elevator/elevator.js | 18 +- build/elevator/main.js | 40 +- build/elevator/output.js | 31 +- build/elevator/request.js | 4 +- build/elevator/requestMap.js | 4 +- build/elevator/types.js | 3 +- build/jest.config.cjs | 10 +- build/test/elevator.test.js | 138 ---- build/test/requestMap.test.js | 61 -- coverage/clover.xml | 172 ++++- coverage/coverage-final.json | 5 +- coverage/lcov-report/elevator.js.html | 646 ++++++++++++++++++ coverage/lcov-report/index.html | 67 +- coverage/lcov-report/output.js.html | 214 ++++++ coverage/lcov-report/requestMap.js.html | 217 ++++++ coverage/lcov-report/requestMap.ts.html | 35 +- coverage/lcov.info | 330 +++++++++ elevator/README2.md | 5 - elevator/__tests__/elevator.test.ts | 276 ++++++++ .../__tests__}/requestMap.test.ts | 8 +- elevator/elevator.ts | 1 - jest.config.cjs | 8 +- output.txt | 30 + package-lock.json | 1 + package.json | 5 +- test/elevator.test.ts | 190 ------ tsconfig.json | 4 +- 32 files changed, 3022 insertions(+), 466 deletions(-) create mode 100644 build/coverage/lcov-report/block-navigation.js create mode 100644 build/coverage/lcov-report/prettify.js create mode 100644 build/coverage/lcov-report/sorter.js create mode 100644 build/elevator/__tests__/elevator.test.js create mode 100644 build/elevator/__tests__/requestMap.test.js delete mode 100644 build/test/elevator.test.js delete mode 100644 build/test/requestMap.test.js create mode 100644 coverage/lcov-report/elevator.js.html create mode 100644 coverage/lcov-report/output.js.html create mode 100644 coverage/lcov-report/requestMap.js.html create mode 100644 elevator/__tests__/elevator.test.ts rename {test => elevator/__tests__}/requestMap.test.ts (89%) delete mode 100644 test/elevator.test.ts diff --git a/build/coverage/lcov-report/block-navigation.js b/build/coverage/lcov-report/block-navigation.js new file mode 100644 index 0000000..24a45eb --- /dev/null +++ b/build/coverage/lcov-report/block-navigation.js @@ -0,0 +1,70 @@ +"use strict"; +/* eslint-disable */ +var jumpToCode = (function init() { + // Classes of code we would like to highlight in the file view + var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; + // Elements to highlight in the file listing view + var fileListingElements = ['td.pct.low']; + // We don't want to select elements that are direct descendants of another match + var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` + // Selecter that finds elements on the page to which we can jump + var selector = fileListingElements.join(', ') + + ', ' + + notSelector + + missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` + // The NodeList of matching elements + var missingCoverageElements = document.querySelectorAll(selector); + var currentIndex; + function toggleClass(index) { + missingCoverageElements + .item(currentIndex) + .classList.remove('highlighted'); + missingCoverageElements.item(index).classList.add('highlighted'); + } + function makeCurrent(index) { + toggleClass(index); + currentIndex = index; + missingCoverageElements.item(index).scrollIntoView({ + behavior: 'smooth', + block: 'center', + inline: 'center' + }); + } + function goToPrevious() { + var nextIndex = 0; + if (typeof currentIndex !== 'number' || currentIndex === 0) { + nextIndex = missingCoverageElements.length - 1; + } + else if (missingCoverageElements.length > 1) { + nextIndex = currentIndex - 1; + } + makeCurrent(nextIndex); + } + function goToNext() { + var nextIndex = 0; + if (typeof currentIndex === 'number' && + currentIndex < missingCoverageElements.length - 1) { + nextIndex = currentIndex + 1; + } + makeCurrent(nextIndex); + } + return function jump(event) { + if (document.getElementById('fileSearch') === document.activeElement && + document.activeElement != null) { + // if we're currently focused on the search input, we don't want to navigate + return; + } + switch (event.which) { + case 78: // n + case 74: // j + goToNext(); + break; + case 66: // b + case 75: // k + case 80: // p + goToPrevious(); + break; + } + }; +})(); +window.addEventListener('keydown', jumpToCode); diff --git a/build/coverage/lcov-report/prettify.js b/build/coverage/lcov-report/prettify.js new file mode 100644 index 0000000..37bc099 --- /dev/null +++ b/build/coverage/lcov-report/prettify.js @@ -0,0 +1,477 @@ +"use strict"; +/* eslint-disable */ +window.PR_SHOULD_USE_CONTINUATION = true; +(function () { var h = ["break,continue,do,else,for,if,return,while"]; var u = [h, "auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"]; var p = [u, "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"]; var l = [p, "alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"]; var x = [p, "abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"]; var R = [x, "as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"]; var r = "all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes"; var w = [p, "debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"]; var s = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"; var I = [h, "and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"]; var f = [h, "alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"]; var H = [h, "case,done,elif,esac,eval,fi,function,in,local,set,then,until"]; var A = [l, R, w, s + I, f, H]; var e = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/; var C = "str"; var z = "kwd"; var j = "com"; var O = "typ"; var G = "lit"; var L = "pun"; var F = "pln"; var m = "tag"; var E = "dec"; var J = "src"; var P = "atn"; var n = "atv"; var N = "nocode"; var M = "(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*"; function k(Z) { var ad = 0; var S = false; var ac = false; for (var V = 0, U = Z.length; V < U; ++V) { + var ae = Z[V]; + if (ae.ignoreCase) { + ac = true; + } + else { + if (/[a-z]/i.test(ae.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ""))) { + S = true; + ac = false; + break; + } + } +} var Y = { b: 8, t: 9, n: 10, v: 11, f: 12, r: 13 }; function ab(ah) { var ag = ah.charCodeAt(0); if (ag !== 92) { + return ag; +} var af = ah.charAt(1); ag = Y[af]; if (ag) { + return ag; +} +else { + if ("0" <= af && af <= "7") { + return parseInt(ah.substring(1), 8); + } + else { + if (af === "u" || af === "x") { + return parseInt(ah.substring(2), 16); + } + else { + return ah.charCodeAt(1); + } + } +} } function T(af) { if (af < 32) { + return (af < 16 ? "\\x0" : "\\x") + af.toString(16); +} var ag = String.fromCharCode(af); if (ag === "\\" || ag === "-" || ag === "[" || ag === "]") { + ag = "\\" + ag; +} return ag; } function X(am) { var aq = am.substring(1, am.length - 1).match(new RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]", "g")); var ak = []; var af = []; var ao = aq[0] === "^"; for (var ar = ao ? 1 : 0, aj = aq.length; ar < aj; ++ar) { + var ah = aq[ar]; + if (/\\[bdsw]/i.test(ah)) { + ak.push(ah); + } + else { + var ag = ab(ah); + var al; + if (ar + 2 < aj && "-" === aq[ar + 1]) { + al = ab(aq[ar + 2]); + ar += 2; + } + else { + al = ag; + } + af.push([ag, al]); + if (!(al < 65 || ag > 122)) { + if (!(al < 65 || ag > 90)) { + af.push([Math.max(65, ag) | 32, Math.min(al, 90) | 32]); + } + if (!(al < 97 || ag > 122)) { + af.push([Math.max(97, ag) & ~32, Math.min(al, 122) & ~32]); + } + } + } +} af.sort(function (av, au) { return (av[0] - au[0]) || (au[1] - av[1]); }); var ai = []; var ap = [NaN, NaN]; for (var ar = 0; ar < af.length; ++ar) { + var at = af[ar]; + if (at[0] <= ap[1] + 1) { + ap[1] = Math.max(ap[1], at[1]); + } + else { + ai.push(ap = at); + } +} var an = ["["]; if (ao) { + an.push("^"); +} an.push.apply(an, ak); for (var ar = 0; ar < ai.length; ++ar) { + var at = ai[ar]; + an.push(T(at[0])); + if (at[1] > at[0]) { + if (at[1] + 1 > at[0]) { + an.push("-"); + } + an.push(T(at[1])); + } +} an.push("]"); return an.join(""); } function W(al) { var aj = al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)", "g")); var ah = aj.length; var an = []; for (var ak = 0, am = 0; ak < ah; ++ak) { + var ag = aj[ak]; + if (ag === "(") { + ++am; + } + else { + if ("\\" === ag.charAt(0)) { + var af = +ag.substring(1); + if (af && af <= am) { + an[af] = -1; + } + } + } +} for (var ak = 1; ak < an.length; ++ak) { + if (-1 === an[ak]) { + an[ak] = ++ad; + } +} for (var ak = 0, am = 0; ak < ah; ++ak) { + var ag = aj[ak]; + if (ag === "(") { + ++am; + if (an[am] === undefined) { + aj[ak] = "(?:"; + } + } + else { + if ("\\" === ag.charAt(0)) { + var af = +ag.substring(1); + if (af && af <= am) { + aj[ak] = "\\" + an[am]; + } + } + } +} for (var ak = 0, am = 0; ak < ah; ++ak) { + if ("^" === aj[ak] && "^" !== aj[ak + 1]) { + aj[ak] = ""; + } +} if (al.ignoreCase && S) { + for (var ak = 0; ak < ah; ++ak) { + var ag = aj[ak]; + var ai = ag.charAt(0); + if (ag.length >= 2 && ai === "[") { + aj[ak] = X(ag); + } + else { + if (ai !== "\\") { + aj[ak] = ag.replace(/[a-zA-Z]/g, function (ao) { var ap = ao.charCodeAt(0); return "[" + String.fromCharCode(ap & ~32, ap | 32) + "]"; }); + } + } + } +} return aj.join(""); } var aa = []; for (var V = 0, U = Z.length; V < U; ++V) { + var ae = Z[V]; + if (ae.global || ae.multiline) { + throw new Error("" + ae); + } + aa.push("(?:" + W(ae) + ")"); +} return new RegExp(aa.join("|"), ac ? "gi" : "g"); } function a(V) { var U = /(?:^|\s)nocode(?:\s|$)/; var X = []; var T = 0; var Z = []; var W = 0; var S; if (V.currentStyle) { + S = V.currentStyle.whiteSpace; +} +else { + if (window.getComputedStyle) { + S = document.defaultView.getComputedStyle(V, null).getPropertyValue("white-space"); + } +} var Y = S && "pre" === S.substring(0, 3); function aa(ab) { switch (ab.nodeType) { + case 1: + if (U.test(ab.className)) { + return; + } + for (var ae = ab.firstChild; ae; ae = ae.nextSibling) { + aa(ae); + } + var ad = ab.nodeName; + if ("BR" === ad || "LI" === ad) { + X[W] = "\n"; + Z[W << 1] = T++; + Z[(W++ << 1) | 1] = ab; + } + break; + case 3: + case 4: + var ac = ab.nodeValue; + if (ac.length) { + if (!Y) { + ac = ac.replace(/[ \t\r\n]+/g, " "); + } + else { + ac = ac.replace(/\r\n?/g, "\n"); + } + X[W] = ac; + Z[W << 1] = T; + T += ac.length; + Z[(W++ << 1) | 1] = ab; + } + break; +} } aa(V); return { sourceCode: X.join("").replace(/\n$/, ""), spans: Z }; } function B(S, U, W, T) { if (!U) { + return; +} var V = { sourceCode: U, basePos: S }; W(V); T.push.apply(T, V.decorations); } var v = /\S/; function o(S) { var V = undefined; for (var U = S.firstChild; U; U = U.nextSibling) { + var T = U.nodeType; + V = (T === 1) ? (V ? S : U) : (T === 3) ? (v.test(U.nodeValue) ? S : V) : V; +} return V === S ? undefined : V; } function g(U, T) { var S = {}; var V; (function () { var ad = U.concat(T); var ah = []; var ag = {}; for (var ab = 0, Z = ad.length; ab < Z; ++ab) { + var Y = ad[ab]; + var ac = Y[3]; + if (ac) { + for (var ae = ac.length; --ae >= 0;) { + S[ac.charAt(ae)] = Y; + } + } + var af = Y[1]; + var aa = "" + af; + if (!ag.hasOwnProperty(aa)) { + ah.push(af); + ag[aa] = null; + } +} ah.push(/[\0-\uffff]/); V = k(ah); })(); var X = T.length; var W = function (ah) { var Z = ah.sourceCode, Y = ah.basePos; var ad = [Y, F]; var af = 0; var an = Z.match(V) || []; var aj = {}; for (var ae = 0, aq = an.length; ae < aq; ++ae) { + var ag = an[ae]; + var ap = aj[ag]; + var ai = void 0; + var am; + if (typeof ap === "string") { + am = false; + } + else { + var aa = S[ag.charAt(0)]; + if (aa) { + ai = ag.match(aa[1]); + ap = aa[0]; + } + else { + for (var ao = 0; ao < X; ++ao) { + aa = T[ao]; + ai = ag.match(aa[1]); + if (ai) { + ap = aa[0]; + break; + } + } + if (!ai) { + ap = F; + } + } + am = ap.length >= 5 && "lang-" === ap.substring(0, 5); + if (am && !(ai && typeof ai[1] === "string")) { + am = false; + ap = J; + } + if (!am) { + aj[ag] = ap; + } + } + var ab = af; + af += ag.length; + if (!am) { + ad.push(Y + ab, ap); + } + else { + var al = ai[1]; + var ak = ag.indexOf(al); + var ac = ak + al.length; + if (ai[2]) { + ac = ag.length - ai[2].length; + ak = ac - al.length; + } + var ar = ap.substring(5); + B(Y + ab, ag.substring(0, ak), W, ad); + B(Y + ab + ak, al, q(ar, al), ad); + B(Y + ab + ac, ag.substring(ac), W, ad); + } +} ah.decorations = ad; }; return W; } function i(T) { var W = [], S = []; if (T.tripleQuotedStrings) { + W.push([C, /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/, null, "'\""]); +} +else { + if (T.multiLineStrings) { + W.push([C, /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/, null, "'\"`"]); + } + else { + W.push([C, /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/, null, "\"'"]); + } +} if (T.verbatimStrings) { + S.push([C, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]); +} var Y = T.hashComments; if (Y) { + if (T.cStyleComments) { + if (Y > 1) { + W.push([j, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, "#"]); + } + else { + W.push([j, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/, null, "#"]); + } + S.push([C, /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/, null]); + } + else { + W.push([j, /^#[^\r\n]*/, null, "#"]); + } +} if (T.cStyleComments) { + S.push([j, /^\/\/[^\r\n]*/, null]); + S.push([j, /^\/\*[\s\S]*?(?:\*\/|$)/, null]); +} if (T.regexLiterals) { + var X = ("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/"); + S.push(["lang-regex", new RegExp("^" + M + "(" + X + ")")]); +} var V = T.types; if (V) { + S.push([O, V]); +} var U = ("" + T.keywords).replace(/^ | $/g, ""); if (U.length) { + S.push([z, new RegExp("^(?:" + U.replace(/[\s,]+/g, "|") + ")\\b"), null]); +} W.push([F, /^\s+/, null, " \r\n\t\xA0"]); S.push([G, /^@[a-z_$][a-z_$@0-9]*/i, null], [O, /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null], [F, /^[a-z_$][a-z_$@0-9]*/i, null], [G, new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*", "i"), null, "0123456789"], [F, /^\\[\s\S]?/, null], [L, /^.[^\s\w\.$@\'\"\`\/\#\\]*/, null]); return g(W, S); } var K = i({ keywords: A, hashComments: true, cStyleComments: true, multiLineStrings: true, regexLiterals: true }); function Q(V, ag) { var U = /(?:^|\s)nocode(?:\s|$)/; var ab = /\r\n?|\n/; var ac = V.ownerDocument; var S; if (V.currentStyle) { + S = V.currentStyle.whiteSpace; +} +else { + if (window.getComputedStyle) { + S = ac.defaultView.getComputedStyle(V, null).getPropertyValue("white-space"); + } +} var Z = S && "pre" === S.substring(0, 3); var af = ac.createElement("LI"); while (V.firstChild) { + af.appendChild(V.firstChild); +} var W = [af]; function ae(al) { switch (al.nodeType) { + case 1: + if (U.test(al.className)) { + break; + } + if ("BR" === al.nodeName) { + ad(al); + if (al.parentNode) { + al.parentNode.removeChild(al); + } + } + else { + for (var an = al.firstChild; an; an = an.nextSibling) { + ae(an); + } + } + break; + case 3: + case 4: + if (Z) { + var am = al.nodeValue; + var aj = am.match(ab); + if (aj) { + var ai = am.substring(0, aj.index); + al.nodeValue = ai; + var ah = am.substring(aj.index + aj[0].length); + if (ah) { + var ak = al.parentNode; + ak.insertBefore(ac.createTextNode(ah), al.nextSibling); + } + ad(al); + if (!ai) { + al.parentNode.removeChild(al); + } + } + } + break; +} } function ad(ak) { while (!ak.nextSibling) { + ak = ak.parentNode; + if (!ak) { + return; + } +} function ai(al, ar) { var aq = ar ? al.cloneNode(false) : al; var ao = al.parentNode; if (ao) { + var ap = ai(ao, 1); + var an = al.nextSibling; + ap.appendChild(aq); + for (var am = an; am; am = an) { + an = am.nextSibling; + ap.appendChild(am); + } +} return aq; } var ah = ai(ak.nextSibling, 0); for (var aj; (aj = ah.parentNode) && aj.nodeType === 1;) { + ah = aj; +} W.push(ah); } for (var Y = 0; Y < W.length; ++Y) { + ae(W[Y]); +} if (ag === (ag | 0)) { + W[0].setAttribute("value", ag); +} var aa = ac.createElement("OL"); aa.className = "linenums"; var X = Math.max(0, ((ag - 1)) | 0) || 0; for (var Y = 0, T = W.length; Y < T; ++Y) { + af = W[Y]; + af.className = "L" + ((Y + X) % 10); + if (!af.firstChild) { + af.appendChild(ac.createTextNode("\xA0")); + } + aa.appendChild(af); +} V.appendChild(aa); } function D(ac) { var aj = /\bMSIE\b/.test(navigator.userAgent); var am = /\n/g; var al = ac.sourceCode; var an = al.length; var V = 0; var aa = ac.spans; var T = aa.length; var ah = 0; var X = ac.decorations; var Y = X.length; var Z = 0; X[Y] = an; var ar, aq; for (aq = ar = 0; aq < Y;) { + if (X[aq] !== X[aq + 2]) { + X[ar++] = X[aq++]; + X[ar++] = X[aq++]; + } + else { + aq += 2; + } +} Y = ar; for (aq = ar = 0; aq < Y;) { + var at = X[aq]; + var ab = X[aq + 1]; + var W = aq + 2; + while (W + 2 <= Y && X[W + 1] === ab) { + W += 2; + } + X[ar++] = at; + X[ar++] = ab; + aq = W; +} Y = X.length = ar; var ae = null; while (ah < T) { + var af = aa[ah]; + var S = aa[ah + 2] || an; + var ag = X[Z]; + var ap = X[Z + 2] || an; + var W = Math.min(S, ap); + var ak = aa[ah + 1]; + var U; + if (ak.nodeType !== 1 && (U = al.substring(V, W))) { + if (aj) { + U = U.replace(am, "\r"); + } + ak.nodeValue = U; + var ai = ak.ownerDocument; + var ao = ai.createElement("SPAN"); + ao.className = X[Z + 1]; + var ad = ak.parentNode; + ad.replaceChild(ao, ak); + ao.appendChild(ak); + if (V < S) { + aa[ah + 1] = ak = ai.createTextNode(al.substring(W, S)); + ad.insertBefore(ak, ao.nextSibling); + } + } + V = W; + if (V >= S) { + ah += 2; + } + if (V >= ap) { + Z += 2; + } +} } var t = {}; function c(U, V) { for (var S = V.length; --S >= 0;) { + var T = V[S]; + if (!t.hasOwnProperty(T)) { + t[T] = U; + } + else { + if (window.console) { + console.warn("cannot override language handler %s", T); + } + } +} } function q(T, S) { if (!(T && t.hasOwnProperty(T))) { + T = /^\s*]*(?:>|$)/], [j, /^<\!--[\s\S]*?(?:-\->|$)/], ["lang-", /^<\?([\s\S]+?)(?:\?>|$)/], ["lang-", /^<%([\s\S]+?)(?:%>|$)/], [L, /^(?:<[%?]|[%?]>)/], ["lang-", /^]*>([\s\S]+?)<\/xmp\b[^>]*>/i], ["lang-js", /^]*>([\s\S]*?)(<\/script\b[^>]*>)/i], ["lang-css", /^]*>([\s\S]*?)(<\/style\b[^>]*>)/i], ["lang-in.tag", /^(<\/?[a-z][^<>]*>)/i]]), ["default-markup", "htm", "html", "mxml", "xhtml", "xml", "xsl"]); c(g([[F, /^[\s]+/, null, " \t\r\n"], [n, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, "\"'"]], [[m, /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i], [P, /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i], ["lang-uq.val", /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/], [L, /^[=<>\/]+/], ["lang-js", /^on\w+\s*=\s*\"([^\"]+)\"/i], ["lang-js", /^on\w+\s*=\s*\'([^\']+)\'/i], ["lang-js", /^on\w+\s*=\s*([^\"\'>\s]+)/i], ["lang-css", /^style\s*=\s*\"([^\"]+)\"/i], ["lang-css", /^style\s*=\s*\'([^\']+)\'/i], ["lang-css", /^style\s*=\s*([^\"\'>\s]+)/i]]), ["in.tag"]); c(g([], [[n, /^[\s\S]+/]]), ["uq.val"]); c(i({ keywords: l, hashComments: true, cStyleComments: true, types: e }), ["c", "cc", "cpp", "cxx", "cyc", "m"]); c(i({ keywords: "null,true,false" }), ["json"]); c(i({ keywords: R, hashComments: true, cStyleComments: true, verbatimStrings: true, types: e }), ["cs"]); c(i({ keywords: x, cStyleComments: true }), ["java"]); c(i({ keywords: H, hashComments: true, multiLineStrings: true }), ["bsh", "csh", "sh"]); c(i({ keywords: I, hashComments: true, multiLineStrings: true, tripleQuotedStrings: true }), ["cv", "py"]); c(i({ keywords: s, hashComments: true, multiLineStrings: true, regexLiterals: true }), ["perl", "pl", "pm"]); c(i({ keywords: f, hashComments: true, multiLineStrings: true, regexLiterals: true }), ["rb"]); c(i({ keywords: w, cStyleComments: true, regexLiterals: true }), ["js"]); c(i({ keywords: r, hashComments: 3, cStyleComments: true, multilineStrings: true, tripleQuotedStrings: true, regexLiterals: true }), ["coffee"]); c(g([], [[C, /^[\s\S]+/]]), ["regex"]); function d(V) { var U = V.langExtension; try { + var S = a(V.sourceNode); + var T = S.sourceCode; + V.sourceCode = T; + V.spans = S.spans; + V.basePos = 0; + q(U, T)(V); + D(V); +} +catch (W) { + if ("console" in window) { + console.log(W && W.stack ? W.stack : W); + } +} } function y(W, V, U) { var S = document.createElement("PRE"); S.innerHTML = W; if (U) { + Q(S, U); +} var T = { langExtension: V, numberLines: U, sourceNode: S }; d(T); return S.innerHTML; } function b(ad) { function Y(af) { return document.getElementsByTagName(af); } var ac = [Y("pre"), Y("code"), Y("xmp")]; var T = []; for (var aa = 0; aa < ac.length; ++aa) { + for (var Z = 0, V = ac[aa].length; Z < V; ++Z) { + T.push(ac[aa][Z]); + } +} ac = null; var W = Date; if (!W.now) { + W = { now: function () { return +(new Date); } }; +} var X = 0; var S; var ab = /\blang(?:uage)?-([\w.]+)(?!\S)/; var ae = /\bprettyprint\b/; function U() { var ag = (window.PR_SHOULD_USE_CONTINUATION ? W.now() + 250 : Infinity); for (; X < T.length && W.now() < ag; X++) { + var aj = T[X]; + var ai = aj.className; + if (ai.indexOf("prettyprint") >= 0) { + var ah = ai.match(ab); + var am; + if (!ah && (am = o(aj)) && "CODE" === am.tagName) { + ah = am.className.match(ab); + } + if (ah) { + ah = ah[1]; + } + var al = false; + for (var ak = aj.parentNode; ak; ak = ak.parentNode) { + if ((ak.tagName === "pre" || ak.tagName === "code" || ak.tagName === "xmp") && ak.className && ak.className.indexOf("prettyprint") >= 0) { + al = true; + break; + } + } + if (!al) { + var af = aj.className.match(/\blinenums\b(?::(\d+))?/); + af = af ? af[1] && af[1].length ? +af[1] : true : false; + if (af) { + Q(aj, af); + } + S = { langExtension: ah, sourceNode: aj, numberLines: af }; + d(S); + } + } +} if (X < T.length) { + setTimeout(U, 250); +} +else { + if (ad) { + ad(); + } +} } U(); } window.prettyPrintOne = y; window.prettyPrint = b; window.PR = { createSimpleLexer: g, registerLangHandler: c, sourceDecorator: i, PR_ATTRIB_NAME: P, PR_ATTRIB_VALUE: n, PR_COMMENT: j, PR_DECLARATION: E, PR_KEYWORD: z, PR_LITERAL: G, PR_NOCODE: N, PR_PLAIN: F, PR_PUNCTUATION: L, PR_SOURCE: J, PR_STRING: C, PR_TAG: m, PR_TYPE: O }; })(); +PR.registerLangHandler(PR.createSimpleLexer([], [[PR.PR_DECLARATION, /^]*(?:>|$)/], [PR.PR_COMMENT, /^<\!--[\s\S]*?(?:-\->|$)/], [PR.PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/], ["lang-", /^<\?([\s\S]+?)(?:\?>|$)/], ["lang-", /^<%([\s\S]+?)(?:%>|$)/], ["lang-", /^]*>([\s\S]+?)<\/xmp\b[^>]*>/i], ["lang-handlebars", /^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i], ["lang-js", /^]*>([\s\S]*?)(<\/script\b[^>]*>)/i], ["lang-css", /^]*>([\s\S]*?)(<\/style\b[^>]*>)/i], ["lang-in.tag", /^(<\/?[a-z][^<>]*>)/i], [PR.PR_DECLARATION, /^{{[#^>/]?\s*[\w.][^}]*}}/], [PR.PR_DECLARATION, /^{{&?\s*[\w.][^}]*}}/], [PR.PR_DECLARATION, /^{{{>?\s*[\w.][^}]*}}}/], [PR.PR_COMMENT, /^{{![^}]*}}/]]), ["handlebars", "hbs"]); +PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN, /^[ \t\r\n\f]+/, null, " \t\r\n\f"]], [[PR.PR_STRING, /^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/, null], [PR.PR_STRING, /^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/, null], ["lang-css-str", /^url\(([^\)\"\']*)\)/i], [PR.PR_KEYWORD, /^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i, null], ["lang-css-kw", /^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i], [PR.PR_COMMENT, /^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//], [PR.PR_COMMENT, /^(?:)/], [PR.PR_LITERAL, /^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i], [PR.PR_LITERAL, /^#(?:[0-9a-f]{3}){1,2}/i], [PR.PR_PLAIN, /^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i], [PR.PR_PUNCTUATION, /^[^\s\w\'\"]+/]]), ["css"]); +PR.registerLangHandler(PR.createSimpleLexer([], [[PR.PR_KEYWORD, /^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]), ["css-kw"]); +PR.registerLangHandler(PR.createSimpleLexer([], [[PR.PR_STRING, /^[^\)\"\']+/]]), ["css-str"]); diff --git a/build/coverage/lcov-report/sorter.js b/build/coverage/lcov-report/sorter.js new file mode 100644 index 0000000..303d604 --- /dev/null +++ b/build/coverage/lcov-report/sorter.js @@ -0,0 +1,163 @@ +"use strict"; +/* eslint-disable */ +var addSorting = (function () { + 'use strict'; + var cols, currentSort = { + index: 0, + desc: false + }; + // returns the summary table element + function getTable() { + return document.querySelector('.coverage-summary'); + } + // returns the thead element of the summary table + function getTableHeader() { + return getTable().querySelector('thead tr'); + } + // returns the tbody element of the summary table + function getTableBody() { + return getTable().querySelector('tbody'); + } + // returns the th element for nth column + function getNthColumn(n) { + return getTableHeader().querySelectorAll('th')[n]; + } + function onFilterInput() { + const searchValue = document.getElementById('fileSearch').value; + const rows = document.getElementsByTagName('tbody')[0].children; + for (let i = 0; i < rows.length; i++) { + const row = rows[i]; + if (row.textContent + .toLowerCase() + .includes(searchValue.toLowerCase())) { + row.style.display = ''; + } + else { + row.style.display = 'none'; + } + } + } + // loads the search box + function addSearchBox() { + var template = document.getElementById('filterTemplate'); + var templateClone = template.content.cloneNode(true); + templateClone.getElementById('fileSearch').oninput = onFilterInput; + template.parentElement.appendChild(templateClone); + } + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), colNode, cols = [], col, i; + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = + colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), colNode, col, data = {}, i, val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), i; + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, sorter = function (a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, finalSorter = sorter, tableBody = document.querySelector('.coverage-summary tbody'), rowNodes = tableBody.querySelectorAll('tr'), rows = [], i; + if (desc) { + finalSorter = function (a, b) { + return -1 * sorter(a, b); + }; + } + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + rows.sort(finalSorter); + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), cls = col.className; + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc + ? ' sorted-desc' + : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, el, ithSorter = function ithSorter(i) { + var col = cols[i]; + return function () { + var desc = col.defaultDescSort; + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i = 0; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } + else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function () { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(); + addSearchBox(); + addSortIndicators(); + enableUI(); + }; +})(); +window.addEventListener('load', addSorting); diff --git a/build/elevator/__tests__/elevator.test.js b/build/elevator/__tests__/elevator.test.js new file mode 100644 index 0000000..b48194b --- /dev/null +++ b/build/elevator/__tests__/elevator.test.js @@ -0,0 +1,204 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const elevator_js_1 = __importDefault(require("../elevator.js")); +jest.useFakeTimers(); +describe('checkOn', () => { + let elevator; + beforeEach(() => { + elevator = new elevator_js_1.default(15); + elevator.externalRequestMap.set(12, { '1': [], '-1': [1] }); + elevator.currentFloor = 12; + elevator.currentDestination = 12; + elevator.currentDirection = 1; + }); + afterEach(() => { + jest.clearAllTimers(); + }); + it('should not add new people to boardingPassengers if at or above the weight limit', () => { + elevator.currentWeight = elevator.weightLimit; + elevator.checkOn(); + expect(elevator.boardingPassengers.length).toEqual(0); + }); + it('should add passengers to boardingPassengers if below weightLimit', () => { + elevator.checkOn(); + expect(elevator.boardingPassengers.length).toEqual(1); + }); + it('should only add passengers to boardingPassengers if they are on the current floor', () => { + elevator.externalRequestMap.set(13, { '1': [], '-1': [1] }); + elevator.checkOn(); + expect(elevator.boardingPassengers.length).toEqual(1); + }); + it('should remove passengers from elevator.externalRequestMap when added to elevator.boardingPassengers', () => { + elevator.checkOn(); + expect(elevator.externalRequestMap.map.size).toEqual(0); + }); + it('should increment weight when passengers added to boardingPassengers', () => { + elevator.checkOn(); + expect(elevator.currentWeight).toEqual(1); + }); + it('should only add passengers traveling in same direction as the elevator currently', () => { + elevator.externalRequestMap.map.get(12)[1].push(1); + elevator.checkOn(); + expect(elevator.externalRequestMap.map.get(12)[1].length).toEqual(0); + expect(elevator.externalRequestMap.map.get(12)[-1].length).toEqual(1); + }); + it('should change direction if we reach current destination and there is a request in opposite direction', () => { + elevator.currentFloor = 11; + elevator.move(); + expect(elevator.currentDirection).toEqual(-1); + }); +}); +describe('checkOff', () => { + let elevator; + beforeEach(() => { + // Create a new Elevator instance before each test + elevator = new elevator_js_1.default(15); + elevator.departureRequestMap.set(15, [1]); + elevator.currentFloor = 15; + elevator.currentDestination = 15; + elevator.currentDirection = 1; + elevator.currentWeight = 12; + }); + afterEach(() => { + jest.clearAllTimers(); + }); + it('should only add people to departingPassengers if they are on current floor', () => { + elevator.departureRequestMap.set(13, [1]); + elevator.checkOff(); + expect(elevator.departingPassengers.length).toEqual(1); + }); + it('should delete key from departureRequestMap if it has no passengers left', () => { + elevator.checkOff(); + expect(elevator.departureRequestMap.map.size).toEqual(0); + }); + it('should decrement weight when passenger is added to departingPassengers', () => { + elevator.checkOff(); + expect(elevator.currentWeight).toEqual(11); + }); +}); +describe('request', () => { + let elevator; + beforeEach(() => { + elevator = new elevator_js_1.default(15); + }); + it('should add request to externalRequestMap', () => { + elevator.request({ currentFloor: 1, direction: 1, weight: 1 }); + expect(elevator.externalRequestMap.map.size).toEqual(1); + }); +}); +describe('selectFloor', () => { + let elevator; + beforeEach(() => { + elevator = new elevator_js_1.default(15); + }); + it('should move passengers weight from passengerRequestQueue to departureRequestMap', () => { + elevator.passengerRequestQueue.push(1); + elevator.selectFloor(5); + expect(elevator.departureRequestMap.map.size).toEqual(1); + expect(elevator.passengerRequestQueue.length).toBe(0); + }); +}); +describe('checkDestination under weight limit', () => { + let elevator; + beforeEach(() => { + elevator = new elevator_js_1.default(15); + elevator.externalRequestMap.set(15, { '1': [], '-1': [1] }); + elevator.externalRequestMap.set(14, { '1': [], '-1': [1] }); + elevator.externalRequestMap.set(13, { '1': [], '-1': [1] }); + elevator.departureRequestMap.set(12, [1]); + elevator.departureRequestMap.set(11, [1]); + elevator.departureRequestMap.set(10, [1]); + }); + it('should pick the highest number floor while traveling up as the destination', () => { + elevator.currentDirection = 1; + elevator.currentFloor = 1; + elevator.checkDestination(); + expect(elevator.currentDestination).toEqual(15); + }); + it('should pick the lowest number floor while traveling down as the destination', () => { + elevator.currentDirection = -1; + elevator.currentDestination = -1; + elevator.currentFloor = 15; + elevator.checkDestination(); + expect(elevator.currentDestination).toEqual(10); + }); + it('should change direction if destination is set opposite of current direction', () => { + elevator.currentDestination = -1; + elevator.currentFloor = 9; + elevator.currentDirection = -1; + elevator.checkDestination(); + expect(elevator.currentDirection).toEqual(1); + }); +}); +describe('checkDestination over weight limit', () => { + let elevator; + beforeEach(() => { + elevator = new elevator_js_1.default(15); + elevator.externalRequestMap.set(15, { '1': [], '-1': [1] }); + elevator.externalRequestMap.set(14, { '1': [], '-1': [1] }); + elevator.externalRequestMap.set(13, { '1': [], '-1': [1] }); + elevator.departureRequestMap.set(12, [1]); + elevator.departureRequestMap.set(11, [1]); + elevator.departureRequestMap.set(10, [1]); + elevator.externalRequestMap.set(9, { '1': [], '-1': [1] }); + elevator.currentWeight = elevator.weightLimit; + }); + it('should pick the highest number in departurerequestmap while travelling up and ignore ext requests', () => { + elevator.currentDirection = 1; + elevator.currentFloor = 1; + elevator.checkDestination(); + expect(elevator.currentDestination).toEqual(12); + }); + it('should pick the lowest number from departure request map while traveling down and ignore ext requests', () => { + elevator.currentDirection = -1; + elevator.currentDestination = -1; + elevator.currentFloor = 15; + elevator.checkDestination(); + expect(elevator.currentDestination).toEqual(10); + }); +}); +describe('move', () => { + let elevator; + beforeEach(() => { + elevator = new elevator_js_1.default(15); + }); + it('should stop if there are passengers getting off/on', () => { + elevator.boardingPassengers.push(1); + elevator.state = 'moving'; + elevator.move(); + expect(elevator.state).toEqual('stopped'); + }); + it('should increment currentdirection if we are going up', () => { + elevator.currentDirection = 1; + elevator.currentFloor = 11; + elevator.departureRequestMap.set(14, [1]); + elevator.move(); + expect(elevator.currentFloor).toEqual(12); + }); + it('should decrement currentdirection if we are going down', () => { + elevator.currentDirection = -1; + elevator.currentFloor = 14; + elevator.departureRequestMap.set(10, [1]); + elevator.move(); + expect(elevator.currentFloor).toEqual(13); + }); + it('should change dest to -1 when we reach current destination with no other requests', () => { + elevator.currentDestination = 14; + elevator.currentFloor = 14; + elevator.departingPassengers.push(1); + elevator.move(); + expect(elevator.state).toEqual('stopped'); + expect(elevator.currentDestination).toEqual(-1); + }); + it('should correctly select dest when there is no destination and new request comes in', () => { + elevator.currentDestination = -1; + elevator.currentFloor = 14; + elevator.currentDirection = -1; + elevator.departureRequestMap.set(1, [1]); + elevator.move(); + expect(elevator.currentDestination).toEqual(1); + }); +}); diff --git a/build/elevator/__tests__/requestMap.test.js b/build/elevator/__tests__/requestMap.test.js new file mode 100644 index 0000000..65f7834 --- /dev/null +++ b/build/elevator/__tests__/requestMap.test.js @@ -0,0 +1,51 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// import RequestMap from '../elevator/requestMap.js' +const requestMap_js_1 = __importDefault(require("../requestMap.js")); +describe('RequestMap', () => { + let requestMap; + beforeEach(() => { + // Create a new Elevator instance before each test + requestMap = new requestMap_js_1.default(); + }); + it('both max and min should be -1 if there requestMap.map size = 0', () => { + expect(requestMap.map.size).toBe(0); + expect(requestMap.min).toBe(-1); + expect(requestMap.max).toBe(-1); + }); + it('both max and min should be -1 if item is removed to make size = 0', () => { + requestMap.set(1, 1); + requestMap.delete(1); + expect(requestMap.min).toBe(-1); + expect(requestMap.max).toBe(-1); + }); + it('should correctly set max/min when a higher number is added', () => { + requestMap.set(1, 1); + requestMap.set(2, 1); + expect(requestMap.max).toEqual(2); + expect(requestMap.min).toEqual(1); + }); + it('should correctly set min/min when a lower number is added', () => { + requestMap.set(4, 1); + requestMap.set(3, 1); + expect(requestMap.min).toEqual(3); + expect(requestMap.max).toEqual(4); + }); + it('min should be reset to correct number if current min is deleted and size !== 0', () => { + requestMap.set(1, 1); + requestMap.set(2, 1); + requestMap.delete(1); + expect(requestMap.min).toBe(2); + expect(requestMap.max).toBe(2); + }); + it('max should be reset to correct number if current max is removed and size !== 0', () => { + requestMap.set(1, 1); + requestMap.set(2, 1); + requestMap.delete(2); + expect(requestMap.min).toBe(1); + expect(requestMap.max).toBe(1); + }); +}); diff --git a/build/elevator/elevator.js b/build/elevator/elevator.js index cf87e85..128ab3d 100644 --- a/build/elevator/elevator.js +++ b/build/elevator/elevator.js @@ -1,5 +1,10 @@ -import RequestMap from './requestMap.js'; -import Output from './output.js'; +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const requestMap_js_1 = __importDefault(require("./requestMap.js")); +const output_js_1 = __importDefault(require("./output.js")); const sum = (arr) => { let sum = 0; sum = arr.reduce((a, b) => a + b); @@ -19,12 +24,12 @@ class Elevator { this.quit = false; this.currentWeight = 0; this.weightLimit = 50; - this.departureRequestMap = new RequestMap(); // maybe it makes sense to have this be a priority queue? - this.externalRequestMap = new RequestMap(); + this.departureRequestMap = new requestMap_js_1.default(); // maybe it makes sense to have this be a priority queue? + this.externalRequestMap = new requestMap_js_1.default(); this.passengerRequestQueue = []; this.boardingPassengers = []; this.departingPassengers = []; - this.output = new Output('output.txt'); + this.output = new output_js_1.default('output.txt'); } move() { this.move = this.move.bind(this); @@ -167,5 +172,4 @@ class Elevator { && !this.departingPassengers.length); } } -export default Elevator; -// testMatch: ['*/__tests__/**/*.ts?(x)', '**/?(*.)+(test).ts?(x)'], +exports.default = Elevator; diff --git a/build/elevator/main.js b/build/elevator/main.js index 8ff28b3..38bc847 100644 --- a/build/elevator/main.js +++ b/build/elevator/main.js @@ -1,13 +1,41 @@ -import Elevator from './elevator.js'; -import ElevatorRequest from './request.js'; -import * as fs from 'fs'; -import * as readline from 'readline'; +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const elevator_js_1 = __importDefault(require("./elevator.js")); +const request_js_1 = __importDefault(require("./request.js")); +const fs = __importStar(require("fs")); +const readline = __importStar(require("readline")); // Create an interface for reading from the command line const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); -const elevator = new Elevator(15); +const elevator = new elevator_js_1.default(15); elevator.move(); const question = () => { if (elevator.quit) { @@ -43,7 +71,7 @@ const question = () => { }; // defaulting to weight of 25 const createRequest = (floor, direction) => { - const req = new ElevatorRequest(Number(floor), direction, 25); + const req = new request_js_1.default(Number(floor), direction, 25); elevator.request(req); }; fs.writeFileSync('output.txt', ''); diff --git a/build/elevator/output.js b/build/elevator/output.js index cab12a1..595a986 100644 --- a/build/elevator/output.js +++ b/build/elevator/output.js @@ -1,7 +1,32 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); // to write to new files for output -import * as fs from 'fs'; +const fs = __importStar(require("fs")); // to add EOL character to file output -import * as os from 'os'; +const os = __importStar(require("os")); class Output { constructor(filename) { this.outputFileName = filename; @@ -15,4 +40,4 @@ class Output { fs.appendFileSync(this.outputFileName, outputString + os.EOL); } } -export default Output; +exports.default = Output; diff --git a/build/elevator/request.js b/build/elevator/request.js index 9fb417a..1a11241 100644 --- a/build/elevator/request.js +++ b/build/elevator/request.js @@ -1,8 +1,10 @@ +"use strict"; // class ElevatorRequest { // currentFloor: number; // direction: number; // weight: number; // destinationFloor: undefined | number; +Object.defineProperty(exports, "__esModule", { value: true }); class ElevatorRequest { constructor(currentFloor, direction, weight) { this.currentFloor = currentFloor; @@ -10,4 +12,4 @@ class ElevatorRequest { this.weight = weight; } } -export default ElevatorRequest; +exports.default = ElevatorRequest; diff --git a/build/elevator/requestMap.js b/build/elevator/requestMap.js index 99426af..eeea12f 100644 --- a/build/elevator/requestMap.js +++ b/build/elevator/requestMap.js @@ -1,5 +1,7 @@ +"use strict"; // keep track of max / min // be a normal object +Object.defineProperty(exports, "__esModule", { value: true }); class RequestMap { constructor() { this.map = new Map(); @@ -39,4 +41,4 @@ class RequestMap { this.max = Math.max(...Array.from(this.map.keys())); } } -export default RequestMap; +exports.default = RequestMap; diff --git a/build/elevator/types.js b/build/elevator/types.js index cb0ff5c..c8ad2e5 100644 --- a/build/elevator/types.js +++ b/build/elevator/types.js @@ -1 +1,2 @@ -export {}; +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/build/jest.config.cjs b/build/jest.config.cjs index d742761..a18414e 100644 --- a/build/jest.config.cjs +++ b/build/jest.config.cjs @@ -1,11 +1,13 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); module.exports = { preset: 'ts-jest', transform: { - '^.+\\.ts?$': 'ts-jest', + '^.+\\.(t|j)s?$': 'ts-jest', '^.+\\.(js|jsx)$': 'babel-jest' }, - testMatch: ['*/__tests__/**/*.ts?(x)', '**/?(*.)+(test).ts?(x)'], + testMatch: ['**/*.test.js?(x)', '**/*.spec.ts?(x)'], testTimeout: 5000, - modulePaths: [''] + modulePaths: [''], + testEnvironment: 'node' }; -export {}; diff --git a/build/test/elevator.test.js b/build/test/elevator.test.js deleted file mode 100644 index 11d243b..0000000 --- a/build/test/elevator.test.js +++ /dev/null @@ -1,138 +0,0 @@ -// import RequestMap from '../elevator/requestMap' -// import Elevator from '../build/elevator/elevator.js'; -jest.useFakeTimers(); -describe('Elevator.move', () => { - let elevator; - beforeEach(() => { - // Create a new Elevator instance before each test - elevator = new Elevator(15); - }); - afterEach(() => { - jest.clearAllTimers(); - }); - it('should move the elevator to the next floor when the current direction is 1 and current destination > current floor', () => { - elevator.currentFloor = 0; - elevator.currentDirection = 1; - elevator.currentDestination = 4; - // elevator.externalRequestMap.set(); - elevator.move(); - expect(elevator.currentFloor).toEqual(1); - expect(elevator.state).toEqual('moving'); - expect(elevator.currentDestination).toEqual(1); - expect(elevator.currentDirection).toEqual(1); - expect(elevator.boardingPassengers).toEqual([]); - expect(elevator.departingPassengers).toEqual([]); - }); - // it('should stop the elevator and board passengers when there are external requests on the next floor', () => { - // elevator.currentFloor = 2; - // elevator.currentDirection = 1; - // elevator.currentDestination = 3; - // elevator.externalRequestObject = { 3: { - // '1': [25], - // '-1': [] - // } }; - // elevator.move(); - // expect(elevator.currentFloor).toEqual(3); - // expect(elevator.state).toEqual('moving'); - // expect(elevator.currentDestination).toEqual(3); - // expect(elevator.currentDirection).toEqual(1); - // expect(elevator.boardingPassengers.length).toEqual(1); - // expect(elevator.departingPassengers).toEqual([]); - // }); - // it('should stop the elevator and deboard/board passengers when there are passengers with a request to get off on the current floor', () => { - // elevator.currentFloor = 5; - // elevator.currentDirection = 1; - // elevator.currentDestination = 5; - // elevator.externalRequestObject = {}; - // elevator.boardingPassengers = [10,10,10]; - // elevator.departingPassengers = [10]; - // elevator.move(); - // expect(elevator.currentFloor).toEqual(5); - // expect(elevator.state).toEqual('stopped'); - // expect(elevator.currentDestination).toEqual(-1); - // expect(elevator.currentDirection).toEqual(1); - // expect(elevator.boardingPassengers).toEqual([]); - // expect(elevator.departingPassengers).toEqual([]); - // expect(elevator.passengerRequestQueue.length).toEqual(3); - // }); - // it('should not stop at next floor if there is a request to board but we are at the weight limit', () => { - // elevator.currentFloor = 4; - // elevator.currentWeight = 50; - // elevator.currentDirection = 1; - // elevator.departureRequestMap.set(8, [10]); - // elevator.currentDestination = 8; - // elevator.externalRequestObject = { 5: { - // '1': [25], - // '-1': [] - // } }; - // elevator.move(); - // expect(elevator.currentFloor).toEqual(5); - // expect(elevator.state).toEqual('moving'); - // expect(elevator.currentDestination).toEqual(8); - // expect(elevator.currentDirection).toEqual(1); - // expect(elevator.boardingPassengers).toEqual([]); - // expect(elevator.departingPassengers).toEqual([]); - // }); - // it('should properly track weight going on and off', () => { - // elevator.currentFloor = 4; - // elevator.currentWeight = 50; - // elevator.currentDirection = 1; - // elevator.currentDestination = 5; - // elevator.externalRequestObject= {5: {'1': [10,10,10], '-1':[]}} - // elevator.departureRequestMap.set(5, [10]); - // elevator.currentWeight = 20; - // elevator.move(); - // expect(elevator.currentFloor).toEqual(5); - // expect(elevator.state).toEqual('moving'); - // expect(elevator.currentWeight).toEqual(40); - // }); - // it('should not stop program if elevator.stop is true, it should finish requests and then stop', () => { - // elevator.quit = true; - // elevator.currentFloor = 4; - // elevator.currentDirection = 1; - // elevator.currentDestination = 5; - // elevator.departureRequestMap.set(5,[10]); - // elevator.move(); - // expect(elevator.currentFloor).toEqual(5); - // expect(elevator.state).toEqual('moving'); - // }) - // }); - // describe('Elevator.setDestinationExternal', () => { - // let elevator: Elevator; - // beforeEach(() => { - // // Create a new Elevator instance before each test - // elevator = new Elevator(10); - // }); - // afterEach(() => { - // jest.clearAllTimers(); - // }) - // it('should set destination to higher floor if moving up', () => { - // elevator.currentFloor = 0; - // elevator.currentDirection = 1; - // elevator.currentDestination = 4; - // elevator.setDestinationExternal(9); - // expect(elevator.currentDestination).toEqual(9); - // }); - // it('should set destination to lower floor if moving down', () => { - // elevator.currentFloor = 9; - // elevator.currentDirection = -1; - // elevator.currentDestination = 4; - // elevator.setDestinationExternal(2); - // expect(elevator.currentDestination).toEqual(2); - // }); - // it('should not change destination if moving up and currentDest > new request', () => { - // elevator.currentFloor = 0; - // elevator.currentDirection = 1; - // elevator.currentDestination = 4; - // elevator.setDestinationExternal(3); - // expect(elevator.currentDestination).toEqual(4); - // }); - // it('should not change destination if moving down and currentDest < new request', () => { - // elevator.currentFloor = 9; - // elevator.currentDirection = -1; - // elevator.currentDestination = 4; - // elevator.setDestinationExternal(5); - // expect(elevator.currentDestination).toEqual(4); - // }); -}); -export {}; diff --git a/build/test/requestMap.test.js b/build/test/requestMap.test.js deleted file mode 100644 index 980c64e..0000000 --- a/build/test/requestMap.test.js +++ /dev/null @@ -1,61 +0,0 @@ -import RequestMap from '../elevator/requestMap.js' - - -describe('RequestMap', () => { - let requestMap = new RequestMap(); - beforeEach(() => { - // Create a new Elevator instance before each test - let requestMap = new RequestMap(); - }); - - it('both max and min should be -1 if there requestMap.map size = 0', () => { - expect(requestMap.map.size).toBe(0); - expect(requestMap.min).toBe(-1) - expect(requestMap.max).toBe(-1) - }); - - it('both max and min should be -1 if item is removed to make size = 0', () => { - requestMap.set(1,1); - requestMap.delete(1); - expect(requestMap.min).toBe(-1) - expect(requestMap.max).toBe(-1) - }); - - it('should correctly set max/min when a higher number is added', () => { - requestMap.set(1,1); - requestMap.set(2,1); - - expect(requestMap.max).toEqual(2); - expect(requestMap.min).toEqual(1); - - }) - - it('should correctly set min/min when a lower number is added', () => { - requestMap.set(4,1); - requestMap.set(3,1); - - expect(requestMap.min).toEqual(3); - expect(requestMap.max).toEqual(4); - - }) - - it('min should be reset to correct number if current min is deleted and size !== 0', () => { - requestMap.set(1,1); - requestMap.set(2,1) - requestMap.delete(1); - expect(requestMap.min).toBe(2) - expect(requestMap.max).toBe(2) - }); - - it('max should be reset to correct number if current max is removed and size !== 0', () => { - requestMap.set(1,1); - requestMap.set(2,1) - requestMap.delete(2); - expect(requestMap.min).toBe(1) - expect(requestMap.max).toBe(1) - }); - - - - -}); \ No newline at end of file diff --git a/coverage/clover.xml b/coverage/clover.xml index 9c5f27a..66143c1 100644 --- a/coverage/clover.xml +++ b/coverage/clover.xml @@ -1,6 +1,172 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/coverage/coverage-final.json b/coverage/coverage-final.json index 0967ef4..937fd71 100644 --- a/coverage/coverage-final.json +++ b/coverage/coverage-final.json @@ -1 +1,4 @@ -{} +{"/Users/shaysheller/Desktop/coding-challenge/build/elevator.js": {"path":"/Users/shaysheller/Desktop/coding-challenge/build/elevator.js","statementMap":{"0":{"start":{"line":2,"column":22},"end":{"line":4,"column":1}},"1":{"start":{"line":3,"column":4},"end":{"line":3,"column":62}},"2":{"start":{"line":5,"column":0},"end":{"line":5,"column":62}},"3":{"start":{"line":6,"column":24},"end":{"line":6,"column":67}},"4":{"start":{"line":7,"column":20},"end":{"line":7,"column":59}},"5":{"start":{"line":8,"column":12},"end":{"line":12,"column":1}},"6":{"start":{"line":9,"column":14},"end":{"line":9,"column":15}},"7":{"start":{"line":10,"column":4},"end":{"line":10,"column":38}},"8":{"start":{"line":10,"column":31},"end":{"line":10,"column":36}},"9":{"start":{"line":11,"column":4},"end":{"line":11,"column":15}},"10":{"start":{"line":17,"column":8},"end":{"line":17,"column":29}},"11":{"start":{"line":18,"column":8},"end":{"line":18,"column":31}},"12":{"start":{"line":19,"column":8},"end":{"line":19,"column":30}},"13":{"start":{"line":20,"column":8},"end":{"line":20,"column":34}},"14":{"start":{"line":21,"column":8},"end":{"line":21,"column":37}},"15":{"start":{"line":22,"column":8},"end":{"line":22,"column":35}},"16":{"start":{"line":23,"column":8},"end":{"line":23,"column":33}},"17":{"start":{"line":24,"column":8},"end":{"line":24,"column":26}},"18":{"start":{"line":25,"column":8},"end":{"line":25,"column":31}},"19":{"start":{"line":26,"column":8},"end":{"line":26,"column":30}},"20":{"start":{"line":27,"column":8},"end":{"line":27,"column":65}},"21":{"start":{"line":28,"column":8},"end":{"line":28,"column":64}},"22":{"start":{"line":29,"column":8},"end":{"line":29,"column":40}},"23":{"start":{"line":30,"column":8},"end":{"line":30,"column":37}},"24":{"start":{"line":31,"column":8},"end":{"line":31,"column":38}},"25":{"start":{"line":32,"column":8},"end":{"line":32,"column":60}},"26":{"start":{"line":35,"column":8},"end":{"line":35,"column":41}},"27":{"start":{"line":36,"column":8},"end":{"line":38,"column":null}},"28":{"start":{"line":37,"column":12},"end":{"line":37,"column":27}},"29":{"start":{"line":40,"column":8},"end":{"line":44,"column":null}},"30":{"start":{"line":41,"column":12},"end":{"line":41,"column":73}},"31":{"start":{"line":42,"column":12},"end":{"line":42,"column":32}},"32":{"start":{"line":43,"column":12},"end":{"line":43,"column":19}},"33":{"start":{"line":45,"column":8},"end":{"line":47,"column":null}},"34":{"start":{"line":46,"column":12},"end":{"line":46,"column":70}},"35":{"start":{"line":48,"column":8},"end":{"line":48,"column":32}},"36":{"start":{"line":50,"column":8},"end":{"line":53,"column":null}},"37":{"start":{"line":51,"column":12},"end":{"line":51,"column":55}},"38":{"start":{"line":52,"column":12},"end":{"line":52,"column":34}},"39":{"start":{"line":55,"column":8},"end":{"line":55,"column":24}},"40":{"start":{"line":56,"column":8},"end":{"line":56,"column":23}},"41":{"start":{"line":57,"column":8},"end":{"line":62,"column":null}},"42":{"start":{"line":58,"column":12},"end":{"line":58,"column":55}},"43":{"start":{"line":61,"column":12},"end":{"line":61,"column":53}},"44":{"start":{"line":66,"column":18},"end":{"line":66,"column":46}},"45":{"start":{"line":67,"column":18},"end":{"line":67,"column":46}},"46":{"start":{"line":69,"column":8},"end":{"line":75,"column":null}},"47":{"start":{"line":70,"column":12},"end":{"line":73,"column":65}},"48":{"start":{"line":71,"column":16},"end":{"line":71,"column":50}},"49":{"start":{"line":72,"column":17},"end":{"line":73,"column":65}},"50":{"start":{"line":73,"column":16},"end":{"line":73,"column":65}},"51":{"start":{"line":74,"column":12},"end":{"line":74,"column":61}},"52":{"start":{"line":76,"column":8},"end":{"line":79,"column":null}},"53":{"start":{"line":77,"column":12},"end":{"line":77,"column":41}},"54":{"start":{"line":78,"column":12},"end":{"line":78,"column":19}},"55":{"start":{"line":80,"column":8},"end":{"line":85,"column":null}},"56":{"start":{"line":81,"column":12},"end":{"line":81,"column":42}},"57":{"start":{"line":83,"column":13},"end":{"line":85,"column":null}},"58":{"start":{"line":84,"column":12},"end":{"line":84,"column":42}},"59":{"start":{"line":86,"column":8},"end":{"line":86,"column":85}},"60":{"start":{"line":90,"column":8},"end":{"line":90,"column":31}},"61":{"start":{"line":91,"column":8},"end":{"line":93,"column":null}},"62":{"start":{"line":92,"column":12},"end":{"line":92,"column":91}},"63":{"start":{"line":94,"column":8},"end":{"line":97,"column":null}},"64":{"start":{"line":95,"column":12},"end":{"line":95,"column":72}},"65":{"start":{"line":96,"column":12},"end":{"line":96,"column":91}},"66":{"start":{"line":98,"column":8},"end":{"line":98,"column":38}},"67":{"start":{"line":99,"column":8},"end":{"line":99,"column":37}},"68":{"start":{"line":100,"column":8},"end":{"line":102,"column":null}},"69":{"start":{"line":101,"column":12},"end":{"line":101,"column":36}},"70":{"start":{"line":103,"column":8},"end":{"line":103,"column":49}},"71":{"start":{"line":109,"column":8},"end":{"line":113,"column":null}},"72":{"start":{"line":110,"column":12},"end":{"line":110,"column":141}},"73":{"start":{"line":111,"column":12},"end":{"line":111,"column":64}},"74":{"start":{"line":112,"column":12},"end":{"line":112,"column":63}},"75":{"start":{"line":117,"column":8},"end":{"line":138,"column":null}},"76":{"start":{"line":119,"column":12},"end":{"line":122,"column":null}},"77":{"start":{"line":121,"column":16},"end":{"line":121,"column":77}},"78":{"start":{"line":123,"column":32},"end":{"line":123,"column":105}},"79":{"start":{"line":124,"column":12},"end":{"line":131,"column":null}},"80":{"start":{"line":124,"column":25},"end":{"line":124,"column":47}},"81":{"start":{"line":125,"column":37},"end":{"line":125,"column":51}},"82":{"start":{"line":126,"column":16},"end":{"line":130,"column":null}},"83":{"start":{"line":127,"column":20},"end":{"line":127,"column":65}},"84":{"start":{"line":128,"column":20},"end":{"line":128,"column":38}},"85":{"start":{"line":129,"column":20},"end":{"line":129,"column":57}},"86":{"start":{"line":132,"column":12},"end":{"line":133,"column":95}},"87":{"start":{"line":133,"column":16},"end":{"line":133,"column":95}},"88":{"start":{"line":135,"column":12},"end":{"line":137,"column":null}},"89":{"start":{"line":136,"column":16},"end":{"line":136,"column":66}},"90":{"start":{"line":142,"column":8},"end":{"line":142,"column":71}},"91":{"start":{"line":143,"column":8},"end":{"line":144,"column":19}},"92":{"start":{"line":144,"column":12},"end":{"line":144,"column":19}},"93":{"start":{"line":145,"column":23},"end":{"line":145,"column":57}},"94":{"start":{"line":146,"column":8},"end":{"line":148,"column":null}},"95":{"start":{"line":147,"column":12},"end":{"line":147,"column":52}},"96":{"start":{"line":149,"column":8},"end":{"line":149,"column":61}},"97":{"start":{"line":153,"column":52},"end":{"line":153,"column":59}},"98":{"start":{"line":154,"column":8},"end":{"line":159,"column":null}},"99":{"start":{"line":155,"column":12},"end":{"line":158,"column":15}},"100":{"start":{"line":160,"column":8},"end":{"line":160,"column":78}},"101":{"start":{"line":161,"column":8},"end":{"line":161,"column":78}},"102":{"start":{"line":165,"column":8},"end":{"line":165,"column":25}},"103":{"start":{"line":169,"column":8},"end":{"line":172,"column":49}},"104":{"start":{"line":175,"column":0},"end":{"line":175,"column":27}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":2,"column":56},"end":{"line":2,"column":66}},"loc":{"start":{"line":2,"column":69},"end":{"line":4,"column":1}}},"1":{"name":"(anonymous_1)","decl":{"start":{"line":8,"column":12},"end":{"line":8,"column":13}},"loc":{"start":{"line":8,"column":20},"end":{"line":12,"column":1}}},"2":{"name":"(anonymous_2)","decl":{"start":{"line":10,"column":21},"end":{"line":10,"column":22}},"loc":{"start":{"line":10,"column":31},"end":{"line":10,"column":36}}},"3":{"name":"(anonymous_3)","decl":{"start":{"line":16,"column":4},"end":{"line":16,"column":16}},"loc":{"start":{"line":16,"column":22},"end":{"line":33,"column":5}}},"4":{"name":"(anonymous_4)","decl":{"start":{"line":34,"column":4},"end":{"line":34,"column":8}},"loc":{"start":{"line":34,"column":8},"end":{"line":63,"column":5}}},"5":{"name":"(anonymous_5)","decl":{"start":{"line":65,"column":4},"end":{"line":65,"column":20}},"loc":{"start":{"line":65,"column":20},"end":{"line":87,"column":5}}},"6":{"name":"(anonymous_6)","decl":{"start":{"line":89,"column":4},"end":{"line":89,"column":16}},"loc":{"start":{"line":89,"column":16},"end":{"line":104,"column":5}}},"7":{"name":"(anonymous_7)","decl":{"start":{"line":107,"column":4},"end":{"line":107,"column":12}},"loc":{"start":{"line":107,"column":12},"end":{"line":114,"column":5}}},"8":{"name":"(anonymous_8)","decl":{"start":{"line":116,"column":4},"end":{"line":116,"column":11}},"loc":{"start":{"line":116,"column":11},"end":{"line":139,"column":5}}},"9":{"name":"(anonymous_9)","decl":{"start":{"line":141,"column":4},"end":{"line":141,"column":15}},"loc":{"start":{"line":141,"column":21},"end":{"line":150,"column":5}}},"10":{"name":"(anonymous_10)","decl":{"start":{"line":152,"column":4},"end":{"line":152,"column":11}},"loc":{"start":{"line":152,"column":19},"end":{"line":162,"column":5}}},"11":{"name":"(anonymous_11)","decl":{"start":{"line":164,"column":4},"end":{"line":164,"column":15}},"loc":{"start":{"line":164,"column":15},"end":{"line":166,"column":5}}},"12":{"name":"(anonymous_12)","decl":{"start":{"line":168,"column":4},"end":{"line":168,"column":14}},"loc":{"start":{"line":168,"column":14},"end":{"line":173,"column":5}}}},"branchMap":{"0":{"loc":{"start":{"line":2,"column":22},"end":{"line":4,"column":1}},"type":"binary-expr","locations":[{"start":{"line":2,"column":23},"end":{"line":2,"column":27}},{"start":{"line":2,"column":31},"end":{"line":2,"column":51}},{"start":{"line":2,"column":56},"end":{"line":4,"column":1}}]},"1":{"loc":{"start":{"line":3,"column":11},"end":{"line":3,"column":61}},"type":"cond-expr","locations":[{"start":{"line":3,"column":37},"end":{"line":3,"column":40}},{"start":{"line":3,"column":43},"end":{"line":3,"column":61}}]},"2":{"loc":{"start":{"line":3,"column":12},"end":{"line":3,"column":33}},"type":"binary-expr","locations":[{"start":{"line":3,"column":12},"end":{"line":3,"column":15}},{"start":{"line":3,"column":19},"end":{"line":3,"column":33}}]},"3":{"loc":{"start":{"line":36,"column":8},"end":{"line":38,"column":null}},"type":"if","locations":[{"start":{"line":36,"column":8},"end":{"line":38,"column":null}}]},"4":{"loc":{"start":{"line":36,"column":12},"end":{"line":36,"column":42}},"type":"binary-expr","locations":[{"start":{"line":36,"column":12},"end":{"line":36,"column":21}},{"start":{"line":36,"column":25},"end":{"line":36,"column":42}}]},"5":{"loc":{"start":{"line":40,"column":8},"end":{"line":44,"column":null}},"type":"if","locations":[{"start":{"line":40,"column":8},"end":{"line":44,"column":null}}]},"6":{"loc":{"start":{"line":40,"column":12},"end":{"line":40,"column":77}},"type":"binary-expr","locations":[{"start":{"line":40,"column":12},"end":{"line":40,"column":42}},{"start":{"line":40,"column":46},"end":{"line":40,"column":77}}]},"7":{"loc":{"start":{"line":45,"column":8},"end":{"line":47,"column":null}},"type":"if","locations":[{"start":{"line":45,"column":8},"end":{"line":47,"column":null}}]},"8":{"loc":{"start":{"line":50,"column":8},"end":{"line":53,"column":null}},"type":"if","locations":[{"start":{"line":50,"column":8},"end":{"line":53,"column":null}}]},"9":{"loc":{"start":{"line":57,"column":8},"end":{"line":62,"column":null}},"type":"if","locations":[{"start":{"line":57,"column":8},"end":{"line":62,"column":null}},{"start":{"line":60,"column":13},"end":{"line":62,"column":null}}]},"10":{"loc":{"start":{"line":69,"column":8},"end":{"line":75,"column":null}},"type":"if","locations":[{"start":{"line":69,"column":8},"end":{"line":75,"column":null}}]},"11":{"loc":{"start":{"line":70,"column":12},"end":{"line":73,"column":65}},"type":"if","locations":[{"start":{"line":70,"column":12},"end":{"line":73,"column":65}},{"start":{"line":72,"column":17},"end":{"line":73,"column":65}}]},"12":{"loc":{"start":{"line":72,"column":17},"end":{"line":73,"column":65}},"type":"if","locations":[{"start":{"line":72,"column":17},"end":{"line":73,"column":65}}]},"13":{"loc":{"start":{"line":76,"column":8},"end":{"line":79,"column":null}},"type":"if","locations":[{"start":{"line":76,"column":8},"end":{"line":79,"column":null}}]},"14":{"loc":{"start":{"line":76,"column":12},"end":{"line":76,"column":36}},"type":"binary-expr","locations":[{"start":{"line":76,"column":12},"end":{"line":76,"column":22}},{"start":{"line":76,"column":26},"end":{"line":76,"column":36}}]},"15":{"loc":{"start":{"line":80,"column":8},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":80,"column":8},"end":{"line":85,"column":null}},{"start":{"line":83,"column":13},"end":{"line":85,"column":null}}]},"16":{"loc":{"start":{"line":83,"column":13},"end":{"line":85,"column":null}},"type":"if","locations":[{"start":{"line":83,"column":13},"end":{"line":85,"column":null}}]},"17":{"loc":{"start":{"line":86,"column":32},"end":{"line":86,"column":84}},"type":"cond-expr","locations":[{"start":{"line":86,"column":78},"end":{"line":86,"column":79}},{"start":{"line":86,"column":82},"end":{"line":86,"column":84}}]},"18":{"loc":{"start":{"line":91,"column":8},"end":{"line":93,"column":null}},"type":"if","locations":[{"start":{"line":91,"column":8},"end":{"line":93,"column":null}}]},"19":{"loc":{"start":{"line":94,"column":8},"end":{"line":97,"column":null}},"type":"if","locations":[{"start":{"line":94,"column":8},"end":{"line":97,"column":null}}]},"20":{"loc":{"start":{"line":100,"column":8},"end":{"line":102,"column":null}},"type":"if","locations":[{"start":{"line":100,"column":8},"end":{"line":102,"column":null}}]},"21":{"loc":{"start":{"line":109,"column":8},"end":{"line":113,"column":null}},"type":"if","locations":[{"start":{"line":109,"column":8},"end":{"line":113,"column":null}}]},"22":{"loc":{"start":{"line":110,"column":45},"end":{"line":110,"column":139}},"type":"cond-expr","locations":[{"start":{"line":110,"column":132},"end":{"line":110,"column":134}},{"start":{"line":110,"column":137},"end":{"line":110,"column":139}}]},"23":{"loc":{"start":{"line":110,"column":45},"end":{"line":110,"column":129}},"type":"binary-expr","locations":[{"start":{"line":110,"column":45},"end":{"line":110,"column":112}},{"start":{"line":110,"column":116},"end":{"line":110,"column":129}}]},"24":{"loc":{"start":{"line":117,"column":8},"end":{"line":138,"column":null}},"type":"if","locations":[{"start":{"line":117,"column":8},"end":{"line":138,"column":null}}]},"25":{"loc":{"start":{"line":119,"column":12},"end":{"line":122,"column":null}},"type":"if","locations":[{"start":{"line":119,"column":12},"end":{"line":122,"column":null}}]},"26":{"loc":{"start":{"line":119,"column":16},"end":{"line":120,"column":97}},"type":"binary-expr","locations":[{"start":{"line":119,"column":16},"end":{"line":119,"column":61}},{"start":{"line":120,"column":16},"end":{"line":120,"column":97}}]},"27":{"loc":{"start":{"line":121,"column":40},"end":{"line":121,"column":76}},"type":"cond-expr","locations":[{"start":{"line":121,"column":70},"end":{"line":121,"column":72}},{"start":{"line":121,"column":75},"end":{"line":121,"column":76}}]},"28":{"loc":{"start":{"line":126,"column":16},"end":{"line":130,"column":null}},"type":"if","locations":[{"start":{"line":126,"column":16},"end":{"line":130,"column":null}}]},"29":{"loc":{"start":{"line":132,"column":12},"end":{"line":133,"column":95}},"type":"if","locations":[{"start":{"line":132,"column":12},"end":{"line":133,"column":95}}]},"30":{"loc":{"start":{"line":135,"column":12},"end":{"line":137,"column":null}},"type":"if","locations":[{"start":{"line":135,"column":12},"end":{"line":137,"column":null}}]},"31":{"loc":{"start":{"line":135,"column":16},"end":{"line":135,"column":143}},"type":"binary-expr","locations":[{"start":{"line":135,"column":16},"end":{"line":135,"column":77}},{"start":{"line":135,"column":81},"end":{"line":135,"column":143}}]},"32":{"loc":{"start":{"line":143,"column":8},"end":{"line":144,"column":19}},"type":"if","locations":[{"start":{"line":143,"column":8},"end":{"line":144,"column":19}}]},"33":{"loc":{"start":{"line":146,"column":8},"end":{"line":148,"column":null}},"type":"if","locations":[{"start":{"line":146,"column":8},"end":{"line":148,"column":null}}]},"34":{"loc":{"start":{"line":154,"column":8},"end":{"line":159,"column":null}},"type":"if","locations":[{"start":{"line":154,"column":8},"end":{"line":159,"column":null}}]},"35":{"loc":{"start":{"line":169,"column":16},"end":{"line":172,"column":47}},"type":"binary-expr","locations":[{"start":{"line":169,"column":16},"end":{"line":169,"column":49}},{"start":{"line":170,"column":12},"end":{"line":170,"column":46}},{"start":{"line":171,"column":12},"end":{"line":171,"column":46}},{"start":{"line":171,"column":50},"end":{"line":171,"column":81}},{"start":{"line":172,"column":15},"end":{"line":172,"column":47}}]}},"s":{"0":1,"1":2,"2":1,"3":1,"4":1,"5":1,"6":0,"7":0,"8":0,"9":0,"10":1,"11":1,"12":1,"13":1,"14":1,"15":1,"16":1,"17":1,"18":1,"19":1,"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0,"37":0,"38":0,"39":0,"40":0,"41":0,"42":0,"43":0,"44":0,"45":0,"46":0,"47":0,"48":0,"49":0,"50":0,"51":0,"52":0,"53":0,"54":0,"55":0,"56":0,"57":0,"58":0,"59":0,"60":0,"61":0,"62":0,"63":0,"64":0,"65":0,"66":0,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0,"84":0,"85":0,"86":0,"87":0,"88":0,"89":0,"90":0,"91":0,"92":0,"93":0,"94":0,"95":0,"96":0,"97":0,"98":0,"99":0,"100":0,"101":0,"102":0,"103":0,"104":1},"f":{"0":2,"1":0,"2":0,"3":1,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0},"b":{"0":[1,1,1],"1":[2,0],"2":[2,2],"3":[0],"4":[0,0],"5":[0],"6":[0,0],"7":[0],"8":[0],"9":[0,0],"10":[0],"11":[0,0],"12":[0],"13":[0],"14":[0,0],"15":[0,0],"16":[0],"17":[0,0],"18":[0],"19":[0],"20":[0],"21":[0],"22":[0,0],"23":[0,0],"24":[0],"25":[0],"26":[0,0],"27":[0,0],"28":[0],"29":[0],"30":[0],"31":[0,0],"32":[0],"33":[0],"34":[0],"35":[0,0,0,0,0]}} +,"/Users/shaysheller/Desktop/coding-challenge/build/output.js": {"path":"/Users/shaysheller/Desktop/coding-challenge/build/output.js","statementMap":{"0":{"start":{"line":2,"column":22},"end":{"line":12,"column":3}},"1":{"start":{"line":3,"column":4},"end":{"line":3,"column":33}},"2":{"start":{"line":3,"column":26},"end":{"line":3,"column":33}},"3":{"start":{"line":4,"column":15},"end":{"line":4,"column":52}},"4":{"start":{"line":5,"column":4},"end":{"line":7,"column":null}},"5":{"start":{"line":6,"column":6},"end":{"line":6,"column":68}},"6":{"start":{"line":6,"column":51},"end":{"line":6,"column":63}},"7":{"start":{"line":8,"column":4},"end":{"line":8,"column":39}},"8":{"start":{"line":10,"column":4},"end":{"line":10,"column":33}},"9":{"start":{"line":10,"column":26},"end":{"line":10,"column":33}},"10":{"start":{"line":11,"column":4},"end":{"line":11,"column":17}},"11":{"start":{"line":13,"column":25},"end":{"line":17,"column":2}},"12":{"start":{"line":14,"column":4},"end":{"line":14,"column":72}},"13":{"start":{"line":16,"column":4},"end":{"line":16,"column":21}},"14":{"start":{"line":18,"column":19},"end":{"line":24,"column":1}},"15":{"start":{"line":19,"column":4},"end":{"line":19,"column":42}},"16":{"start":{"line":19,"column":31},"end":{"line":19,"column":42}},"17":{"start":{"line":20,"column":17},"end":{"line":20,"column":19}},"18":{"start":{"line":21,"column":4},"end":{"line":21,"column":141}},"19":{"start":{"line":21,"column":21},"end":{"line":21,"column":141}},"20":{"start":{"line":21,"column":40},"end":{"line":21,"column":141}},"21":{"start":{"line":21,"column":109},"end":{"line":21,"column":141}},"22":{"start":{"line":22,"column":4},"end":{"line":22,"column":36}},"23":{"start":{"line":23,"column":4},"end":{"line":23,"column":18}},"24":{"start":{"line":25,"column":0},"end":{"line":25,"column":62}},"25":{"start":{"line":27,"column":11},"end":{"line":27,"column":38}},"26":{"start":{"line":29,"column":11},"end":{"line":29,"column":38}},"27":{"start":{"line":32,"column":8},"end":{"line":32,"column":39}},"28":{"start":{"line":35,"column":21},"end":{"line":35,"column":31}},"29":{"start":{"line":36,"column":22},"end":{"line":36,"column":37}},"30":{"start":{"line":37,"column":24},"end":{"line":37,"column":41}},"31":{"start":{"line":38,"column":24},"end":{"line":38,"column":41}},"32":{"start":{"line":39,"column":29},"end":{"line":39,"column":70}},"33":{"start":{"line":40,"column":8},"end":{"line":40,"column":70}},"34":{"start":{"line":43,"column":0},"end":{"line":43,"column":25}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":2,"column":74},"end":{"line":2,"column":83}},"loc":{"start":{"line":2,"column":94},"end":{"line":9,"column":1}}},"1":{"name":"(anonymous_1)","decl":{"start":{"line":6,"column":38},"end":{"line":6,"column":51}},"loc":{"start":{"line":6,"column":38},"end":{"line":6,"column":65}}},"2":{"name":"(anonymous_2)","decl":{"start":{"line":9,"column":6},"end":{"line":9,"column":15}},"loc":{"start":{"line":9,"column":26},"end":{"line":12,"column":1}}},"3":{"name":"(anonymous_3)","decl":{"start":{"line":13,"column":80},"end":{"line":13,"column":89}},"loc":{"start":{"line":13,"column":93},"end":{"line":15,"column":1}}},"4":{"name":"(anonymous_4)","decl":{"start":{"line":15,"column":5},"end":{"line":15,"column":14}},"loc":{"start":{"line":15,"column":18},"end":{"line":17,"column":1}}},"5":{"name":"(anonymous_5)","decl":{"start":{"line":18,"column":50},"end":{"line":18,"column":60}},"loc":{"start":{"line":18,"column":63},"end":{"line":24,"column":1}}},"6":{"name":"(anonymous_6)","decl":{"start":{"line":31,"column":4},"end":{"line":31,"column":16}},"loc":{"start":{"line":31,"column":24},"end":{"line":33,"column":5}}},"7":{"name":"(anonymous_7)","decl":{"start":{"line":34,"column":4},"end":{"line":34,"column":10}},"loc":{"start":{"line":34,"column":14},"end":{"line":41,"column":5}}}},"branchMap":{"0":{"loc":{"start":{"line":2,"column":22},"end":{"line":12,"column":3}},"type":"binary-expr","locations":[{"start":{"line":2,"column":23},"end":{"line":2,"column":27}},{"start":{"line":2,"column":31},"end":{"line":2,"column":51}},{"start":{"line":2,"column":57},"end":{"line":12,"column":2}}]},"1":{"loc":{"start":{"line":2,"column":57},"end":{"line":12,"column":2}},"type":"cond-expr","locations":[{"start":{"line":2,"column":74},"end":{"line":9,"column":1}},{"start":{"line":9,"column":6},"end":{"line":12,"column":1}}]},"2":{"loc":{"start":{"line":3,"column":4},"end":{"line":3,"column":33}},"type":"if","locations":[{"start":{"line":3,"column":4},"end":{"line":3,"column":33}}]},"3":{"loc":{"start":{"line":5,"column":4},"end":{"line":7,"column":null}},"type":"if","locations":[{"start":{"line":5,"column":4},"end":{"line":7,"column":null}}]},"4":{"loc":{"start":{"line":5,"column":8},"end":{"line":5,"column":85}},"type":"binary-expr","locations":[{"start":{"line":5,"column":8},"end":{"line":5,"column":13}},{"start":{"line":5,"column":18},"end":{"line":5,"column":84}}]},"5":{"loc":{"start":{"line":5,"column":18},"end":{"line":5,"column":84}},"type":"cond-expr","locations":[{"start":{"line":5,"column":34},"end":{"line":5,"column":47}},{"start":{"line":5,"column":50},"end":{"line":5,"column":84}}]},"6":{"loc":{"start":{"line":5,"column":50},"end":{"line":5,"column":84}},"type":"binary-expr","locations":[{"start":{"line":5,"column":50},"end":{"line":5,"column":63}},{"start":{"line":5,"column":67},"end":{"line":5,"column":84}}]},"7":{"loc":{"start":{"line":10,"column":4},"end":{"line":10,"column":33}},"type":"if","locations":[{"start":{"line":10,"column":4},"end":{"line":10,"column":33}}]},"8":{"loc":{"start":{"line":13,"column":25},"end":{"line":17,"column":2}},"type":"binary-expr","locations":[{"start":{"line":13,"column":26},"end":{"line":13,"column":30}},{"start":{"line":13,"column":34},"end":{"line":13,"column":57}},{"start":{"line":13,"column":63},"end":{"line":17,"column":1}}]},"9":{"loc":{"start":{"line":13,"column":63},"end":{"line":17,"column":1}},"type":"cond-expr","locations":[{"start":{"line":13,"column":80},"end":{"line":15,"column":1}},{"start":{"line":15,"column":5},"end":{"line":17,"column":1}}]},"10":{"loc":{"start":{"line":18,"column":19},"end":{"line":24,"column":1}},"type":"binary-expr","locations":[{"start":{"line":18,"column":20},"end":{"line":18,"column":24}},{"start":{"line":18,"column":28},"end":{"line":18,"column":45}},{"start":{"line":18,"column":50},"end":{"line":24,"column":1}}]},"11":{"loc":{"start":{"line":19,"column":4},"end":{"line":19,"column":42}},"type":"if","locations":[{"start":{"line":19,"column":4},"end":{"line":19,"column":42}}]},"12":{"loc":{"start":{"line":19,"column":8},"end":{"line":19,"column":29}},"type":"binary-expr","locations":[{"start":{"line":19,"column":8},"end":{"line":19,"column":11}},{"start":{"line":19,"column":15},"end":{"line":19,"column":29}}]},"13":{"loc":{"start":{"line":21,"column":4},"end":{"line":21,"column":141}},"type":"if","locations":[{"start":{"line":21,"column":4},"end":{"line":21,"column":141}}]},"14":{"loc":{"start":{"line":21,"column":40},"end":{"line":21,"column":141}},"type":"if","locations":[{"start":{"line":21,"column":40},"end":{"line":21,"column":141}}]},"15":{"loc":{"start":{"line":21,"column":44},"end":{"line":21,"column":107}},"type":"binary-expr","locations":[{"start":{"line":21,"column":44},"end":{"line":21,"column":59}},{"start":{"line":21,"column":63},"end":{"line":21,"column":107}}]}},"s":{"0":1,"1":122,"2":122,"3":122,"4":122,"5":116,"6":0,"7":122,"8":0,"9":0,"10":0,"11":1,"12":2,"13":0,"14":1,"15":2,"16":0,"17":2,"18":2,"19":2,"20":122,"21":122,"22":2,"23":2,"24":1,"25":1,"26":1,"27":1,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":1},"f":{"0":122,"1":0,"2":0,"3":2,"4":0,"5":2,"6":1,"7":0},"b":{"0":[1,1,1],"1":[1,0],"2":[122],"3":[116],"4":[122,122],"5":[5,117],"6":[117,8],"7":[0],"8":[1,1,1],"9":[1,0],"10":[1,1,1],"11":[0],"12":[2,2],"13":[2],"14":[122],"15":[122,122]}} +,"/Users/shaysheller/Desktop/coding-challenge/build/requestMap.js": {"path":"/Users/shaysheller/Desktop/coding-challenge/build/requestMap.js","statementMap":{"0":{"start":{"line":4,"column":0},"end":{"line":4,"column":62}},"1":{"start":{"line":7,"column":8},"end":{"line":7,"column":29}},"2":{"start":{"line":8,"column":8},"end":{"line":8,"column":22}},"3":{"start":{"line":9,"column":8},"end":{"line":9,"column":22}},"4":{"start":{"line":12,"column":8},"end":{"line":12,"column":33}},"5":{"start":{"line":13,"column":8},"end":{"line":16,"column":null}},"6":{"start":{"line":14,"column":12},"end":{"line":14,"column":27}},"7":{"start":{"line":15,"column":12},"end":{"line":15,"column":27}},"8":{"start":{"line":17,"column":8},"end":{"line":18,"column":27}},"9":{"start":{"line":18,"column":12},"end":{"line":18,"column":27}},"10":{"start":{"line":19,"column":8},"end":{"line":20,"column":27}},"11":{"start":{"line":20,"column":12},"end":{"line":20,"column":27}},"12":{"start":{"line":23,"column":8},"end":{"line":23,"column":29}},"13":{"start":{"line":24,"column":8},"end":{"line":25,"column":26}},"14":{"start":{"line":25,"column":12},"end":{"line":25,"column":26}},"15":{"start":{"line":26,"column":8},"end":{"line":27,"column":26}},"16":{"start":{"line":27,"column":12},"end":{"line":27,"column":26}},"17":{"start":{"line":30,"column":8},"end":{"line":33,"column":null}},"18":{"start":{"line":31,"column":12},"end":{"line":31,"column":26}},"19":{"start":{"line":32,"column":12},"end":{"line":32,"column":19}},"20":{"start":{"line":34,"column":8},"end":{"line":34,"column":60}},"21":{"start":{"line":37,"column":8},"end":{"line":40,"column":null}},"22":{"start":{"line":38,"column":12},"end":{"line":38,"column":26}},"23":{"start":{"line":39,"column":12},"end":{"line":39,"column":19}},"24":{"start":{"line":41,"column":8},"end":{"line":41,"column":60}},"25":{"start":{"line":44,"column":0},"end":{"line":44,"column":29}}},"fnMap":{"0":{"name":"(anonymous_0)","decl":{"start":{"line":6,"column":4},"end":{"line":6,"column":null}},"loc":{"start":{"line":6,"column":4},"end":{"line":10,"column":5}}},"1":{"name":"(anonymous_1)","decl":{"start":{"line":11,"column":4},"end":{"line":11,"column":7}},"loc":{"start":{"line":11,"column":18},"end":{"line":21,"column":5}}},"2":{"name":"(anonymous_2)","decl":{"start":{"line":22,"column":4},"end":{"line":22,"column":10}},"loc":{"start":{"line":22,"column":14},"end":{"line":28,"column":5}}},"3":{"name":"(anonymous_3)","decl":{"start":{"line":29,"column":4},"end":{"line":29,"column":10}},"loc":{"start":{"line":29,"column":10},"end":{"line":35,"column":5}}},"4":{"name":"(anonymous_4)","decl":{"start":{"line":36,"column":4},"end":{"line":36,"column":10}},"loc":{"start":{"line":36,"column":10},"end":{"line":42,"column":5}}}},"branchMap":{"0":{"loc":{"start":{"line":13,"column":8},"end":{"line":16,"column":null}},"type":"if","locations":[{"start":{"line":13,"column":8},"end":{"line":16,"column":null}}]},"1":{"loc":{"start":{"line":17,"column":8},"end":{"line":18,"column":27}},"type":"if","locations":[{"start":{"line":17,"column":8},"end":{"line":18,"column":27}}]},"2":{"loc":{"start":{"line":19,"column":8},"end":{"line":20,"column":27}},"type":"if","locations":[{"start":{"line":19,"column":8},"end":{"line":20,"column":27}}]},"3":{"loc":{"start":{"line":19,"column":12},"end":{"line":19,"column":45}},"type":"binary-expr","locations":[{"start":{"line":19,"column":12},"end":{"line":19,"column":26}},{"start":{"line":19,"column":30},"end":{"line":19,"column":45}}]},"4":{"loc":{"start":{"line":24,"column":8},"end":{"line":25,"column":26}},"type":"if","locations":[{"start":{"line":24,"column":8},"end":{"line":25,"column":26}}]},"5":{"loc":{"start":{"line":26,"column":8},"end":{"line":27,"column":26}},"type":"if","locations":[{"start":{"line":26,"column":8},"end":{"line":27,"column":26}}]},"6":{"loc":{"start":{"line":30,"column":8},"end":{"line":33,"column":null}},"type":"if","locations":[{"start":{"line":30,"column":8},"end":{"line":33,"column":null}}]},"7":{"loc":{"start":{"line":37,"column":8},"end":{"line":40,"column":null}},"type":"if","locations":[{"start":{"line":37,"column":8},"end":{"line":40,"column":null}}]}},"s":{"0":2,"1":8,"2":8,"3":8,"4":9,"5":9,"6":0,"7":0,"8":9,"9":8,"10":9,"11":6,"12":3,"13":3,"14":2,"15":3,"16":2,"17":2,"18":1,"19":1,"20":1,"21":2,"22":1,"23":1,"24":1,"25":2},"f":{"0":8,"1":9,"2":3,"3":2,"4":2},"b":{"0":[0],"1":[8],"2":[6],"3":[9,8],"4":[2],"5":[2],"6":[1],"7":[1]}} +} diff --git a/coverage/lcov-report/elevator.js.html b/coverage/lcov-report/elevator.js.html new file mode 100644 index 0000000..ee64ae1 --- /dev/null +++ b/coverage/lcov-report/elevator.js.html @@ -0,0 +1,646 @@ + + + + + + Code coverage report for elevator.js + + + + + + + + + +
+
+

All files elevator.js

+
+ +
+ 21.9% + Statements + 23/105 +
+ + +
+ 10.71% + Branches + 6/56 +
+ + +
+ 15.38% + Functions + 2/13 +
+ + +
+ 22.33% + Lines + 23/103 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188  +1x +2x +  +1x +1x +1x +1x +  +  +  +  +  +  +  +  +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +1x +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1x +  +  +  +  +  +  +  +  +  +  +  +  + 
"use strict";
+var __importDefault = (this && this.__importDefault) || function (mod) {
+    return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+const requestMap_js_1 = __importDefault(require("./requestMap.js"));
+const output_js_1 = __importDefault(require("./output.js"));
+const sum = (arr) => {
+    let sum = 0;
+    sum = arr.reduce((a, b) => a + b);
+    return sum;
+};
+// internal request : buttons pressed from inside the elevator by passengers
+// external requets : buttons pressed on floor N going U or D 
+class Elevator {
+    constructor(floors) {
+        this.floors = floors;
+        this.state = 'stopped';
+        this.currentFloor = 0;
+        this.currentDirection = 1;
+        this.currentDestination = -1;
+        this.travelInterval = 3000;
+        this.stopInterval = 1000;
+        this.quit = false;
+        this.currentWeight = 0;
+        this.weightLimit = 50;
+        this.departureRequestMap = new requestMap_js_1.default(); // maybe it makes sense to have this be a priority queue? 
+        this.externalRequestMap = new requestMap_js_1.default();
+        this.passengerRequestQueue = [];
+        this.boardingPassengers = [];
+        this.departingPassengers = [];
+        this.output = new output_js_1.default('output.txt');
+    }
+    move() {
+        this.move = this.move.bind(this);
+        Iif (this.quit && this.endProcess()) {
+            process.exit();
+        }
+        // check if anyone is getting on or off at current floor
+        Iif (this.boardingPassengers.length || this.departingPassengers.length) {
+            this.output.output('Stopped on floor: ' + this.currentFloor);
+            this.stopAndBoard();
+            return;
+        }
+        Iif (this.state === 'moving') {
+            this.output.output('Passing floor: ' + this.currentFloor);
+        }
+        this.checkDestination();
+        // increment / decrement current floor and change state to moving if there is a current destination
+        Iif (this.currentDestination !== -1) {
+            this.currentFloor += this.currentDirection;
+            this.state = 'moving';
+        }
+        // check if anyone is getting on / off at upcoming floor
+        this.checkOff();
+        this.checkOn();
+        if (this.state === 'moving') {
+            setTimeout(this.move, this.travelInterval);
+        }
+        else {
+            setTimeout(this.move, this.stopInterval);
+        }
+    }
+    // need to chagne it so we aren't taking min of -1 and another number
+    checkDestination() {
+        let min = this.departureRequestMap.min;
+        let max = this.departureRequestMap.max;
+        //if we are at or above the weight limit don't consider external requests
+        Iif (this.currentWeight < this.weightLimit) {
+            if (min === -1)
+                min = this.externalRequestMap.min;
+            else Iif (this.externalRequestMap.min !== -1)
+                min = Math.min(this.externalRequestMap.min, min);
+            max = Math.max(this.externalRequestMap.max, max);
+        }
+        Iif (min === -1 && max === -1) {
+            this.currentDestination = -1;
+            return;
+        }
+        if (this.currentDirection === 1) {
+            this.currentDestination = max;
+        }
+        else Iif (this.currentDirection === -1) {
+            this.currentDestination = min;
+        }
+        this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1;
+    }
+    // stops elevator and boards / deboards passengers depending on their request
+    stopAndBoard() {
+        this.state = 'stopped';
+        Iif (this.departingPassengers.length) {
+            this.output.output(this.departingPassengers.length + ' passenger(s) got off ');
+        }
+        Iif (this.boardingPassengers.length) {
+            this.passengerRequestQueue.push(...this.boardingPassengers);
+            this.output.output((this.boardingPassengers.length + ' passenger(s) got on '));
+        }
+        this.departingPassengers = [];
+        this.boardingPassengers = [];
+        Iif (this.currentFloor === this.currentDestination) {
+            this.checkDestination();
+        }
+        setTimeout(this.move, this.stopInterval);
+    }
+    // check who is getting off the elevator while it is in transit from floor n to floor n +/- 1
+    // decrements weight of passengers getting off
+    checkOff() {
+        var _a;
+        Iif (this.departureRequestMap.map.get(this.currentFloor) !== undefined) {
+            this.departingPassengers.push(...(_a = this.departureRequestMap.map.get(this.currentFloor)) !== null && _a !== void 0 ? _a : []);
+            this.currentWeight -= sum(this.departingPassengers);
+            this.departureRequestMap.delete(this.currentFloor);
+        }
+    }
+    // checks who is getting on based on direction elevator is traveling and currentWeight of elevator
+    checkOn() {
+        Iif (this.externalRequestMap.map.get(this.currentFloor) !== undefined) {
+            // if elevator has reached destination floor it needs to change direction if the request is in the opposite direction
+            Iif (this.currentFloor === this.currentDestination &&
+                !this.externalRequestMap.map.get(this.currentFloor)[this.currentDirection].length) {
+                this.currentDirection = this.currentDirection === 1 ? -1 : 1;
+            }
+            const boardingArr = this.externalRequestMap.map.get(this.currentFloor)[this.currentDirection];
+            for (let i = boardingArr.length - 1; i >= 0; i--) {
+                let currentBoarder = boardingArr[i];
+                Iif (currentBoarder + this.currentWeight <= this.weightLimit) {
+                    this.boardingPassengers.push(currentBoarder);
+                    boardingArr.pop();
+                    this.currentWeight += currentBoarder;
+                }
+            }
+            Iif (!boardingArr.length)
+                this.externalRequestMap.map.get(this.currentFloor)[this.currentDirection] = [];
+            // clears request Obj of current floor if there aren't any more requests on this floor
+            Iif (!this.externalRequestMap.map.get(this.currentFloor)[1].length && !this.externalRequestMap.map.get(this.currentFloor)[-1].length) {
+                this.externalRequestMap.delete(this.currentFloor);
+            }
+        }
+    }
+    // internal floor request sets their destination in departureRequestMap
+    selectFloor(floor) {
+        this.output.output('Floor ' + floor + ' requested internally');
+        Iif (!this.passengerRequestQueue.length)
+            return;
+        const weight = this.passengerRequestQueue.shift();
+        Iif (this.departureRequestMap.map.get(floor) === undefined) {
+            this.departureRequestMap.set(floor, []);
+        }
+        this.departureRequestMap.map.get(floor).push(weight);
+    }
+    // handles external request
+    request(request) {
+        const { currentFloor, direction, weight } = request;
+        Iif (this.externalRequestMap.map.get(currentFloor) === undefined) {
+            this.externalRequestMap.set(currentFloor, {
+                '1': [],
+                '-1': []
+            });
+        }
+        this.externalRequestMap.map.get(currentFloor)[direction].push(weight);
+        this.output.output('Floor ' + currentFloor + ' requested externally');
+    }
+    // when quit is typed into console
+    stopProcess() {
+        this.quit = true;
+    }
+    // will end when all requests have been served and all passengers are off the elevator
+    endProcess() {
+        return (!this.externalRequestMap.map.size &&
+            !this.passengerRequestQueue.length &&
+            !this.departureRequestMap.map.size && !this.boardingPassengers.length
+            && !this.departingPassengers.length);
+    }
+}
+exports.default = Elevator;
+// testMatch: ['*/__tests__/**/*.ts?(x)', '**/?(*.)+(test).ts?(x)'],
+// module.exports = {
+//   preset: 'ts-jest',
+//   transform: {
+//     '^.+\\.(t|j)s?$': 'ts-jest',
+//     '^.+\\.(js|jsx)$': 'babel-jest'
+//   },
+//   testMatch: ['*/__tests__/**/*.ts?(x)', '**/?(*.)+(test).ts?(x)'],
+//   testTimeout: 5000,
+//   modulePaths: ['<rootDir>'],
+//   testEnvironment: 'node'
+// };
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/index.html b/coverage/lcov-report/index.html index 5ec5509..04a9d97 100644 --- a/coverage/lcov-report/index.html +++ b/coverage/lcov-report/index.html @@ -23,30 +23,30 @@

All files

- Unknown% + 42.16% Statements - 0/0 + 70/166
- Unknown% + 41.48% Branches - 0/0 + 39/94
- Unknown% + 42.3% Functions - 0/0 + 11/26
- Unknown% + 42.03% Lines - 0/0 + 66/157
@@ -61,7 +61,7 @@

All files

-
+
@@ -78,7 +78,52 @@

All files

- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
elevator.js +
+
21.9%23/10510.71%6/5615.38%2/1322.33%23/103
output.js +
+
65.71%23/3586.2%25/2950%4/867.85%19/28
requestMap.js +
+
92.3%24/2688.88%8/9100%5/592.3%24/26
@@ -86,7 +131,7 @@

All files

+ + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/requestMap.js.html b/coverage/lcov-report/requestMap.js.html new file mode 100644 index 0000000..1ef58bc --- /dev/null +++ b/coverage/lcov-report/requestMap.js.html @@ -0,0 +1,217 @@ + + + + + + Code coverage report for requestMap.js + + + + + + + + + +
+
+

All files requestMap.js

+
+ +
+ 92.3% + Statements + 24/26 +
+ + +
+ 88.88% + Branches + 8/9 +
+ + +
+ 100% + Functions + 5/5 +
+ + +
+ 92.3% + Lines + 24/26 +
+ + +
+

+ Press n or j to go to the next uncovered block, b, p or k for the previous block. +

+ +
+
+

+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45  +  +  +2x +  +  +8x +8x +8x +  +  +9x +9x +  +  +  +9x +8x +9x +6x +  +  +3x +3x +2x +3x +2x +  +  +2x +1x +1x +  +1x +  +  +2x +1x +1x +  +1x +  +  +2x + 
"use strict";
+// keep track of max / min 
+// be a normal object
+Object.defineProperty(exports, "__esModule", { value: true });
+class RequestMap {
+    constructor() {
+        this.map = new Map();
+        this.max = -1;
+        this.min = -1;
+    }
+    set(key, value) {
+        this.map.set(key, value);
+        Iif (this.map.size === 0) {
+            this.min = key;
+            this.max = key;
+        }
+        if (key > this.max)
+            this.max = key;
+        if (key < this.min || this.min === -1)
+            this.min = key;
+    }
+    delete(key) {
+        this.map.delete(key);
+        if (key === this.min)
+            this.setMin();
+        if (key === this.max)
+            this.setMax();
+    }
+    setMin() {
+        if (!this.map.size) {
+            this.min = -1;
+            return;
+        }
+        this.min = Math.min(...Array.from(this.map.keys()));
+    }
+    setMax() {
+        if (!this.map.size) {
+            this.max = -1;
+            return;
+        }
+        this.max = Math.max(...Array.from(this.map.keys()));
+    }
+}
+exports.default = RequestMap;
+ 
+ +
+
+ + + + + + + + \ No newline at end of file diff --git a/coverage/lcov-report/requestMap.ts.html b/coverage/lcov-report/requestMap.ts.html index c6a2ce7..920b4b7 100644 --- a/coverage/lcov-report/requestMap.ts.html +++ b/coverage/lcov-report/requestMap.ts.html @@ -23,16 +23,16 @@

All files requestMap.ts

- 90.9% + 92% Statements - 20/22 + 23/25
- 100% + 88.88% Branches - 6/6 + 8/9
@@ -44,9 +44,9 @@

All files requestMap.ts

- 88.88% + 90.47% Lines - 16/18 + 19/21
@@ -119,10 +119,7 @@

All files requestMap.ts

54 55 56 -57 -58 -59 -60  +57        @@ -140,7 +137,7 @@

All files requestMap.ts

    9x -  +9x       @@ -157,7 +154,7 @@

All files requestMap.ts

      -  +2x 1x 1x   @@ -166,7 +163,7 @@

All files requestMap.ts

      -  +2x 1x 1x   @@ -178,9 +175,6 @@

All files requestMap.ts

      -  -  -  1x
// keep track of max / min 
 // be a normal object
  
@@ -199,7 +193,7 @@ 

All files requestMap.ts

  set(key: number, value: T) { this.map.set(key, value); - if(this.map.size === 0) { + Iif(this.map.size === 0) { this.min = key; this.max = key; } @@ -232,14 +226,11 @@

All files requestMap.ts

this.max = Math.max(...Array.from(this.map.keys())); }   -  -  -  -  }       +  export default RequestMap;
@@ -247,7 +238,7 @@

All files requestMap.ts

- - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/elevator.ts.html b/coverage/lcov-report/elevator.ts.html deleted file mode 100644 index f298086..0000000 --- a/coverage/lcov-report/elevator.ts.html +++ /dev/null @@ -1,787 +0,0 @@ - - - - - - Code coverage report for elevator.ts - - - - - - - - - -
-
-

All files elevator.ts

-
- -
- 39.02% - Statements - 32/82 -
- - -
- 21.42% - Branches - 6/28 -
- - -
- 41.66% - Functions - 5/12 -
- - -
- 40.25% - Lines - 31/77 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -1x -  -  -  -1x -  -1x -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  - 
import {ElevatorRequest, DirectionObject, direction} from './types';
-import RequestMap from './requestMap';
-import Output from './output';
- 
-const sum = (arr: number[]) => {
-  let sum = 0;
-  sum = arr.reduce((a, b) => a + b);
-  return sum;
-};
- 
- 
-// internal request : buttons pressed from inside the elevator by passengers
-// external requets : buttons pressed on floor N going U or D 
- 
-class Elevator { 
- 
-  floors: number;
-  state: 'stopped' | 'moving';
-  currentFloor: number;
-  currentDirection: direction;
-  currentDestination: number;
-  travelInterval: number;
-  stopInterval: number;
-  quit: boolean;
-  currentWeight: number;
-  weightLimit: number;
-  departureRequestMap: RequestMap<number[]>;
-  externalRequestMap: RequestMap<DirectionObject>;
-  passengerRequestQueue: number[];
-  boardingPassengers: number[];
-  departingPassengers: number[];
-  output: Output;
- 
-  constructor(floors: number) {
-    this.floors = floors;
-    this.state = 'stopped'
-    this.currentFloor = 0;
-    this.currentDirection = 1;
-    this.currentDestination = -1;
-    this.travelInterval = 3000;
-    this.stopInterval = 1000;
-    this.quit = false;
-    this.currentWeight = 0;
-    this.weightLimit = 50;
-    this.departureRequestMap = new RequestMap<number[]>();// maybe it makes sense to have this be a priority queue? 
-    this.externalRequestMap = new RequestMap<DirectionObject>();
-    this.passengerRequestQueue = [];
-    this.boardingPassengers = [];
-    this.departingPassengers = [];
-    this.output = new Output('output.txt');
-  }
- 
-  move() {
- 
-    this.move = this.move.bind(this);
- 
-    if(this.quit && this.endProcess()) {
-      process.exit();
-    }
-    
-    // check if anyone is getting on or off at current floor
-    if(this.boardingPassengers.length || this.departingPassengers.length) {
-      this.output.output('Stopped on floor: ' + this.currentFloor);
-      this.stopAndBoard();
-      return;
-    } 
- 
-    if(this.state === 'moving') {
-      this.output.output('Passing floor: ' + this.currentFloor);
-    }
- 
-    this.checkDestination(); 
-    
-    // increment / decrement current floor and change state to moving if there is a current destination
-    if(this.currentDestination !== -1) {
-      this.currentFloor += this.currentDirection;
-      this.state = 'moving';
-    }
- 
-    // check if anyone is getting on / off at upcoming floor
-    this.checkOff();
-    this.checkOn();
- 
-    
-    if(this.state === 'moving') {
-      setTimeout(this.move, this.travelInterval);
-    } else {
-      setTimeout(this.move, this.stopInterval);
-    }
-    
-  }
- 
- 
-  // need to chagne it so we aren't taking min of -1 and another number
-  checkDestination() {
- 
-    let min = this.departureRequestMap.min;
-    let max = this.departureRequestMap.max;
-    
-    //if we are at or above the weight limit don't consider external requests
-    if(this.currentWeight < this.weightLimit) {
-      if(min === -1) min = this.externalRequestMap.min;
-      else IEif (this.externalRequestMap.min !== -1) min = Math.min(this.externalRequestMap.min, min);
-      max = Math.max(this.externalRequestMap.max, max);
-    }
- 
-    if(min === -1 && max === -1) {
-      this.currentDestination = -1;
-      return;
-    }
- 
-    if(this.currentDirection === 1) {
-      this.currentDestination = max;
-    } else if(this.currentDirection === -1) {
-      this.currentDestination = min;
-    }
- 
-    this.currentDirection = this.currentFloor < this.currentDestination ? 1 : -1;
- 
-  }
- 
-  // stops elevator and boards / deboards passengers depending on their request
-  stopAndBoard() {
-  
-    this.state = 'stopped';
- 
-    if(this.departingPassengers.length) {
-      this.output.output(this.departingPassengers.length + ' passenger(s) got off ');
-    }
- 
-    if(this.boardingPassengers.length) {
-      this.passengerRequestQueue.push(...this.boardingPassengers);
-      this.output.output((this.boardingPassengers.length + ' passenger(s) got on '));
-    }
- 
-    this.departingPassengers = [];
-    this.boardingPassengers = [];
- 
-    if(this.currentFloor === this.currentDestination){
-      this.checkDestination();
-    } 
- 
-    setTimeout(this.move, this.stopInterval);
-  }
-  
-  // check who is getting off the elevator while it is in transit from floor n to floor n +/- 1
-  // decrements weight of passengers getting off
-  checkOff() {
- 
-    if(this.departureRequestMap.map.get(this.currentFloor) !== undefined) {
-      this.departingPassengers.push(...this.departureRequestMap.map.get(this.currentFloor) ?? []);
-      this.currentWeight -= sum(this.departingPassengers);
-      this.departureRequestMap.delete(this.currentFloor);
-    }
-  }
- 
-  // checks who is getting on based on direction elevator is traveling and currentWeight of elevator
-  checkOn() {
-    
-    if(this.externalRequestMap.map.get(this.currentFloor) !== undefined) {
-      // if elevator has reached destination floor it needs to change direction if the request is in the opposite direction
-      if(this.currentFloor === this.currentDestination && 
-        !this.externalRequestMap.map.get(this.currentFloor)![this.currentDirection].length) {
-          this.currentDirection = this.currentDirection === 1 ? -1 : 1;
-      }
- 
-      const boardingArr = this.externalRequestMap.map.get(this.currentFloor)![this.currentDirection];
-      for(let i = boardingArr.length - 1; i >= 0; i--) {
-        let currentBoarder = boardingArr[i];
-        if(currentBoarder + this.currentWeight <= this.weightLimit) {
-          this.boardingPassengers.push(currentBoarder);
-          boardingArr.pop();
-          this.currentWeight += currentBoarder;
-        }
-      }
-      Iif(!boardingArr.length) this.externalRequestMap.map.get(this.currentFloor)![this.currentDirection] = [];
-      
-      // clears request Obj of current floor if there aren't any more requests on this floor
-      if(!this.externalRequestMap.map.get(this.currentFloor)![1].length && !this.externalRequestMap.map.get(this.currentFloor)![-1].length) {
-          this.externalRequestMap.delete(this.currentFloor);
-      }
- 
-    }
-  }
- 
-  // internal floor request sets their destination in departureRequestMap
-  selectFloor(floor: number) {
-    this.output.output('Floor ' + floor + ' requested internally');
- 
-    Iif(!this.passengerRequestQueue.length) return;
- 
-    const weight = this.passengerRequestQueue.shift()!;
-    if(this.departureRequestMap.map.get(floor) === undefined) {
-      this.departureRequestMap.set(floor, []);
-    }
- 
-    this.departureRequestMap.map.get(floor)!.push(weight);
-    
-  }
- 
-  // handles external request
-  request(request: ElevatorRequest) {
-    
-    const {currentFloor, direction, weight} = request;
- 
-    if(this.externalRequestMap.map.get(currentFloor) === undefined) {
-      this.externalRequestMap.set(currentFloor, {
-        '1': [],
-        '-1': []
-      })
-    }
-    this.externalRequestMap.map.get(currentFloor)![direction].push(weight);
-    this.output.output('Floor ' + currentFloor + ' requested externally');
- 
-  }
- 
-  // when quit is typed into console
-  stopProcess() {
-    this.quit = true;
-  }
- 
-  // will end when all requests have been served and all passengers are off the elevator
-  endProcess() {
-    return (!this.externalRequestMap.map.size && 
-    !this.passengerRequestQueue.length && 
-    !this.departureRequestMap.map.size && !this.boardingPassengers.length
-    && !this.departingPassengers.length)
-  }
- 
-}
- 
-export default Elevator;
- 
- 
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/favicon.png b/coverage/lcov-report/favicon.png deleted file mode 100644 index c1525b811a167671e9de1fa78aab9f5c0b61cef7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> - - - - Code coverage report for All files - - - - - - - - - -
-
-

All files

-
- -
- 42.16% - Statements - 70/166 -
- - -
- 41.48% - Branches - 39/94 -
- - -
- 42.3% - Functions - 11/26 -
- - -
- 42.03% - Lines - 66/157 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
elevator.js -
-
21.9%23/10510.71%6/5615.38%2/1322.33%23/103
output.js -
-
65.71%23/3586.2%25/2950%4/867.85%19/28
requestMap.js -
-
92.3%24/2688.88%8/9100%5/592.3%24/26
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/output.js.html b/coverage/lcov-report/output.js.html deleted file mode 100644 index 7d4cbc3..0000000 --- a/coverage/lcov-report/output.js.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - Code coverage report for output.js - - - - - - - - - -
-
-

All files output.js

-
- -
- 65.71% - Statements - 23/35 -
- - -
- 86.2% - Branches - 25/29 -
- - -
- 50% - Functions - 4/8 -
- - -
- 67.85% - Lines - 19/28 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44  -1x -122x -122x -122x -116x -  -122x -  -  -  -  -1x -2x -  -  -  -1x -2x -2x -122x -2x -2x -  -1x -  -1x -  -1x -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x - 
"use strict";
-var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
-    if (k2 === undefined) k2 = k;
-    var desc = Object.getOwnPropertyDescriptor(m, k);
-    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
-      desc = { enumerable: true, get: function() { return m[k]; } };
-    }
-    Object.defineProperty(o, k2, desc);
-}) : (function(o, m, k, k2) {
-    Iif (k2 === undefined) k2 = k;
-    o[k2] = m[k];
-}));
-var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
-    Object.defineProperty(o, "default", { enumerable: true, value: v });
-}) : function(o, v) {
-    o["default"] = v;
-});
-var __importStar = (this && this.__importStar) || function (mod) {
-    Iif (mod && mod.__esModule) return mod;
-    var result = {};
-    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
-    __setModuleDefault(result, mod);
-    return result;
-};
-Object.defineProperty(exports, "__esModule", { value: true });
-// to write to new files for output 
-const fs = __importStar(require("fs"));
-// to add EOL character to file output
-const os = __importStar(require("os"));
-class Output {
-    constructor(filename) {
-        this.outputFileName = filename;
-    }
-    output(txt) {
-        const time = new Date();
-        const hours = time.getHours();
-        const minutes = time.getMinutes();
-        const seconds = time.getSeconds();
-        const outputString = `${hours}:${minutes}:${seconds} - ${txt}`;
-        fs.appendFileSync(this.outputFileName, outputString + os.EOL);
-    }
-}
-exports.default = Output;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/output.ts.html b/coverage/lcov-report/output.ts.html deleted file mode 100644 index 24bf9f3..0000000 --- a/coverage/lcov-report/output.ts.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - Code coverage report for output.ts - - - - - - - - - -
-
-

All files output.ts

-
- -
- 40% - Statements - 4/10 -
- - -
- 100% - Branches - 0/0 -
- - -
- 50% - Functions - 1/2 -
- - -
- 40% - Lines - 4/10 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26  -1x -  -  -1x -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x
// to write to new files for output 
-import * as fs from 'fs'
- 
-// to add EOL character to file output
-import * as os from 'os';
- 
- 
-class Output {
-  outputFileName: string;
- 
-  constructor(filename: string) {
-    this.outputFileName = filename;
-  }
- 
-  output(txt:string) {
-    const time = new Date();
-    const hours = time.getHours();
-    const minutes = time.getMinutes();
-    const seconds = time.getSeconds();
-    const outputString = `${hours}:${minutes}:${seconds} - ${txt}`;
-    fs.appendFileSync(this.outputFileName, outputString + os.EOL);
-  }
- 
-}
- 
-export default Output;
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/prettify.css b/coverage/lcov-report/prettify.css deleted file mode 100644 index b317a7c..0000000 --- a/coverage/lcov-report/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/lcov-report/prettify.js b/coverage/lcov-report/prettify.js deleted file mode 100644 index b322523..0000000 --- a/coverage/lcov-report/prettify.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-disable */ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/lcov-report/requestMap.js.html b/coverage/lcov-report/requestMap.js.html deleted file mode 100644 index 1ef58bc..0000000 --- a/coverage/lcov-report/requestMap.js.html +++ /dev/null @@ -1,217 +0,0 @@ - - - - - - Code coverage report for requestMap.js - - - - - - - - - -
-
-

All files requestMap.js

-
- -
- 92.3% - Statements - 24/26 -
- - -
- 88.88% - Branches - 8/9 -
- - -
- 100% - Functions - 5/5 -
- - -
- 92.3% - Lines - 24/26 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45  -  -  -2x -  -  -8x -8x -8x -  -  -9x -9x -  -  -  -9x -8x -9x -6x -  -  -3x -3x -2x -3x -2x -  -  -2x -1x -1x -  -1x -  -  -2x -1x -1x -  -1x -  -  -2x - 
"use strict";
-// keep track of max / min 
-// be a normal object
-Object.defineProperty(exports, "__esModule", { value: true });
-class RequestMap {
-    constructor() {
-        this.map = new Map();
-        this.max = -1;
-        this.min = -1;
-    }
-    set(key, value) {
-        this.map.set(key, value);
-        Iif (this.map.size === 0) {
-            this.min = key;
-            this.max = key;
-        }
-        if (key > this.max)
-            this.max = key;
-        if (key < this.min || this.min === -1)
-            this.min = key;
-    }
-    delete(key) {
-        this.map.delete(key);
-        if (key === this.min)
-            this.setMin();
-        if (key === this.max)
-            this.setMax();
-    }
-    setMin() {
-        if (!this.map.size) {
-            this.min = -1;
-            return;
-        }
-        this.min = Math.min(...Array.from(this.map.keys()));
-    }
-    setMax() {
-        if (!this.map.size) {
-            this.max = -1;
-            return;
-        }
-        this.max = Math.max(...Array.from(this.map.keys()));
-    }
-}
-exports.default = RequestMap;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/requestMap.ts.html b/coverage/lcov-report/requestMap.ts.html deleted file mode 100644 index 920b4b7..0000000 --- a/coverage/lcov-report/requestMap.ts.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - - - Code coverage report for requestMap.ts - - - - - - - - - -
-
-

All files requestMap.ts

-
- -
- 92% - Statements - 23/25 -
- - -
- 88.88% - Branches - 8/9 -
- - -
- 100% - Functions - 5/5 -
- - -
- 90.47% - Lines - 19/21 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57  -  -  -  -  -  -  -  -  -  -  -6x -6x -6x -  -  -  -9x -9x -  -  -  -9x -9x -  -  -  -3x -  -3x -3x -  -  -  -  -2x -1x -1x -  -1x -  -  -  -  -2x -1x -1x -  -1x -  -  -  -  -  -  -  -1x
// keep track of max / min 
-// be a normal object
- 
- 
- 
- 
-class RequestMap<T> {
-  map: Map<number, T>;
-  min: number;
-  max: number;
-  constructor() {
-    this.map = new Map<number, T>();
-    this.max = -1;
-    this.min = -1;
-  }
- 
-  set(key: number, value: T) {
-    this.map.set(key, value);
-    Iif(this.map.size === 0) {
-      this.min = key;
-      this.max = key;
-    }
-    if(key > this.max) this.max = key;
-    if(key < this.min || this.min === -1) this.min = key;
-  }
- 
-  delete(key: number) {
-    this.map.delete(key);
- 
-    if(key === this.min) this.setMin();
-    if(key === this.max) this.setMax();
- 
-  }  
- 
-  setMin() {
-    if(!this.map.size) {
-      this.min = -1;
-      return;
-    }
-    this.min = Math.min(...Array.from(this.map.keys()));
- 
-  }
- 
-  setMax() {
-    if(!this.map.size) {
-      this.max = -1;
-      return;
-    }
-    this.max = Math.max(...Array.from(this.map.keys()));
-  }
- 
-}
- 
- 
- 
- 
-export default RequestMap;
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/sort-arrow-sprite.png b/coverage/lcov-report/sort-arrow-sprite.png deleted file mode 100644 index 6ed68316eb3f65dec9063332d2f69bf3093bbfab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc diff --git a/coverage/lcov-report/sorter.js b/coverage/lcov-report/sorter.js deleted file mode 100644 index 2bb296a..0000000 --- a/coverage/lcov-report/sorter.js +++ /dev/null @@ -1,196 +0,0 @@ -/* eslint-disable */ -var addSorting = (function() { - 'use strict'; - var cols, - currentSort = { - index: 0, - desc: false - }; - - // returns the summary table element - function getTable() { - return document.querySelector('.coverage-summary'); - } - // returns the thead element of the summary table - function getTableHeader() { - return getTable().querySelector('thead tr'); - } - // returns the tbody element of the summary table - function getTableBody() { - return getTable().querySelector('tbody'); - } - // returns the th element for nth column - function getNthColumn(n) { - return getTableHeader().querySelectorAll('th')[n]; - } - - function onFilterInput() { - const searchValue = document.getElementById('fileSearch').value; - const rows = document.getElementsByTagName('tbody')[0].children; - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - if ( - row.textContent - .toLowerCase() - .includes(searchValue.toLowerCase()) - ) { - row.style.display = ''; - } else { - row.style.display = 'none'; - } - } - } - - // loads the search box - function addSearchBox() { - var template = document.getElementById('filterTemplate'); - var templateClone = template.content.cloneNode(true); - templateClone.getElementById('fileSearch').oninput = onFilterInput; - template.parentElement.appendChild(templateClone); - } - - // loads all columns - function loadColumns() { - var colNodes = getTableHeader().querySelectorAll('th'), - colNode, - cols = [], - col, - i; - - for (i = 0; i < colNodes.length; i += 1) { - colNode = colNodes[i]; - col = { - key: colNode.getAttribute('data-col'), - sortable: !colNode.getAttribute('data-nosort'), - type: colNode.getAttribute('data-type') || 'string' - }; - cols.push(col); - if (col.sortable) { - col.defaultDescSort = col.type === 'number'; - colNode.innerHTML = - colNode.innerHTML + ''; - } - } - return cols; - } - // attaches a data attribute to every tr element with an object - // of data values keyed by column name - function loadRowData(tableRow) { - var tableCols = tableRow.querySelectorAll('td'), - colNode, - col, - data = {}, - i, - val; - for (i = 0; i < tableCols.length; i += 1) { - colNode = tableCols[i]; - col = cols[i]; - val = colNode.getAttribute('data-value'); - if (col.type === 'number') { - val = Number(val); - } - data[col.key] = val; - } - return data; - } - // loads all row data - function loadData() { - var rows = getTableBody().querySelectorAll('tr'), - i; - - for (i = 0; i < rows.length; i += 1) { - rows[i].data = loadRowData(rows[i]); - } - } - // sorts the table using the data for the ith column - function sortByIndex(index, desc) { - var key = cols[index].key, - sorter = function(a, b) { - a = a.data[key]; - b = b.data[key]; - return a < b ? -1 : a > b ? 1 : 0; - }, - finalSorter = sorter, - tableBody = document.querySelector('.coverage-summary tbody'), - rowNodes = tableBody.querySelectorAll('tr'), - rows = [], - i; - - if (desc) { - finalSorter = function(a, b) { - return -1 * sorter(a, b); - }; - } - - for (i = 0; i < rowNodes.length; i += 1) { - rows.push(rowNodes[i]); - tableBody.removeChild(rowNodes[i]); - } - - rows.sort(finalSorter); - - for (i = 0; i < rows.length; i += 1) { - tableBody.appendChild(rows[i]); - } - } - // removes sort indicators for current column being sorted - function removeSortIndicators() { - var col = getNthColumn(currentSort.index), - cls = col.className; - - cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); - col.className = cls; - } - // adds sort indicators for current column being sorted - function addSortIndicators() { - getNthColumn(currentSort.index).className += currentSort.desc - ? ' sorted-desc' - : ' sorted'; - } - // adds event listeners for all sorter widgets - function enableUI() { - var i, - el, - ithSorter = function ithSorter(i) { - var col = cols[i]; - - return function() { - var desc = col.defaultDescSort; - - if (currentSort.index === i) { - desc = !currentSort.desc; - } - sortByIndex(i, desc); - removeSortIndicators(); - currentSort.index = i; - currentSort.desc = desc; - addSortIndicators(); - }; - }; - for (i = 0; i < cols.length; i += 1) { - if (cols[i].sortable) { - // add the click event handler on the th so users - // dont have to click on those tiny arrows - el = getNthColumn(i).querySelector('.sorter').parentElement; - if (el.addEventListener) { - el.addEventListener('click', ithSorter(i)); - } else { - el.attachEvent('onclick', ithSorter(i)); - } - } - } - } - // adds sorting functionality to the UI - return function() { - if (!getTable()) { - return; - } - cols = loadColumns(); - loadData(); - addSearchBox(); - addSortIndicators(); - enableUI(); - }; -})(); - -window.addEventListener('load', addSorting); diff --git a/coverage/lcov.info b/coverage/lcov.info deleted file mode 100644 index 6895be9..0000000 --- a/coverage/lcov.info +++ /dev/null @@ -1,330 +0,0 @@ -TN: -SF:build/elevator.js -FN:2,(anonymous_0) -FN:8,(anonymous_1) -FN:10,(anonymous_2) -FN:16,(anonymous_3) -FN:34,(anonymous_4) -FN:65,(anonymous_5) -FN:89,(anonymous_6) -FN:107,(anonymous_7) -FN:116,(anonymous_8) -FN:141,(anonymous_9) -FN:152,(anonymous_10) -FN:164,(anonymous_11) -FN:168,(anonymous_12) -FNF:13 -FNH:2 -FNDA:2,(anonymous_0) -FNDA:0,(anonymous_1) -FNDA:0,(anonymous_2) -FNDA:1,(anonymous_3) -FNDA:0,(anonymous_4) -FNDA:0,(anonymous_5) -FNDA:0,(anonymous_6) -FNDA:0,(anonymous_7) -FNDA:0,(anonymous_8) -FNDA:0,(anonymous_9) -FNDA:0,(anonymous_10) -FNDA:0,(anonymous_11) -FNDA:0,(anonymous_12) -DA:2,1 -DA:3,2 -DA:5,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,0 -DA:10,0 -DA:11,0 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:35,0 -DA:36,0 -DA:37,0 -DA:40,0 -DA:41,0 -DA:42,0 -DA:43,0 -DA:45,0 -DA:46,0 -DA:48,0 -DA:50,0 -DA:51,0 -DA:52,0 -DA:55,0 -DA:56,0 -DA:57,0 -DA:58,0 -DA:61,0 -DA:66,0 -DA:67,0 -DA:69,0 -DA:70,0 -DA:71,0 -DA:72,0 -DA:73,0 -DA:74,0 -DA:76,0 -DA:77,0 -DA:78,0 -DA:80,0 -DA:81,0 -DA:83,0 -DA:84,0 -DA:86,0 -DA:90,0 -DA:91,0 -DA:92,0 -DA:94,0 -DA:95,0 -DA:96,0 -DA:98,0 -DA:99,0 -DA:100,0 -DA:101,0 -DA:103,0 -DA:109,0 -DA:110,0 -DA:111,0 -DA:112,0 -DA:117,0 -DA:119,0 -DA:121,0 -DA:123,0 -DA:124,0 -DA:125,0 -DA:126,0 -DA:127,0 -DA:128,0 -DA:129,0 -DA:132,0 -DA:133,0 -DA:135,0 -DA:136,0 -DA:142,0 -DA:143,0 -DA:144,0 -DA:145,0 -DA:146,0 -DA:147,0 -DA:149,0 -DA:153,0 -DA:154,0 -DA:155,0 -DA:160,0 -DA:161,0 -DA:165,0 -DA:169,0 -DA:175,1 -LF:103 -LH:23 -BRDA:2,0,0,1 -BRDA:2,0,1,1 -BRDA:2,0,2,1 -BRDA:3,1,0,2 -BRDA:3,1,1,0 -BRDA:3,2,0,2 -BRDA:3,2,1,2 -BRDA:36,3,0,0 -BRDA:36,4,0,0 -BRDA:36,4,1,0 -BRDA:40,5,0,0 -BRDA:40,6,0,0 -BRDA:40,6,1,0 -BRDA:45,7,0,0 -BRDA:50,8,0,0 -BRDA:57,9,0,0 -BRDA:57,9,1,0 -BRDA:69,10,0,0 -BRDA:70,11,0,0 -BRDA:70,11,1,0 -BRDA:72,12,0,0 -BRDA:76,13,0,0 -BRDA:76,14,0,0 -BRDA:76,14,1,0 -BRDA:80,15,0,0 -BRDA:80,15,1,0 -BRDA:83,16,0,0 -BRDA:86,17,0,0 -BRDA:86,17,1,0 -BRDA:91,18,0,0 -BRDA:94,19,0,0 -BRDA:100,20,0,0 -BRDA:109,21,0,0 -BRDA:110,22,0,0 -BRDA:110,22,1,0 -BRDA:110,23,0,0 -BRDA:110,23,1,0 -BRDA:117,24,0,0 -BRDA:119,25,0,0 -BRDA:119,26,0,0 -BRDA:119,26,1,0 -BRDA:121,27,0,0 -BRDA:121,27,1,0 -BRDA:126,28,0,0 -BRDA:132,29,0,0 -BRDA:135,30,0,0 -BRDA:135,31,0,0 -BRDA:135,31,1,0 -BRDA:143,32,0,0 -BRDA:146,33,0,0 -BRDA:154,34,0,0 -BRDA:169,35,0,0 -BRDA:169,35,1,0 -BRDA:169,35,2,0 -BRDA:169,35,3,0 -BRDA:169,35,4,0 -BRF:56 -BRH:6 -end_of_record -TN: -SF:build/output.js -FN:2,(anonymous_0) -FN:6,(anonymous_1) -FN:9,(anonymous_2) -FN:13,(anonymous_3) -FN:15,(anonymous_4) -FN:18,(anonymous_5) -FN:31,(anonymous_6) -FN:34,(anonymous_7) -FNF:8 -FNH:4 -FNDA:122,(anonymous_0) -FNDA:0,(anonymous_1) -FNDA:0,(anonymous_2) -FNDA:2,(anonymous_3) -FNDA:0,(anonymous_4) -FNDA:2,(anonymous_5) -FNDA:1,(anonymous_6) -FNDA:0,(anonymous_7) -DA:2,1 -DA:3,122 -DA:4,122 -DA:5,122 -DA:6,116 -DA:8,122 -DA:10,0 -DA:11,0 -DA:13,1 -DA:14,2 -DA:16,0 -DA:18,1 -DA:19,2 -DA:20,2 -DA:21,122 -DA:22,2 -DA:23,2 -DA:25,1 -DA:27,1 -DA:29,1 -DA:32,1 -DA:35,0 -DA:36,0 -DA:37,0 -DA:38,0 -DA:39,0 -DA:40,0 -DA:43,1 -LF:28 -LH:19 -BRDA:2,0,0,1 -BRDA:2,0,1,1 -BRDA:2,0,2,1 -BRDA:2,1,0,1 -BRDA:2,1,1,0 -BRDA:3,2,0,122 -BRDA:5,3,0,116 -BRDA:5,4,0,122 -BRDA:5,4,1,122 -BRDA:5,5,0,5 -BRDA:5,5,1,117 -BRDA:5,6,0,117 -BRDA:5,6,1,8 -BRDA:10,7,0,0 -BRDA:13,8,0,1 -BRDA:13,8,1,1 -BRDA:13,8,2,1 -BRDA:13,9,0,1 -BRDA:13,9,1,0 -BRDA:18,10,0,1 -BRDA:18,10,1,1 -BRDA:18,10,2,1 -BRDA:19,11,0,0 -BRDA:19,12,0,2 -BRDA:19,12,1,2 -BRDA:21,13,0,2 -BRDA:21,14,0,122 -BRDA:21,15,0,122 -BRDA:21,15,1,122 -BRF:29 -BRH:25 -end_of_record -TN: -SF:build/requestMap.js -FN:6,(anonymous_0) -FN:11,(anonymous_1) -FN:22,(anonymous_2) -FN:29,(anonymous_3) -FN:36,(anonymous_4) -FNF:5 -FNH:5 -FNDA:8,(anonymous_0) -FNDA:9,(anonymous_1) -FNDA:3,(anonymous_2) -FNDA:2,(anonymous_3) -FNDA:2,(anonymous_4) -DA:4,2 -DA:7,8 -DA:8,8 -DA:9,8 -DA:12,9 -DA:13,9 -DA:14,0 -DA:15,0 -DA:17,9 -DA:18,8 -DA:19,9 -DA:20,6 -DA:23,3 -DA:24,3 -DA:25,2 -DA:26,3 -DA:27,2 -DA:30,2 -DA:31,1 -DA:32,1 -DA:34,1 -DA:37,2 -DA:38,1 -DA:39,1 -DA:41,1 -DA:44,2 -LF:26 -LH:24 -BRDA:13,0,0,0 -BRDA:17,1,0,8 -BRDA:19,2,0,6 -BRDA:19,3,0,9 -BRDA:19,3,1,8 -BRDA:24,4,0,2 -BRDA:26,5,0,2 -BRDA:30,6,0,1 -BRDA:37,7,0,1 -BRF:9 -BRH:8 -end_of_record From 2e2c19a3e2a8aa9fb661c8438bca0bd8f3b80b9b Mon Sep 17 00:00:00 2001 From: shaysheller <24629189+shaysheller@users.noreply.github.com> Date: Sun, 2 Apr 2023 23:05:00 -0700 Subject: [PATCH 21/22] Delete output.txt --- output.txt | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 output.txt diff --git a/output.txt b/output.txt deleted file mode 100644 index 871debb..0000000 --- a/output.txt +++ /dev/null @@ -1,30 +0,0 @@ -22:59:46 - Floor 1 requested externally -22:59:46 - Floor 2 requested externally -22:59:46 - Floor 3 requested externally -22:59:50 - Stopped on floor: 1 -22:59:50 - 1 passenger(s) got on -22:59:54 - Stopped on floor: 2 -22:59:54 - 1 passenger(s) got on -23:0:6 - Floor 5 requested internally -23:0:7 - Floor 6 requested externally -23:0:10 - Passing floor: 3 -23:0:13 - Passing floor: 4 -23:0:16 - Stopped on floor: 5 -23:0:16 - 1 passenger(s) got off -23:0:20 - Stopped on floor: 6 -23:0:20 - 1 passenger(s) got on -23:0:26 - Floor 2 requested internally -23:0:27 - Floor 1 requested internally -23:0:29 - Passing floor: 5 -23:0:32 - Passing floor: 4 -23:0:35 - Passing floor: 3 -23:0:38 - Stopped on floor: 2 -23:0:38 - 1 passenger(s) got off -23:0:42 - Stopped on floor: 1 -23:0:42 - 1 passenger(s) got off -23:0:46 - Passing floor: 2 -23:0:49 - Stopped on floor: 3 -23:0:49 - 1 passenger(s) got on -23:0:55 - Floor 4 requested internally -23:0:59 - Stopped on floor: 4 -23:0:59 - 1 passenger(s) got off From 4343c98b74c18003ac891074a53cc85ee80e60b7 Mon Sep 17 00:00:00 2001 From: shaysheller <24629189+shaysheller@users.noreply.github.com> Date: Sun, 2 Apr 2023 23:13:03 -0700 Subject: [PATCH 22/22] Update README2.md --- elevator/README2.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/elevator/README2.md b/elevator/README2.md index 2bb46fc..0c470b3 100644 --- a/elevator/README2.md +++ b/elevator/README2.md @@ -5,3 +5,6 @@ - type: `node build/elevator/main.js` into command line - Elevator instructions are the same as the initial README - to run tests: `npm run test` into command line + +# Notes +- source code is written in TypeScript in the root/elevator directory.