This commit is contained in:
Andrea Bianchi 2025-05-06 14:29:24 +09:00
commit 7c0fd87578
28 changed files with 1167 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
node_modules
.DS_Store
dist
dist-ssr
*.local

143
README.md Normal file
View File

@ -0,0 +1,143 @@
# Homework 6 - OOP and Design Patterns
- _[Live demo](http://hwdemo.prototyping.id/hw6)_
## General Description
In this assignment, you will practice with **classes, inheritance, and Object-Oriented Programming (OOP) patterns** by implementing a simple _shooting game_. The assignment will also familiarize you with loading and playing sounds, timeouts, reading UML class diagrams, and writing code that interfaces with pre-existing code (the `main.js` written by the instructor).
**NOTE**: There could be unwanted delays in the demo due to the fact that images and sounds are loaded. Please ignore delays (they were not meant, and if you run your code locally, they probably will not be there).
<p align="center">
<img src="assets/main.png" width="100%" />
</p>
The application consists of a **shooting game**, with different elements represented by different classes. The image above shows the game and an overlay identifying the different components (i.e., classes) of the game.
The mouse acts like a gun that you can shoot with the left button of the mouse. When you shoot, a bullet hole appears for 2 seconds and then disappears. At every gunshot, the bullet counter (top right) is decremented by one. If you hit a target, the target disappears, and the score is incremented. Once all bullets are used, you can no longer shoot a target, and the trigger produces the sound of an empty gun. By pressing the spacebar, you reset the score and reload the gun.
## Getting started with Vite and the code stubs
The files `index.html` and `main.js` contain a minimal stub to get you started.
To start developing with _Vite.js_, open the terminal and type once
```bash
npm install
npm run dev
```
The app will be previewed on the local server on port `3000`.
## Requirments
- **Implements all the classes and methods** as specified in the UML diagram below.
- You can modify `main.js` and any other file.
- You can also add more classes, functions, or methods to classes, etc. _But, if you do so, you have to document them_ with a UML diagram to be included in your final submission.
## Overview
<p align="center">
<img src="assets/uml_classes.png" width="100%" />
</p>
You are required to implement several classes across several files, as seen in the [image above](assets/uml_classes.png). The diagram above is full of details: **read it carefully**.
### Classes
#### ScoreDisplay
The `ScoreDisplay` appears on the screen as a textual score with the Arial font size 25 (top left) and a set of images of bullets (top right) representing the shots left in the gun. Each of the bullets is drawn using the same bullet.png image (all images are in the folder `data`).
#### Bullet
Each `Bullet` is drawn using the `bulletHole.png` image. It appears only for two seconds when the gun is shot, and then it becomes invisible. You can use `setTimeout` to make the image disappear.
#### Gun
The `Gun` is the mouse. To draw it, hide the cursor with the `noCursor` function and then draw instead the image `cursor.png` at the location of the mouse. To load and play sounds with p5.js take a look at [this example](https://editor.p5js.org/p5/sketches/Sound:_Load_and_Play_Sound). The sound files are `shot.mp3` and `empty.mp3`, depending on whether there are still shots available. Finally, when you shoot with the gun, add a random `CURSOR_SIZE` noise (or a similarly small amount) to alter the bullet's final hitting location.
#### Target
`Target` (base class) and the derived classes `TeddyTarget`, `DuckTarget`, `SquirrelTarget` represents shootable targets. The Target class takes care of everything, except for loading the correct image and returning the number of points associated with each derived target. TeddyTarget gives **1** point, DuckTarget **3** points and SquirrelTarget gives **5** points. Targets return points only if visible (e.g. not previously hit).
#### TargetFactory
Instead of creating directly the Targets, we use a factory class. Inside there is a static `getInstance` method (the _factory_ is a _singleton_). The other two methods should return an array of targets either randomly or based on specified names. The maximum number of targets is **5** (see the `Constants.js` file).
### Patterns
#### Factory and Singleton
`TargetFactory` is both a **singleton** and a **factory**.
- A singleton requires the class to be unique; hence, it implements the static method `getInstance`, which returns the only available instance of the class.
- The factory methods (`getTargetsByName(targetNames, targetWidth, y)` and `getRandomTargets(numTargets, targetWidth, y)`) require specifying the _targetWidth_, the _y_ location of the target on the screen, and either an array of _names_ (e.g., ['teddy', 'duck', 'squirrel', ...]) or a _number_ of desired random targets.
#### Observer
A `Subject` is an observable object. Observers who `subscribe` to a subject are notified when an event happens. For example, both the ScoreDisplay and the targets will be notified anytime the gun shoots. The ScoreDisplay will also be notified whenever a target is hit (`Target` is both a Subject and an observer).
To be an Observer, an object must implement the method `update`, which takes as input a string with the source of the event and a variable number of parameters grouped with the _rest operator_.
For example, the gun, when shot, will trigger an event similar to this one:
```js
this.notifySubscribers('gun', x, y, remainingShots);
```
... and score display will receive and handle the event:
```js
update(source, ...others) {
if (source == 'gun') { // observer of a gun
// ... others contains the data we need
} else if (source == '...') // observer of something else...
//...
}
// ...
}
```
### Constants
Few constants are specified in the `Constants.js` file. These are useful for drawing with correct dimensions. Feel free to include and use the constants in this file.
<p align="center">
<img src="assets/uml_constants.png" width="150px" />
</p>
---
## About grading
The maximum score for this assignment is 100 points, divided this way:
1. **Git**: Submit your local repository with your code (the hidden .git folder). There should be at least 10 commits in a branch called `develop`, which is finally merged back to `main` (10%).
2. **Gun** shoots **bullets**, which are correctly displayed (10%).
3. **Targets** are correctly implemented with inheritance and can be shot (20%).
4. **ScoreDisplay** is correctly updated (10%).
5. **Singleton** pattern correctly implemented (10%).
6. **Factory** pattern correctly implemented (20%).
7. **Observer** pattern correctly implemented (20%).
If the program does not compile (e.g., not a valid JavaScript file), the score is 0. If it runs, the score is inversely proportional to the number of errors. If the code has runtime errors (crash), there is a 20-point penalty, plus a penalty for any additional part that cannot be checked.
## How to submit
<p align="center">
<img src="assets/submission.png" width="600" />
</p>
1. After completing your code, make sure to fill out the [Submission Notes](./SubmissionNotes.md) with your basic info and indicate whether you received any help. Feel free to add any relevant information.
2. Zip the folder of this repository containing your solution.
3. Submit the homework using the class [submission system](https://homework.designware.xyz). Choose `HW6`.
4. For any problems, feel free to contact the professor or TA via Discord.
**NOTES**
- Only submissions made through the system will be considered (e.g., no direct emails to the TA or Prof).
- You can resubmit as many times as you want; only the last submission will be considered.
- Submissions after the deadline (even a few minutes) will receive a penalty of 20%. Submissions made after 24 hours from the deadline will be ignored (score will be 0).
- Keep a screenshot that proves your completed submission.
- Coding style may be considered in grading.

17
SubmissionNotes.md Normal file
View File

@ -0,0 +1,17 @@
# Homework submission form
1. **Your name**: NAME
2. **KAIST ID**: 0000000
3. **Email**: YOUR_EMAIL@kaist.ac.kr
---
## Description
Feel free to use this space to add any relevant information. You can add, for example:
- Links to images/Video/Additional material\*\*: [example](http://...)
- List the people/resources you received help from: ...
- Anything else you want to say about how to use your softare, issues, or limitations of your work

BIN
assets/main.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@ -0,0 +1,128 @@
@startuml
https://www.plantuml.com/plantuml/uml/D8b9_sj8003lxulCoVj7WiISfkqBiIzS_3Hj2K5eX4y_ymvpg4DL_RFWVCRhk__rLuFnjFpzyxFl---fpuS_zNSnld_-bvy_l0o5SmSqKDotRuPu67KBvizQ2AA4KaO-Zc0yrW05au1e0M-oz4RDM19z7rgBSoQVQXkiyCnu_d7s6rpTwZ51Zkz6C4S2V4b3tKRKcckzJi4ezbMc4DgGGPjDmijOtNLgbQFBBH9NHc_OAyczawNUxKIzU4V_L7Wg3emdwto8OP7j_F1I9OvkiCYkWKbJ3eXCFU6e6K0Y61Y_RglcqAawJbq0SnLb9-YRY07qMPQ7cu9aAVCP2HiWGY-EpS3PIIbU3R5H43lCYkgmt0Vwd7Jwewjy-hnZIOFPbf1KllOHE9arw2S7LQxj0t3lI2d73f8p9nBuHlxl-vVRtcvhec6nQsv8FWrfm-bfFKCgojiWl8dYD2Sq3DxiPTYS87fXCvS6uv5bxhuvtl6oJKxZrc9Ac-BYMFCxs3gqodlBnZFpTGh2Vl94QPBuQ5eSsj-RTTklQoYq0jnWeooUML4TeiAe40V1iKqJv5VwTM4bS9KYaidgUO8amMywfreYrk9fsn-QJZ9Y3SZaimC6fdHYqJZRGHPEfMrUY-nBYJwMNKIgI7QxN1GqPVMJVQvnDbmRlit7oLjmUQ_6FFJ0kmhnWtk6hJzQHnltvYYNgOkaXojtHPRr2wticUa5m_bTASrPFx7Usobxr-9-9Hf3Ir-1n3zl7_pWqU4dlF8w7BCh0T2JnrxX6srM2SdLotsXhCK8b5GQiQD6Fa6WoXIAeaht2RFasHltWRmp5yqV8ubfF3LMjuCR2JBVrw8NlgYym8RFVltwjxSgwd7RXi7l_XL4zd0fBcTWh-umxBgYsm73MZG1zd2u1zbY4dMob8bKUqRG_pxPiWmByz9cmFeKywFuaP_8K3UmzVK7RBWmeaKwYGOJKduWE1S0ZHP42Um1W3kmDQ7xY8ugU3iuwF6f67otq5X3x7p3rgrVZ1ZvcXgdQbodo1IOJdXprPbxhIToOrdjksroEHeyduk-86KOtRwNzNOaFSSeVvA2SKtMkmOh87RA73PGbgNbO-0OAI0f3vw90hwhjSUNMXaifML6-PBncQiU1O3gdnL18xGcY4cX2CGti1FkW4opcuz8lFXqyoC8WH-Df5btobIPQayQMpISUIUz012xzb6HgdKGMrkhKPY8FeToVHkAZ6QNcv-Kv6CE7L4TZfnZgZrKyEwX5GSSns0-1SzLFBk1JJTzHkPeZPqCEjzPPJWqCAE_bKvyIkrMzAlY6MMNE79TjtIqTl5SSTq0f3QWb5tUYzIQyoN5rmhEixxspP-BIV_7dDk_l78EzRVDcnAy4JrfzyCsT4CZM_FZcF9CB5WrdyEP1nE-JOE1AO-QCaMKNdM_YnRNF5Zz9wL6Fpvj8C9_f5BpAO69wxqmqhOZuzhuz9bYliHJz387DcCPGUEUmUxpmg62cIvGeGkx-zt3ptti3Rn77QHRGqTree3aeMMP3UV5vLI19oHOu9YDsdzbI8FpzInn4VxY3GWZuPNN6hcOBSJWcRRXD2WzUcaTZczKunrPbxOIH92EbhVM6rd1yFD6wUJ2ziJTl_WuH8L8ofUUmrOe4uPfmLVtMW8uYdfyMbYBYJNxdsIxpg6sGaOhpcAMSlrY39rllFJsfTkA1S0vRVjysITh-Nr8g_qhDdkte2AjqA5Zg-zNS7S7grQORfMgkZmZ8HC7kN5Emg1i6-iGNYiwQT7DvYGwHhmVcDdxcVc-z5HEYXV6vZVSSzvZwfaJj70voYXMGaUf5xjCo4EP2H5IHdj8iRFtKkRX8M2aNGTyASCrZroutP_GID_glm40
' Subject
namespace Subject.js {
class Subject{
- observers: Objects[]
+ constructor()
+ subscribe(observer: Object)
+ unsubscribe(observer: Object)
+ unsubscribeAll()
+ notifySubscribers(source: string)
}
interface Observer{
+update(source: string, ...others)
}
Subject .. Observer #blue;line.dotted;text:blue : notifySubscribers calls update
}
' Targets
namespace Target.js {
class Target extends Subject.js.Subject implements Subject.js.Observer{
-visible: boolean
-x: number
-y: number
-width: number
-height: number
-img: PImage
+constructor(x:number, ,y:number, width:number)
+getPoints(): number
+draw()
+isHit(x:number, y:number): boolean
+shoot(x:number, y:number)
+update(source: string, ...others)
}
class TeddyTarget extends Target {
+constructor(x:number, y:number, width:number)
+getPoints(): number
}
class DuckTarget extends Target{
+constructor(x:number, y:number, width:number)
+getPoints(): number
}
class SquirrelTarget extends Target{
+constructor(x:number, y:number, width:number)
+getPoints(): number
}
class TargetFactory<Singleton>{
+{static}getInstance(): TargetFactory
+getTargetsByName(targetNames: string[], targetWidth:number, y:number)
+getRandomTargets(numTargets:number, targetWidth:number, y:number)
}
note left of TargetFactory : getInstance is STATIC
' Relationships
TargetFactory .. TeddyTarget #blue;line.dotted;text:blue : uses
TargetFactory .. DuckTarget #blue;line.dotted;text:blue : uses
TargetFactory .. SquirrelTarget #blue;line.dotted;text:blue : uses
}
' Gun and Bullet
namespace Gun.js {
class Gun extends Subject.js.Subject {
-cursor: PImage
-shotSound: SoundFile
-emptySound: SoundFile
-totShots: number
-remainingShots: number
-bullets: Bullet[]
+constructor(totShots:number)
+draw()
+reload()
+getRemainingShots():number
+shoot()
}
class Bullet {
-x:number
-y:number
-visible: boolean
-img:PImage
+constructor(x:number, y:number)
+draw()
}
Gun "1" -- "many" Bullet #blue;line.dotted;text:blue : contains
}
' Score Display
namespace ScoreDisplay.js {
class ScoreDisplay implements Subject.js.Observer{
-img: PImage
-shotLeft: number
-score: number
+constructor(initialBullets:number)
+draw()
+resetScore()
+addScore(scoreToAdd:number)
+setBullets(numBullets:number)
+update(source: string, ...others)
}
}
@enduml

View File

@ -0,0 +1,13 @@
@startjson
{
"BULLET_SIZE":"20",
"CURSOR_SIZE":"80",
"TARGET_WIDTH":"100",
"BULLET_DURATION":"2000",
"BULLET_HOLE_SIZE":"20",
"MAX_TARGETS":"5",
"TOT_SHOTS":"6",
"FONT_SIZE":"25"
}
@endjson

BIN
assets/submission.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
assets/uml_classes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

BIN
assets/uml_constants.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

9
css/style.css Normal file
View File

@ -0,0 +1,9 @@
html,
body {
margin: 0;
align-items: center;
text-align: center;
}
canvas {
display: block;
}

BIN
data/bullet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
data/bulletHole.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
data/cursor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
data/duck.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
data/empty.mp3 Normal file

Binary file not shown.

BIN
data/font.vlw Normal file

Binary file not shown.

BIN
data/shot.mp3 Normal file

Binary file not shown.

BIN
data/squirrel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
data/teddy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

20
index.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"
integrity="sha512-4P0ZJ49OMXe3jXT+EsEaq82eNwFeyYL81LeHGzGcEhowFbTqeQ80q+NEkgsE8tHPs6aCqvi7U+XWliAjDmT5Lg=="
crossorigin="anonymous"
></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/addons/p5.sound.js"
integrity="sha512-U2sgwrFhl+Tgx9iGH9h5Ba2WyIjyCes+D0prtIFw3a0V+/fkaeL5Cd/VjyPHno9kUPE1rnNhBGTyvtZsfJp0xg=="
crossorigin="anonymous"
></script>
<meta charset="utf-8" />
</head>
<body>
<script defer type="module" src="./src/main.js"></script>
</body>
</html>

698
package-lock.json generated Normal file
View File

@ -0,0 +1,698 @@
{
"name": "homework-oop",
"version": "0.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "homework-oop",
"version": "0.0.0",
"dependencies": {
"rxjs": "^7.5.5"
},
"devDependencies": {
"vite": "^2.7.2"
}
},
"node_modules/esbuild": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.13.15.tgz",
"integrity": "sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw==",
"dev": true,
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
},
"optionalDependencies": {
"esbuild-android-arm64": "0.13.15",
"esbuild-darwin-64": "0.13.15",
"esbuild-darwin-arm64": "0.13.15",
"esbuild-freebsd-64": "0.13.15",
"esbuild-freebsd-arm64": "0.13.15",
"esbuild-linux-32": "0.13.15",
"esbuild-linux-64": "0.13.15",
"esbuild-linux-arm": "0.13.15",
"esbuild-linux-arm64": "0.13.15",
"esbuild-linux-mips64le": "0.13.15",
"esbuild-linux-ppc64le": "0.13.15",
"esbuild-netbsd-64": "0.13.15",
"esbuild-openbsd-64": "0.13.15",
"esbuild-sunos-64": "0.13.15",
"esbuild-windows-32": "0.13.15",
"esbuild-windows-64": "0.13.15",
"esbuild-windows-arm64": "0.13.15"
}
},
"node_modules/esbuild-android-arm64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz",
"integrity": "sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
]
},
"node_modules/esbuild-darwin-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.15.tgz",
"integrity": "sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
]
},
"node_modules/esbuild-darwin-arm64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.15.tgz",
"integrity": "sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
]
},
"node_modules/esbuild-freebsd-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.15.tgz",
"integrity": "sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/esbuild-freebsd-arm64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.15.tgz",
"integrity": "sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/esbuild-linux-32": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.15.tgz",
"integrity": "sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/esbuild-linux-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.15.tgz",
"integrity": "sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/esbuild-linux-arm": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.15.tgz",
"integrity": "sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/esbuild-linux-arm64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.15.tgz",
"integrity": "sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/esbuild-linux-mips64le": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.15.tgz",
"integrity": "sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg==",
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/esbuild-linux-ppc64le": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.15.tgz",
"integrity": "sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/esbuild-netbsd-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.15.tgz",
"integrity": "sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
]
},
"node_modules/esbuild-openbsd-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.15.tgz",
"integrity": "sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
]
},
"node_modules/esbuild-sunos-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.15.tgz",
"integrity": "sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
]
},
"node_modules/esbuild-windows-32": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.15.tgz",
"integrity": "sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
]
},
"node_modules/esbuild-windows-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.15.tgz",
"integrity": "sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
]
},
"node_modules/esbuild-windows-arm64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.15.tgz",
"integrity": "sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
]
},
"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/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/is-core-module": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
"integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==",
"dev": true,
"dependencies": {
"has": "^1.0.3"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/nanoid": {
"version": "3.1.30",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz",
"integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==",
"dev": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"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/postcss": {
"version": "8.4.5",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz",
"integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==",
"dev": true,
"dependencies": {
"nanoid": "^3.1.30",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
}
},
"node_modules/resolve": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
"integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
"dev": true,
"dependencies": {
"is-core-module": "^2.2.0",
"path-parse": "^1.0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/rollup": {
"version": "2.61.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.61.1.tgz",
"integrity": "sha512-BbTXlEvB8d+XFbK/7E5doIcRtxWPRiqr0eb5vQ0+2paMM04Ye4PZY5nHOQef2ix24l/L0SpLd5hwcH15QHPdvA==",
"dev": true,
"bin": {
"rollup": "dist/bin/rollup"
},
"engines": {
"node": ">=10.0.0"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
"node_modules/rxjs": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz",
"integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/source-map-js": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
"integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/vite": {
"version": "2.7.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-2.7.2.tgz",
"integrity": "sha512-wMffVVdKZRZP/HwW3yttKL8X+IJePz7bUcnGm0vqljffpVwHpjWC3duZtJQHAGvy+wrTjmwU7vkULpZ1dVXY6w==",
"dev": true,
"dependencies": {
"esbuild": "^0.13.12",
"postcss": "^8.3.11",
"resolve": "^1.20.0",
"rollup": "^2.59.0"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
"node": ">=12.2.0"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
},
"peerDependencies": {
"less": "*",
"sass": "*",
"stylus": "*"
},
"peerDependenciesMeta": {
"less": {
"optional": true
},
"sass": {
"optional": true
},
"stylus": {
"optional": true
}
}
}
},
"dependencies": {
"esbuild": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.13.15.tgz",
"integrity": "sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw==",
"dev": true,
"requires": {
"esbuild-android-arm64": "0.13.15",
"esbuild-darwin-64": "0.13.15",
"esbuild-darwin-arm64": "0.13.15",
"esbuild-freebsd-64": "0.13.15",
"esbuild-freebsd-arm64": "0.13.15",
"esbuild-linux-32": "0.13.15",
"esbuild-linux-64": "0.13.15",
"esbuild-linux-arm": "0.13.15",
"esbuild-linux-arm64": "0.13.15",
"esbuild-linux-mips64le": "0.13.15",
"esbuild-linux-ppc64le": "0.13.15",
"esbuild-netbsd-64": "0.13.15",
"esbuild-openbsd-64": "0.13.15",
"esbuild-sunos-64": "0.13.15",
"esbuild-windows-32": "0.13.15",
"esbuild-windows-64": "0.13.15",
"esbuild-windows-arm64": "0.13.15"
}
},
"esbuild-android-arm64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz",
"integrity": "sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg==",
"dev": true,
"optional": true
},
"esbuild-darwin-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.15.tgz",
"integrity": "sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ==",
"dev": true,
"optional": true
},
"esbuild-darwin-arm64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.15.tgz",
"integrity": "sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ==",
"dev": true,
"optional": true
},
"esbuild-freebsd-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.15.tgz",
"integrity": "sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA==",
"dev": true,
"optional": true
},
"esbuild-freebsd-arm64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.15.tgz",
"integrity": "sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ==",
"dev": true,
"optional": true
},
"esbuild-linux-32": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.15.tgz",
"integrity": "sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g==",
"dev": true,
"optional": true
},
"esbuild-linux-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.15.tgz",
"integrity": "sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA==",
"dev": true,
"optional": true
},
"esbuild-linux-arm": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.15.tgz",
"integrity": "sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA==",
"dev": true,
"optional": true
},
"esbuild-linux-arm64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.15.tgz",
"integrity": "sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA==",
"dev": true,
"optional": true
},
"esbuild-linux-mips64le": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.15.tgz",
"integrity": "sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg==",
"dev": true,
"optional": true
},
"esbuild-linux-ppc64le": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.15.tgz",
"integrity": "sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ==",
"dev": true,
"optional": true
},
"esbuild-netbsd-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.15.tgz",
"integrity": "sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w==",
"dev": true,
"optional": true
},
"esbuild-openbsd-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.15.tgz",
"integrity": "sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g==",
"dev": true,
"optional": true
},
"esbuild-sunos-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.15.tgz",
"integrity": "sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw==",
"dev": true,
"optional": true
},
"esbuild-windows-32": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.15.tgz",
"integrity": "sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw==",
"dev": true,
"optional": true
},
"esbuild-windows-64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.15.tgz",
"integrity": "sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ==",
"dev": true,
"optional": true
},
"esbuild-windows-arm64": {
"version": "0.13.15",
"resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.15.tgz",
"integrity": "sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA==",
"dev": true,
"optional": 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
},
"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"
}
},
"is-core-module": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
"integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
},
"nanoid": {
"version": "3.1.30",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz",
"integrity": "sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==",
"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
},
"postcss": {
"version": "8.4.5",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.5.tgz",
"integrity": "sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==",
"dev": true,
"requires": {
"nanoid": "^3.1.30",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.1"
}
},
"resolve": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
"integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
"dev": true,
"requires": {
"is-core-module": "^2.2.0",
"path-parse": "^1.0.6"
}
},
"rollup": {
"version": "2.61.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.61.1.tgz",
"integrity": "sha512-BbTXlEvB8d+XFbK/7E5doIcRtxWPRiqr0eb5vQ0+2paMM04Ye4PZY5nHOQef2ix24l/L0SpLd5hwcH15QHPdvA==",
"dev": true,
"requires": {
"fsevents": "~2.3.2"
}
},
"rxjs": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz",
"integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==",
"requires": {
"tslib": "^2.1.0"
}
},
"source-map-js": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.1.tgz",
"integrity": "sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==",
"dev": true
},
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"vite": {
"version": "2.7.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-2.7.2.tgz",
"integrity": "sha512-wMffVVdKZRZP/HwW3yttKL8X+IJePz7bUcnGm0vqljffpVwHpjWC3duZtJQHAGvy+wrTjmwU7vkULpZ1dVXY6w==",
"dev": true,
"requires": {
"esbuild": "^0.13.12",
"fsevents": "~2.3.2",
"postcss": "^8.3.11",
"resolve": "^1.20.0",
"rollup": "^2.59.0"
}
}
}
}

