diff --git a/.gitignore b/.gitignore index 40b878d..f7dbd61 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,7 @@ -node_modules/ \ No newline at end of file +node_modules/ +coverage +junk* +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ \ No newline at end of file diff --git a/PROJECT_PRESENTATION.md b/PROJECT_PRESENTATION.md deleted file mode 100644 index b45e899..0000000 --- a/PROJECT_PRESENTATION.md +++ /dev/null @@ -1 +0,0 @@ -Put your plan, story, and any supporting material here, you could use the help of a readme markdown generator such as [readme.so](https://readme.so/) diff --git a/README.md b/README.md index b246643..8a5461a 100644 --- a/README.md +++ b/README.md @@ -1,114 +1,95 @@ -# Make your own Codewars Style Challenge +# Flagging Down the Answer -In this workshop, you'll create your own programming challenge for others to solve, similar to the ones you might have tackled on Codewars. You'll write unit tests to validate solutions. Then you can share your challenge with other bootcampers for them to solve. If a submitted solution passes all your tests, it will be considered a correct solution - just like on Codewars. This is a great chance to get creative and come up with a programming challenge to stump your peers! +## Project Summary -## πŸ’‘ OBJECTIVES FOR THE WORKSHOP +The aim of this project was to create a fun and engaging Javascript challenge that would test its user's ability to interact with object arguments and use the provided information to return an array of valid matches. -Here's a glimpse of what you'll be achieving by the end of this workshop: +## Project Description -- Clearly describing a problem/task that you want others to solve -- Writing unit tests to check whether their solution to your task is correct -- Present your project plan, story, and anything else you feel supports your creation process and final outcome in a document +For this project, you are aiming to create a function that filters a list of countries based on the characteristics of their flags. The function, filterFlag, takes two arguments: an object containing the search terms (characteristics of the flag) and an array of flag data (FULL_FLAG_LIST). The function returns an array of country names that match the given characteristics. -## 🎟️ TICKETS +- [Installation](#installation) +- [Data Structure](#data-structure) +- [Testing](#testing) +- [Function Requirements](#Function-Requirements) +- [Constraints](#Constraints) +- [Example Usage](#Example-Usage) +- [Evaluation Criteria](#Evaluation-Criteria) +- [Project Requirements](#Project-Requirements) -Time to dive into action! πŸŠβ€β™‚οΈ Here's what you'll be working on: +## Installation -### 🎫 Ticket 1 - Setup +1. Clone the repository: + ```sh + git clone https://github.com/samannetts/flag-identification.git + ``` +2. Install the dependencies: + ```sh + npm install + ``` -Install Vitest and optionally set up an NPM `test` script that conveniently runs your tests. +### Data Structures -You will be making one kata each, but you will be in development teams. The aim is to co-elevate each other. There are several ways you can and should look to help each other: +Each country's flag is represented by an object with the following keys: -- Brainstorming: Helping each make your ideas better, and giving feedback to each other to add different perspectives and improve the end product -- Planning: You can help validate each others plans, and sense check in a team review the direction of your products -- Check-ins: Regular team stand-ups / check-ins will help make sure you are building and making progress together -- Support: You should aim to help each other overcome issues if one of your team is stuck and cannot Google their way out of it -- Testing: You can act as a first line user test for each others katas. You might find it a good idea to book in regular checkpoints to demo to each other and get initial feedback in quick bursts, making sure you can build in and adapt to any useful feedback before official release of your katas +- `country`: string +- `hasStripes`: boolean +- `numberOfColors`: int +- `hasStars`: boolean +- `stripeDirection`: string (can be "horizontal", "vertical" or null) +- `hasCircles`: boolean +- `colours`: [string, string, string] (an array containing varying number of strings) -### 🎫 Ticket 2 - Plan your kata +### Testing -Attack this as you would any other problem - plan, plan, planΒ and use our agile approach to create steps that allow you to build MVPs and incrementally reach your stretch goals. Brainstorm options with a technique like Disney Ideation. Once you have a compelling challenge and story idea, start breaking it down. Think about the goals of your challenge, and the scenarios you could provide to test if people have reached those goals. Provide any examples or additional details that are necessary for someone taking on your kata to understand the problem, but don't give away so much that it removes the challenge. You want to strike a balance - not too vague but not spoon-feeding the solution either. +To run the tests, use the following command: -Write your kata's scenario in a comment in `main.js` and include the start of an exported function that your audience will use to solve it (like you've seen on the katas you've done before). If it's useful to see an example: - -```js -/** - * Hello challenger! Your task is to write a function named `transformLength` which takes in a string and returns 1 if the length of the string is even and otherwise -1. - * - * Your implementation should handle strings whose length is between 0 (inclusive) and 2500 (inclusive). - * - * A few examples: - * `transformLength("table")` should return -1 as the length of "table" is not even - * `transformLength("wizard")` should return 1 as the length of "wizard" is even - */ -export function transformLength(string) { - // Good luck! -} +```sh +npm test ``` -ℹ️ The reason for leaving the function body empty is that you want the people solving your kata to write their own implementation from scratch. Your role is to provide the overall problem statement and function skeleton. The solving and coding is up to them! Leaving an incomplete skeleton function helps point them in the right direction without giving away a full working solution. - -### 🎫 Ticket 3 - Write your kata - -When drafting your test cases, consider the different inputs that could be passed to the solution function and any edge cases you want to account for. You could put into practice tools such as Equivalency Partitioning, Boundary Value Analysis, and Decision Tables if its useful. Think of test values that will thoroughly cover the expected functionality. The number of tests is up to you, but aim for sufficient coverage to validate correctness. - -Since you'll write tests before seeing people's solutions, focus on defining expected outputs for given inputs, without assumptions about how people actually wrote the code. You're testing for outcomes. You could follow a TDD workflow - write a failing test, then temporarily add code to pass it. Just be sure to remove the solution code before sharing the kata. This helps ensure your tests fail when logic is missing or incorrect and pass when implemented properly. - -If it's useful to see an example (continuing the `checkLength` example from earlier): +Ensure that Vitest is installed as a development dependency: -```js -import { test, expect } from "vitest"; -import { checkLength } from "./main.js"; - -test("should return -1 for strings with an odd length", () => { - const expected = -1; - const actual = checkLength("table"); - expect(actual).toBe(expected); -}); - -test("should return 1 for strings with an even length", () => { - const expected = 1; - const actual = checkLength("wizard"); - expect(actual).toBe(expected); -}); +```sh +npm install --save-dev vitest ``` -🎯 At this stage you should have a description of the problem in `main.js` and some tests in `main.test.js`. +Ensure that Vitest is installed as a development dependency: -### 🎫 Ticket 4 - Check your tests +### Function Requirements -To verify your tests, temporarily add a working implementation to the solution function in `main.js`. Check that the tests fail before implementation and pass when the function is coded correctly. This validates that your tests accurately check for both incorrect and correct solutions. Remember to remove the solution code afterwards before sharing the kata. +The `filterFlag` function should: -If it's useful to see an example (continuing the `checkLength` example from earlier): +1. Handle input objects with varying sets of characteristics. +2. Return the names of the countries that match the given characteristics. -```js -export function checkLength(string) { - // Temporarily added the line below to check if tests pass, but will remove it before committing and pushing. - return string.length % 2 === 0 ? 1 : -1; -} -``` +### Constraints -### 🎫 Ticket 5 - Share your kata +Input Constraints: -Before pushing your final kata repository, be sure to remove any solution code you added for test validation. You want to provide only the kata description, skeleton function, and test cases - no actual solutions. Once ready, share your repo link in the [learn.schoolofcode.co.uk Hackathon Channel](https://learn.schoolofcode.co.uk/path-player?courseid=bc17-qe&unit=66acf966524bf23f05018063Unit) so other bootcampers can find it, clone it, implement solutions, and run your tests to check their progress. This allows them to solve the programming challenge you've created! +- The function must handle input objects with up to 6 keys. +- Input will never be null. +- All input keys will have corresponding values in the `FULL_FLAG_LIST` object. +- The function should return an array of strings representing country names. -Share it with following format: +Output Format: -``` -Room: REPLACE_ME_WITH_YOUR_ROOM_NUMBER -Name: REPLACE_ME_WITH_YOUR_NAME -Link: REPLACE_ME_WITH_A_LINK_TO_YOUR_PUBLIC_GITHUB_REPO_CONTAINING_THE_KATA -Overview: REPLACE_ME_WITH_A_BRIEF_DESCRIPTION_OF_WHAT_YOUR_KATA_IS_ABOUT -``` +- Output should be returned as a array of strings, e.g. ['Belgium', 'Germany', 'Venezuela', 'Romania'] -If it's not public already, remember to change the visibility of your repository to public. +### Example Usage -### 🎫 Ticket 6 - Present you kata +- `filterFlag({hasStripes: true, hasCircles: true}, FULL_FLAG_LIST)` should return `['Argentina']` as this is the only flag with both stripes and a circle. +- `filterFlag({colours: ['red', 'yellow'], numberOfColors: 3}, FULL_FLAG_LIST)` should return `['Belgium', 'Germany', 'Venezuela', 'Romania']`. +- `filterFlag({hasStripes: false, numberOfColors: 2, stripeDirection: null}, FULL_FLAG_LIST)` should return `['China', 'European Union', 'Japan', 'Switzerland']`. -Make sure you present your project in [the markdown file here](/PROJECT_PRESENTATION.md) - this will be assessed alongside your actual kata. Treat this as an asynchronous presentation - anything you would want to talk through (plans, brainstorming, final results, user feedback, etc) should go in here. +### Evaluation Criteria -### 🎫 Ticket 7 - Complete katas from others +- Correctness: Your code must pass all test cases +- Input will never be null +- All input keys will have a corresponding value in the object FULL_FLAG_LIST -To solve katas created by other bootcampers, first clone their repository using the shared link. `cd` into the folder, run `npm install` to get the dependencies, then implement a solution in main.js. Execute their test cases to validate your code against their requirements. Provide feedback on the clarity of their instructions, difficulty level, and effectiveness of the tests. Engaging with each other's challenges allows everyone to learn. Make sure to critique respectfully - creating a programming challenge is difficult! +## Project Requirements +- Design a full suite of tests to evaluate the proposed solution against various input objects. +- Ensure the function meets all technical constraints and limitations. +- Provide clear and comprehensive documentation for users and contributors. diff --git a/flag_database.js b/flag_database.js new file mode 100644 index 0000000..b1d8496 --- /dev/null +++ b/flag_database.js @@ -0,0 +1,137 @@ +export const FULL_FLAG_LIST = Object.freeze([ + { + country: "Argentina", + hasStripes: true, + numberOfColors: 3, + hasStars: false, + stripeDirection: "horizontal", + hasCircles: true, // The sun is a circle + colours: ["blue", "white", "yellow"], + }, + { + country: "Canada", + hasStripes: true, + numberOfColors: 2, + hasStars: false, + stripeDirection: "vertical", + hasCircles: false, + colours: ["red", "white"], + }, + { + country: "Belgium", + hasStripes: true, + numberOfColors: 3, + hasStars: false, + stripeDirection: "vertical", + hasCircles: false, + colours: ["black", "yellow", "red"], + }, + { + country: "China", + hasStripes: false, + numberOfColors: 2, + hasStars: true, + stripeDirection: null, // No stripes + hasCircles: false, + colours: ["red", "yellow"], + }, + { + country: "Australia", + hasStripes: false, + numberOfColors: 3, + hasStars: true, + stripeDirection: null, // No stripes + hasCircles: false, + colours: ["blue", "white", "red"], + }, + { + country: "Germany", + hasStripes: true, + numberOfColors: 3, + hasStars: false, + stripeDirection: "horizontal", + hasCircles: false, + colours: ["black", "red", "yellow"], + }, + { + country: "United States", + hasStripes: true, + numberOfColors: 3, + hasStars: true, + stripeDirection: "horizontal", + hasCircles: false, + colours: ["red", "white", "blue"], + }, + { + country: "United Kingdom", + hasStripes: false, + numberOfColors: 3, + hasStars: false, + stripeDirection: null, // Cross pattern + hasCircles: false, + colours: ["red", "white", "blue"], + }, + { + country: "Ukraine", + hasStripes: true, + numberOfColors: 2, + hasStars: false, + stripeDirection: "horizontal", + hasCircles: false, + colours: ["blue", "yellow"], + }, + { + country: "Venezuela", + hasStripes: true, + numberOfColors: 3, + hasStars: true, + stripeDirection: "horizontal", + hasCircles: false, + colours: ["yellow", "blue", "red"], + }, + { + country: "Netherlands", + hasStripes: true, + numberOfColors: 3, + hasStars: false, + stripeDirection: "horizontal", + hasCircles: false, + colours: ["red", "white", "blue"], + }, + { + country: "European Union", + hasStripes: false, + numberOfColors: 2, + hasStars: true, + stripeDirection: null, // No stripes + hasCircles: false, + colours: ["blue", "yellow"], + }, + { + country: "Japan", + hasStripes: false, + numberOfColors: 2, + hasStars: false, + stripeDirection: null, // No stripes + hasCircles: true, // Red circle + colours: ["white", "red"], + }, + { + country: "Switzerland", + hasStripes: false, + numberOfColors: 2, + hasStars: false, + stripeDirection: null, // No stripes + hasCircles: false, + colours: ["red", "white"], + }, + { + country: "Romania", + hasStripes: true, + numberOfColors: 3, + hasStars: false, + stripeDirection: "vertical", + hasCircles: false, + colours: ["blue", "yellow", "red"], + }, +]); diff --git a/main.js b/main.js index e69de29..5805b11 100644 --- a/main.js +++ b/main.js @@ -0,0 +1,40 @@ +/** + * Hello bootcampers! + * + * A career in tech brings with it countless advantages, not least of all being the flexible working arrangements that many roles offer us. + * However, being that we're all such big thinkers, sometimes smaller details of life evade us, such as: + * What did I eat for dinner last night? Where did I put my keys?...What country am I in again?... + * + * Imagine you've had one of these moments and all you've got to go off is a waving flag in front of you. Your challenge is to write a function that, + * when given some characteristics of the flag, interact with the provided flag 'library' (FULL_FLAG_LIST) and return the country/countries that you may be in! + * + * For reference, for each country held within the list, all details for that country's flag is stored in an object with the following keys: + * + * { + * country: string, + * hasStripes: boolean, + * numberOfColors: int, + * hasStars: boolean, + * stripeDirection: string, (can be "horizontal", "vertical" or null) + * hasCircles: boolean, + * colours: [string, string, string], (Can be an array containing varying number of strings) + * } + * + * A couple of extra notes for this challenge include: + * Any images of the sun is counted as a circle + * Flags with crosses (e.g. the UK) or no stripes will be marked as null + * + * Your function should handle input objects with varying sets of characteristics, and only return the names of the countries. You can assume that all provided attributes have corresponding entries in the FULL_FLAG_LIST object. + * + * A few examples: + * filterFlag({hasStripes: true, hasCircles: true},FULL_FLAG_LIST) should return ['Argentina'] as this is the only flag with both stripes and a circle + * filterFlag({colours: [ 'red', 'yellow' ], numberOfColors: 3}) should return [ 'Belgium', 'Germany', 'Venezuela', 'Romania'] + * filterFlag({hasStripes: false, numberOfColors: 2, stripeDirection: null}) should return [ 'China', 'European Union', 'Japan', 'Switzerland' ]) + * + * Best of luck!! + */ +export function filterFlag(searchTerms, fullFlagList) { + // Input your solution here! +} + +// An input of hasStripes: true should equal ["Argentina","Canada","Belgium","Germany","United States","Ukraine","Venezuela","Netherlands","Romania diff --git a/main.test.js b/main.test.js index e69de29..e0b3904 100644 --- a/main.test.js +++ b/main.test.js @@ -0,0 +1,583 @@ +import { FULL_FLAG_LIST } from "./flag_database"; +import { describe, expect, test } from "vitest"; +import { filterFlag } from "./main.js"; + +describe("Comparing filtering on individual keys (ex. colours)", () => { + test.each([ + [ + { + hasStripes: true, + }, + [ + "Argentina", + "Canada", + "Belgium", + "Germany", + "United States", + "Ukraine", + "Venezuela", + "Netherlands", + "Romania", + ], + FULL_FLAG_LIST, + ], + [ + { + hasStripes: false, + }, + [ + "China", + "Australia", + "United Kingdom", + "European Union", + "Japan", + "Switzerland", + ], + FULL_FLAG_LIST, + ], + ])("An input of %o should return %o", (a, b, c) => { + expect(filterFlag(a, c)).toEqual(b); + }); + + test.each([ + [ + { + numberOfColors: 2, + }, + ["Canada", "China", "Ukraine", "European Union", "Japan", "Switzerland"], + FULL_FLAG_LIST, + ], + [ + { + numberOfColors: 3, + }, + [ + "Argentina", + "Belgium", + "Australia", + "Germany", + "United States", + "United Kingdom", + "Venezuela", + "Netherlands", + "Romania", + ], + FULL_FLAG_LIST, + ], + ])("An input of %o should return %o", (a, b, c) => { + expect(filterFlag(a, c)).toEqual(b); + }); + + test.each([ + [ + { + hasStars: true, + }, + ["China", "Australia", "United States", "Venezuela", "European Union"], + FULL_FLAG_LIST, + ], + [ + { + hasStars: false, + }, + [ + "Argentina", + "Canada", + "Belgium", + "Germany", + "United Kingdom", + "Ukraine", + "Netherlands", + "Japan", + "Switzerland", + "Romania", + ], + FULL_FLAG_LIST, + ], + ])("An input of %o should return %o", (a, b, c) => { + expect(filterFlag(a, c)).toEqual(b); + }); + + test.each([ + [ + { + stripeDirection: "vertical", + }, + ["Canada", "Belgium", "Romania"], + FULL_FLAG_LIST, + ], + [ + { + stripeDirection: "horizontal", + }, + [ + "Argentina", + "Germany", + "United States", + "Ukraine", + "Venezuela", + "Netherlands", + ], + FULL_FLAG_LIST, + ], + [ + { + stripeDirection: null, + }, + [ + "China", + "Australia", + "United Kingdom", + "European Union", + "Japan", + "Switzerland", + ], + FULL_FLAG_LIST, + ], + ])("An input of %o should return %o", (a, b, c) => { + expect(filterFlag(a, c)).toEqual(b); + }); +}); + +describe("Comparing filtering on multiple keys (ex. colours)", () => { + test.each([ + [ + { + hasStripes: true, + numberOfColors: 3, + }, + [ + "Argentina", + "Belgium", + "Germany", + "United States", + "Venezuela", + "Netherlands", + "Romania", + ], + FULL_FLAG_LIST, + ], + [ + { + hasStripes: false, + numberOfColors: 2, + stripeDirection: null, + }, + ["China", "European Union", "Japan", "Switzerland"], + FULL_FLAG_LIST, + ], + [ + { + hasStripes: true, + numberOfColors: 3, + stripeDirection: "horizontal", + }, + ["Argentina", "Germany", "United States", "Venezuela", "Netherlands"], + FULL_FLAG_LIST, + ], + ])("An input of %o should return %o", (a, b, c) => { + expect(filterFlag(a, c)).toEqual(b); + }); +}); + +describe("Comparing filtering on multiple keys (incl colours)", () => { + test.each([ + [ + { + colours: ["red"], + numberOfColors: 3, + }, + [ + "Belgium", + "Australia", + "Germany", + "United States", + "United Kingdom", + "Venezuela", + "Netherlands", + "Romania", + ], + FULL_FLAG_LIST, + ], + [ + { + colours: ["red", "yellow"], + numberOfColors: 3, + }, + ["Belgium", "Germany", "Venezuela", "Romania"], + FULL_FLAG_LIST, + ], + [ + { + hasStripes: true, + numberOfColors: 2, + hasStars: false, + stripeDirection: "vertical", + hasCircles: false, + colours: ["red", "white"], + }, + ["Canada"], + FULL_FLAG_LIST, + ], + ])("An input of %o should return %o", (a, b, c) => { + expect(filterFlag(a, c)).toEqual(b); + }); +}); + +describe("Output is appropriate datatype ", () => { + test("Output should be an array", () => { + //Arrange + const a = { + hasStripes: true, + hasCircles: true, + }; + const b = FULL_FLAG_LIST; + + //Act + const actual = filterFlag(a, b); + //Assert + expect(actual).toBeInstanceOf(Array); + }); +}); + +describe("Comparing filtering on individual keys (ex. colours)", () => { + test("An input of hasStripes: true should return the correct flags", () => { + const a = { hasStripes: true }; + const b = [ + "Argentina", + "Canada", + "Belgium", + "Germany", + "United States", + "Ukraine", + "Venezuela", + "Netherlands", + "Romania", + ]; + expect(filterFlag(a, FULL_FLAG_LIST)).toEqual(b); + }); + + test("An input of hasStripes: false should return the correct flags", () => { + const a = { hasStripes: false }; + const b = [ + "China", + "Australia", + "United Kingdom", + "European Union", + "Japan", + "Switzerland", + ]; + expect(filterFlag(a, FULL_FLAG_LIST)).toEqual(b); + }); +}); + +describe("Filtering flags based on search criteria (incl. colours)", () => { + test("Should return flags with hasStripes: true", () => { + const searchTerm = { hasStripes: true }; + const expectedOutput = [ + "Argentina", + "Canada", + "Belgium", + "Germany", + "United States", + "Ukraine", + "Venezuela", + "Netherlands", + "Romania", + ]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with colours: ['red']", () => { + const searchTerm = { colours: ["red"] }; + const expectedOutput = [ + "Canada", + "Belgium", + "China", + "Australia", + "Germany", + "United States", + "United Kingdom", + "Venezuela", + "Netherlands", + "Japan", + "Switzerland", + "Romania", + ]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with hasStripes: true and colours: ['red', 'yellow']", () => { + const searchTerm = { hasStripes: true, colours: ["red", "yellow"] }; + const expectedOutput = ["Belgium", "Germany", "Venezuela", "Romania"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); +}); + +describe("Output is appropriate datatype", () => { + test("Output should be an array", () => { + const a = { hasStripes: true, hasCircles: true }; + const actual = filterFlag(a, FULL_FLAG_LIST); + expect(Array.isArray(actual)).toBe(true); + }); +}); + +describe("Additional Tests", () => { + test("Should return flags with hasCircles: true", () => { + const searchTerm = { hasCircles: true }; + const expectedOutput = ["Argentina", "Japan"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with stripeDirection: 'vertical'", () => { + const searchTerm = { stripeDirection: "vertical" }; + const expectedOutput = ["Canada", "Belgium", "Romania"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with colours: ['blue', 'white']", () => { + const searchTerm = { colours: ["blue", "white"] }; + const expectedOutput = [ + "Argentina", + "Australia", + "United States", + "United Kingdom", + "Netherlands", + ]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with hasStripes: false and hasStars: true", () => { + const searchTerm = { hasStripes: false, hasStars: true }; + const expectedOutput = ["China", "Australia", "European Union"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with colours: ['red', 'white', 'blue']", () => { + const searchTerm = { colours: ["red", "white", "blue"] }; + const expectedOutput = [ + "Australia", + "United States", + "United Kingdom", + "Netherlands", + ]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with hasStripes: true and hasCircles: false", () => { + const searchTerm = { hasStripes: true, hasCircles: false }; + const expectedOutput = [ + "Canada", + "Belgium", + "Germany", + "United States", + "Ukraine", + "Venezuela", + "Netherlands", + "Romania", + ]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with colours: ['yellow']", () => { + const searchTerm = { colours: ["yellow"] }; + const expectedOutput = [ + "Argentina", + "Belgium", + "China", + "Germany", + "Ukraine", + "Venezuela", + "European Union", + "Romania", + ]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with hasStripes: true and hasStars: true", () => { + const searchTerm = { hasStripes: true, hasStars: true }; + const expectedOutput = ["United States", "Venezuela"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with stripeDirection: null and hasStars: false", () => { + const searchTerm = { stripeDirection: null, hasStars: false }; + const expectedOutput = ["United Kingdom", "Japan", "Switzerland"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with colours: ['black', 'red', 'yellow']", () => { + const searchTerm = { colours: ["black", "red", "yellow"] }; + const expectedOutput = ["Belgium", "Germany"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with hasStripes: true and stripeDirection: 'vertical'", () => { + const searchTerm = { hasStripes: true, stripeDirection: "vertical" }; + const expectedOutput = ["Canada", "Belgium", "Romania"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with colours: ['white', 'red']", () => { + const searchTerm = { colours: ["white", "red"] }; + const expectedOutput = [ + "Canada", + "Australia", + "United States", + "United Kingdom", + "Netherlands", + "Japan", + "Switzerland", + ]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with hasStars: true and stripeDirection: null", () => { + const searchTerm = { hasStars: true, stripeDirection: null }; + const expectedOutput = ["China", "Australia", "European Union"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with colours: ['blue', 'yellow']", () => { + const searchTerm = { colours: ["blue", "yellow"] }; + const expectedOutput = [ + "Argentina", + "Ukraine", + "Venezuela", + "European Union", + "Romania", + ]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with hasCircles: false and stripeDirection: 'horizontal'", () => { + const searchTerm = { hasCircles: false, stripeDirection: "horizontal" }; + const expectedOutput = [ + "Germany", + "United States", + "Ukraine", + "Venezuela", + "Netherlands", + ]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with hasStripes: false and hasCircles: true", () => { + const searchTerm = { hasStripes: false, hasCircles: true }; + const expectedOutput = ["Japan"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with stripeDirection: 'horizontal' and hasStars: false", () => { + const searchTerm = { stripeDirection: "horizontal", hasStars: false }; + const expectedOutput = ["Argentina", "Germany", "Ukraine", "Netherlands"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with colours: ['red', 'blue']", () => { + const searchTerm = { colours: ["red", "blue"] }; + const expectedOutput = [ + "Australia", + "United States", + "United Kingdom", + "Venezuela", + "Netherlands", + "Romania", + ]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with hasStripes: true and hasCircles: true", () => { + const searchTerm = { hasStripes: true, hasCircles: true }; + const expectedOutput = ["Argentina"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); + + test("Should return flags with stripeDirection: 'vertical' and colours: ['red']", () => { + const searchTerm = { stripeDirection: "vertical", colours: ["red"] }; + const expectedOutput = ["Canada", "Belgium", "Romania"]; + expect(filterFlag(searchTerm, FULL_FLAG_LIST)).toEqual(expectedOutput); + }); +}); + +describe("random tests", () => { + // Helper function to generate random search terms + function generateRandomSearchTerms() { + const keys = [ + "hasStripes", + "numberOfColours", + "hasStars", + "stripeDirection", + "hasCircles", + "colours", + ]; + const searchTerms = {}; + + // Randomly select 1 to 6 keys to include in searchTerms + const numKeys = Math.floor(Math.random() * 6) + 1; + const selectedKeys = keys.sort(() => 0.5 - Math.random()).slice(0, numKeys); + + selectedKeys.forEach((key) => { + if (key === "colours") { + // Randomly select 1 to 3 colours + const allColours = [ + "blue", + "white", + "yellow", + "red", + "black", + "green", + "orange", + ]; + const numColours = Math.floor(Math.random() * 3) + 1; + searchTerms[key] = allColours + .sort(() => 0.5 - Math.random()) + .slice(0, numColours); + } else if (key === "stripeDirection") { + // Randomly select a stripe direction + const directions = ["horizontal", "vertical", null]; + searchTerms[key] = + directions[Math.floor(Math.random() * directions.length)]; + } else if (key === "numberOfColours") { + // Randomly select a number of colours (1 to 5) + searchTerms[key] = Math.floor(Math.random() * 5) + 1; + } else { + // Randomly assign true/false for boolean keys + searchTerms[key] = Math.random() < 0.5; + } + }); + + return searchTerms; + } + + // Helper function to manually filter the flag list based on search terms + function manualFilter(searchTerms, fullFlagList) { + return fullFlagList + .filter((countryData) => { + return Object.entries(searchTerms).every(([key, value]) => { + if (key === "colours") { + return value.every((colour) => countryData[key].includes(colour)); + } + return countryData[key] === value; + }); + }) + .map((countryData) => countryData.country); + } + + // Randomized test cases + test("Should pass randomized tests", () => { + for (let i = 0; i < 20; i++) { + // Generate random search terms + const searchTerms = generateRandomSearchTerms(); + + // Get the result from your function + const result = filterFlag(searchTerms, FULL_FLAG_LIST); + + // Get the expected result using manual filtering + const expected = manualFilter(searchTerms, FULL_FLAG_LIST); + + // Assert that the results match + expect(result).toEqual(expected); + } + }); +}); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..cc8f613 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1248 @@ +{ + "name": "workshop_make-your-own-codewars", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "workshop_make-your-own-codewars", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "vitest": "^2.1.8" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.30.1.tgz", + "integrity": "sha512-pSWY+EVt3rJ9fQ3IqlrEUtXh3cGqGtPDH1FQlNZehO2yYxCHEX1SPsz1M//NXwYfbTlcKr9WObLnJX9FsS9K1Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.30.1.tgz", + "integrity": "sha512-/NA2qXxE3D/BRjOJM8wQblmArQq1YoBVJjrjoTSBS09jgUisq7bqxNHJ8kjCHeV21W/9WDGwJEWSN0KQ2mtD/w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.30.1.tgz", + "integrity": "sha512-r7FQIXD7gB0WJ5mokTUgUWPl0eYIH0wnxqeSAhuIwvnnpjdVB8cRRClyKLQr7lgzjctkbp5KmswWszlwYln03Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.30.1.tgz", + "integrity": "sha512-x78BavIwSH6sqfP2xeI1hd1GpHL8J4W2BXcVM/5KYKoAD3nNsfitQhvWSw+TFtQTLZ9OmlF+FEInEHyubut2OA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.30.1.tgz", + "integrity": "sha512-HYTlUAjbO1z8ywxsDFWADfTRfTIIy/oUlfIDmlHYmjUP2QRDTzBuWXc9O4CXM+bo9qfiCclmHk1x4ogBjOUpUQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.30.1.tgz", + "integrity": "sha512-1MEdGqogQLccphhX5myCJqeGNYTNcmTyaic9S7CG3JhwuIByJ7J05vGbZxsizQthP1xpVx7kd3o31eOogfEirw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.30.1.tgz", + "integrity": "sha512-PaMRNBSqCx7K3Wc9QZkFx5+CX27WFpAMxJNiYGAXfmMIKC7jstlr32UhTgK6T07OtqR+wYlWm9IxzennjnvdJg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.30.1.tgz", + "integrity": "sha512-B8Rcyj9AV7ZlEFqvB5BubG5iO6ANDsRKlhIxySXcF1axXYUyqwBok+XZPgIYGBgs7LDXfWfifxhw0Ik57T0Yug==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.30.1.tgz", + "integrity": "sha512-hqVyueGxAj3cBKrAI4aFHLV+h0Lv5VgWZs9CUGqr1z0fZtlADVV1YPOij6AhcK5An33EXaxnDLmJdQikcn5NEw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.30.1.tgz", + "integrity": "sha512-i4Ab2vnvS1AE1PyOIGp2kXni69gU2DAUVt6FSXeIqUCPIR3ZlheMW3oP2JkukDfu3PsexYRbOiJrY+yVNSk9oA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.30.1.tgz", + "integrity": "sha512-fARcF5g296snX0oLGkVxPmysetwUk2zmHcca+e9ObOovBR++9ZPOhqFUM61UUZ2EYpXVPN1redgqVoBB34nTpQ==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.30.1.tgz", + "integrity": "sha512-GLrZraoO3wVT4uFXh67ElpwQY0DIygxdv0BNW9Hkm3X34wu+BkqrDrkcsIapAY+N2ATEbvak0XQ9gxZtCIA5Rw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.30.1.tgz", + "integrity": "sha512-0WKLaAUUHKBtll0wvOmh6yh3S0wSU9+yas923JIChfxOaaBarmb/lBKPF0w/+jTVozFnOXJeRGZ8NvOxvk/jcw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.30.1.tgz", + "integrity": "sha512-GWFs97Ruxo5Bt+cvVTQkOJ6TIx0xJDD/bMAOXWJg8TCSTEK8RnFeOeiFTxKniTc4vMIaWvCplMAFBt9miGxgkA==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.30.1.tgz", + "integrity": "sha512-UtgGb7QGgXDIO+tqqJ5oZRGHsDLO8SlpE4MhqpY9Llpzi5rJMvrK6ZGhsRCST2abZdBqIBeXW6WPD5fGK5SDwg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.30.1.tgz", + "integrity": "sha512-V9U8Ey2UqmQsBT+xTOeMzPzwDzyXmnAoO4edZhL7INkwQcaW1Ckv3WJX3qrrp/VHaDkEWIBWhRwP47r8cdrOow==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.30.1.tgz", + "integrity": "sha512-WabtHWiPaFF47W3PkHnjbmWawnX/aE57K47ZDT1BXTS5GgrBUEpvOzq0FI0V/UYzQJgdb8XlhVNH8/fwV8xDjw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.30.1.tgz", + "integrity": "sha512-pxHAU+Zv39hLUTdQQHUVHf4P+0C47y/ZloorHpzs2SXMRqeAWmGghzAhfOlzFHHwjvgokdFAhC4V+6kC1lRRfw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.30.1.tgz", + "integrity": "sha512-D6qjsXGcvhTjv0kI4fU8tUuBDF/Ueee4SVX79VfNDXZa64TfCW1Slkb6Z7O1p7vflqZjcmOVdZlqf8gvJxc6og==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "license": "MIT" + }, + "node_modules/@vitest/expect": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.8.tgz", + "integrity": "sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw==", + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.8", + "@vitest/utils": "2.1.8", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.8.tgz", + "integrity": "sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA==", + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.8", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.8.tgz", + "integrity": "sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==", + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.8.tgz", + "integrity": "sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==", + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.8", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.8.tgz", + "integrity": "sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==", + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.8", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.8.tgz", + "integrity": "sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==", + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.8.tgz", + "integrity": "sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==", + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.8", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.2.tgz", + "integrity": "sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==", + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.1.0.tgz", + "integrity": "sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==", + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/loupe": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", + "license": "MIT" + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", + "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.1.tgz", + "integrity": "sha512-6oz2beyjc5VMn/KV1pPw8fliQkhBXrVn1Z3TVyqZxU8kZpzEKhBdmCFqI6ZbmGtamQvQGuU1sgPTk8ZrXDD7jQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.30.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.30.1.tgz", + "integrity": "sha512-mlJ4glW020fPuLi7DkM/lN97mYEZGWeqBnrljzN0gs7GLctqX3lNWxKQ7Gl712UAX+6fog/L3jh4gb7R6aVi3w==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.30.1", + "@rollup/rollup-android-arm64": "4.30.1", + "@rollup/rollup-darwin-arm64": "4.30.1", + "@rollup/rollup-darwin-x64": "4.30.1", + "@rollup/rollup-freebsd-arm64": "4.30.1", + "@rollup/rollup-freebsd-x64": "4.30.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.30.1", + "@rollup/rollup-linux-arm-musleabihf": "4.30.1", + "@rollup/rollup-linux-arm64-gnu": "4.30.1", + "@rollup/rollup-linux-arm64-musl": "4.30.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.30.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.30.1", + "@rollup/rollup-linux-riscv64-gnu": "4.30.1", + "@rollup/rollup-linux-s390x-gnu": "4.30.1", + "@rollup/rollup-linux-x64-gnu": "4.30.1", + "@rollup/rollup-linux-x64-musl": "4.30.1", + "@rollup/rollup-win32-arm64-msvc": "4.30.1", + "@rollup/rollup-win32-ia32-msvc": "4.30.1", + "@rollup/rollup-win32-x64-msvc": "4.30.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.0.tgz", + "integrity": "sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==", + "license": "MIT" + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", + "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vite": { + "version": "5.4.14", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.14.tgz", + "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.8.tgz", + "integrity": "sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg==", + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.8.tgz", + "integrity": "sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ==", + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.8", + "@vitest/mocker": "2.1.8", + "@vitest/pretty-format": "^2.1.8", + "@vitest/runner": "2.1.8", + "@vitest/snapshot": "2.1.8", + "@vitest/spy": "2.1.8", + "@vitest/utils": "2.1.8", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.8", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.8", + "@vitest/ui": "2.1.8", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/package.json b/package.json index 275868d..3923bdb 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,11 @@ "description": "", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "vitest" }, "author": "School of Code", - "license": "ISC" + "license": "ISC", + "dependencies": { + "vitest": "^2.1.8" + } }