13
package.json Normal file
View File

@ -0,0 +1,13 @@
{
"name": "homework-oop",
"version": "0.0.0",
"scripts": {
"dev": "vite"
},
"devDependencies": {
"vite": "^2.7.2"
},
"dependencies": {
"rxjs": "^7.5.5"
}
}

10
src/Constants.js Normal file
View File

@ -0,0 +1,10 @@
// Constants for the game
// Use them if you want to
export const BULLET_SIZE = 20;
export const CURSOR_SIZE = 80;
export const TARGET_WIDTH = 100;
export const BULLET_DURATION = 2000;
export const BULLET_HOLE_SIZE = 20;
export const MAX_TARGETS = 5;
export const TOT_SHOTS = 6;
export const FONT_SIZE = 25;

23
src/Gun.js Normal file
View File

@ -0,0 +1,23 @@
import { CURSOR_SIZE, BULLET_HOLE_SIZE, BULLET_DURATION } from './Constants.js';
import { Subject } from './Subject';
// Assets
import cursor from '../data/cursor.png';
import bulletHole from '../data/bulletHole.png';
import shot from '../data/shot.mp3';
import empty from '../data/empty.mp3';
class Gun {
// TO DO
}
// Bullet
class Bullet {
// TO DO
}
export { Gun };

11
src/ScoreDisplay.js Normal file
View File

@ -0,0 +1,11 @@
import { BULLET_SIZE, FONT_SIZE } from './Constants.js';
import { Gun } from './Gun.js';
import { Target } from './Target';
import bullet from '../data/bullet.png';
class ScoreDisplay {
// TO DO
}
export { ScoreDisplay };

5
src/Subject.js Normal file
View File

@ -0,0 +1,5 @@
class Subject {
// TO DO
}
export { Subject };

21
src/Target.js Normal file
View File

@ -0,0 +1,21 @@
import { Subject } from './Subject';
import { Gun } from './Gun';
import teddy from '../data/teddy.png';
import duck from '../data/duck.png';
import squirrel from '../data/squirrel.png';
class Target {
// TO DO
}
// TO DO
// class TeddyTarget ...
// class DuckTarget ...
// class SquirrelTarget ...
class TargetFactory {
// TO DO
}
export { Target, TargetFactory };

51
src/main.js Normal file
View File

@ -0,0 +1,51 @@
import '../css/style.css';
import { MAX_TARGETS, TARGET_WIDTH, TOT_SHOTS } from './Constants.js';
import { ScoreDisplay } from './ScoreDisplay.js';
import { Gun } from './Gun.js';
import { TargetFactory } from './Target.js';
// Globals
let gun;
let score;
let targets = [];
function setup() {
createCanvas(800, 600);
// 1. Init gun and score display
// 2. Init the targets
// 3. Subscribe gun
}
function draw() {
background('#eeeeee');
// draw targets, gun, bullets, score
}
// Shoot
function mousePressed() {
// shoot
}
// Spacebar to reload
function keyPressed() {
if (key === ' ') {
// reset score and targets
}
}
// init the targets
function initTargets() {
// Create new targets from the factory
// Remember to unsubscribe the previous targets and to subscribe the new ones
}
// Do not touch these
window.setup = setup;
window.draw = draw;
window.mousePressed = mousePressed;
window.keyPressed = keyPressed;