├── .gitignore
├── README.md
├── example
├── package-lock.json
├── package.json
├── public
│ ├── Madza-Chords_of_Life.mp3
│ ├── Madza-Late_Night_Drive.mp3
│ ├── Madza-Persistence.mp3
│ ├── favicon.ico
│ ├── index.html
│ └── manifest.json
└── src
│ ├── App.js
│ ├── components
│ ├── Footer.js
│ ├── Footer.module.css
│ ├── Header.js
│ ├── Header.module.css
│ ├── Wrapper.js
│ └── Wrapper.module.css
│ ├── index.css
│ └── index.js
├── package-lock.json
├── package.json
└── src
├── components
├── ButtonsBox.js
├── ButtonsBox.module.css
├── LoopCurrent.js
├── LoopCurrent.module.css
├── Next.js
├── Next.module.css
├── PageTemplate.js
├── PageTemplate.module.css
├── Pause.js
├── Pause.module.css
├── Play.js
├── Play.module.css
├── PlayerTemplate.js
├── PlayerTemplate.module.css
├── PlaylistItem.js
├── PlaylistItem.module.css
├── PlaylistTemplate.js
├── PlaylistTemplate.module.css
├── Previous.js
├── Previous.module.css
├── Progress.js
├── Progress.module.css
├── Search.js
├── Search.module.css
├── Shuffle.js
├── Shuffle.module.css
├── TagItem.js
├── TagItem.module.css
├── TagsTemplate.js
├── TagsTemplate.module.css
├── Time.js
├── Time.module.css
├── Title.js
├── Title.module.css
├── Volume.js
└── Volume.module.css
├── icons
├── loop_current.png
├── loop_none.png
├── next.png
├── pause.png
├── play.png
├── previous.png
├── shuffle_all.png
└── shuffle_none.png
├── index.js
└── styles
└── Player.module.css
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # See https://help.github.com/ignore-files/ for more about ignoring files.
3 |
4 | # dependencies
5 | node_modules
6 |
7 | # builds
8 | build
9 | dist
10 | .rpt2_cache
11 |
12 | # misc
13 | .DS_Store
14 | .env
15 | .env.local
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 |
20 | #log files
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React/NextJS Audio Player
2 |
3 | [](https://github.com/madzadev/audio-player/graphs/commit-activity)
4 | [](https://github.com/madzadev/audio-player/issues/)
5 | [](http://makeapullrequest.com)
6 | [](https://choosealicense.com/licenses/mit/)
7 |
8 | 
9 |
10 | ### Demo: [https://audioplayer.madza.dev](https://audioplayer.madza.dev)
11 |
12 | ---
13 |
14 | ## Installation
15 |
16 | ```javascript
17 | npm install @madzadev/audio-player
18 | ```
19 |
20 | If you are using NPM v7 or above, you need to add `--legacy-peer-deps` at the end of the command above.
21 |
22 | ## Usage
23 |
24 | ```javascript
25 | import Player from "@madzadev/audio-player";
26 | import "@madzadev/audio-player/dist/index.css";
27 | ```
28 |
29 | ```javascript
30 | const tracks = [
31 | {
32 | url: "https://audioplayer.madza.dev/Madza-Chords_of_Life.mp3",
33 | title: "Madza - Chords of Life",
34 | tags: ["house"],
35 | },
36 | {
37 | url: "https://audioplayer.madza.dev/Madza-Late_Night_Drive.mp3",
38 | title: "Madza - Late Night Drive",
39 | tags: ["dnb"],
40 | },
41 | {
42 | url: "https://audioplayer.madza.dev/Madza-Persistence.mp3",
43 | title: "Madza - Persistence",
44 | tags: ["dubstep"],
45 | },
46 | ];
47 | ```
48 |
49 | ```javascript
50 |
51 | ```
52 |
53 | `trackList` is the mandatory prop and requires to pass in an array consisting of objects with `url`, `title` and `tags` keys.
54 |
55 | ## Config for NextJS
56 |
57 | If you are working on NextJS, there are 3 additional steps:
58 |
59 | 1. `npm i next-images next-transpile-modules`
60 | 2. create `next.config.js` in your project's root
61 | 3. paste this in the newly created config file:
62 |
63 | ```javascript
64 | const withImages = require("next-images");
65 | const withTM = require("next-transpile-modules")(["@madzadev/audio-player"]);
66 |
67 | module.exports = withImages(withTM());
68 | ```
69 |
70 | ## Options
71 |
72 | The default values of available options props are displayed.
73 |
74 | ```javascript
75 |
82 | ```
83 |
84 | ## Color schemes
85 |
86 | You can further customize the player UI by editing the colors variable below.
87 |
88 | Pre-defined color schemes are planned in the future.
89 |
90 | ```javascript
91 | const colors = `html {
92 | --tagsBackground: #9440f3;
93 | --tagsText: #ffffff;
94 | --tagsBackgroundHoverActive: #2cc0a0;
95 | --tagsTextHoverActive: #ffffff;
96 | --searchBackground: #18191f;
97 | --searchText: #ffffff;
98 | --searchPlaceHolder: #575a77;
99 | --playerBackground: #18191f;
100 | --titleColor: #ffffff;
101 | --timeColor: #ffffff;
102 | --progressSlider: #9440f3;
103 | --progressUsed: #ffffff;
104 | --progressLeft: #151616;
105 | --volumeSlider: #9440f3;
106 | --volumeUsed: #ffffff;
107 | --volumeLeft: #151616;
108 | --playlistBackground: #18191f;
109 | --playlistText: #575a77;
110 | --playlistBackgroundHoverActive: #18191f;
111 | --playlistTextHoverActive: #ffffff;
112 | }`;
113 | ```
114 |
115 | ```javascript
116 |
117 | ```
118 |
119 | ## Final notes
120 |
121 | It's recommended to use CMS like [Contentful](https://www.contentful.com) or [DatoCMS](https://www.datocms.com/) to manage your audio files and access them via API.
122 |
--------------------------------------------------------------------------------
/example/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@madzadev/audio-player-example",
3 | "version": "0.1.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "@madzadev/audio-player-example",
9 | "version": "0.1.0",
10 | "dependencies": {
11 | "@madzadev/audio-player": "file:..",
12 | "react": "file:../node_modules/react",
13 | "react-dom": "file:../node_modules/react-dom",
14 | "react-scripts": "file:../node_modules/react-scripts"
15 | },
16 | "devDependencies": {
17 | "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
18 | "react-syntax-highlighter": "^15.4.3"
19 | }
20 | },
21 | "..": {
22 | "name": "@madzadev/audio-player",
23 | "version": "1.1.11",
24 | "license": "MIT",
25 | "dependencies": {
26 | "styled-components": "^5.2.1"
27 | },
28 | "devDependencies": {
29 | "cross-env": "^7.0.2",
30 | "microbundle-crl": "^0.13.10",
31 | "npm-run-all": "^4.1.5",
32 | "react": "^16.13.1",
33 | "react-dom": "^16.13.1",
34 | "react-scripts": "^4.0.3"
35 | },
36 | "engines": {
37 | "node": ">=10"
38 | },
39 | "peerDependencies": {
40 | "react": "^16.8.0"
41 | }
42 | },
43 | "../node_modules/react": {
44 | "version": "16.14.0",
45 | "license": "MIT",
46 | "dependencies": {
47 | "loose-envify": "^1.1.0",
48 | "object-assign": "^4.1.1",
49 | "prop-types": "^15.6.2"
50 | },
51 | "engines": {
52 | "node": ">=0.10.0"
53 | }
54 | },
55 | "../node_modules/react-dom": {
56 | "version": "16.14.0",
57 | "license": "MIT",
58 | "dependencies": {
59 | "loose-envify": "^1.1.0",
60 | "object-assign": "^4.1.1",
61 | "prop-types": "^15.6.2",
62 | "scheduler": "^0.19.1"
63 | },
64 | "peerDependencies": {
65 | "react": "^16.14.0"
66 | }
67 | },
68 | "../node_modules/react-scripts": {
69 | "version": "4.0.3",
70 | "license": "MIT",
71 | "dependencies": {
72 | "@babel/core": "7.12.3",
73 | "@pmmmwh/react-refresh-webpack-plugin": "0.4.3",
74 | "@svgr/webpack": "5.5.0",
75 | "@typescript-eslint/eslint-plugin": "^4.5.0",
76 | "@typescript-eslint/parser": "^4.5.0",
77 | "babel-eslint": "^10.1.0",
78 | "babel-jest": "^26.6.0",
79 | "babel-loader": "8.1.0",
80 | "babel-plugin-named-asset-import": "^0.3.7",
81 | "babel-preset-react-app": "^10.0.0",
82 | "bfj": "^7.0.2",
83 | "camelcase": "^6.1.0",
84 | "case-sensitive-paths-webpack-plugin": "2.3.0",
85 | "css-loader": "4.3.0",
86 | "dotenv": "8.2.0",
87 | "dotenv-expand": "5.1.0",
88 | "eslint": "^7.11.0",
89 | "eslint-config-react-app": "^6.0.0",
90 | "eslint-plugin-flowtype": "^5.2.0",
91 | "eslint-plugin-import": "^2.22.1",
92 | "eslint-plugin-jest": "^24.1.0",
93 | "eslint-plugin-jsx-a11y": "^6.3.1",
94 | "eslint-plugin-react": "^7.21.5",
95 | "eslint-plugin-react-hooks": "^4.2.0",
96 | "eslint-plugin-testing-library": "^3.9.2",
97 | "eslint-webpack-plugin": "^2.5.2",
98 | "file-loader": "6.1.1",
99 | "fs-extra": "^9.0.1",
100 | "html-webpack-plugin": "4.5.0",
101 | "identity-obj-proxy": "3.0.0",
102 | "jest": "26.6.0",
103 | "jest-circus": "26.6.0",
104 | "jest-resolve": "26.6.0",
105 | "jest-watch-typeahead": "0.6.1",
106 | "mini-css-extract-plugin": "0.11.3",
107 | "optimize-css-assets-webpack-plugin": "5.0.4",
108 | "pnp-webpack-plugin": "1.6.4",
109 | "postcss-flexbugs-fixes": "4.2.1",
110 | "postcss-loader": "3.0.0",
111 | "postcss-normalize": "8.0.1",
112 | "postcss-preset-env": "6.7.0",
113 | "postcss-safe-parser": "5.0.2",
114 | "prompts": "2.4.0",
115 | "react-app-polyfill": "^2.0.0",
116 | "react-dev-utils": "^11.0.3",
117 | "react-refresh": "^0.8.3",
118 | "resolve": "1.18.1",
119 | "resolve-url-loader": "^3.1.2",
120 | "sass-loader": "^10.0.5",
121 | "semver": "7.3.2",
122 | "style-loader": "1.3.0",
123 | "terser-webpack-plugin": "4.2.3",
124 | "ts-pnp": "1.2.0",
125 | "url-loader": "4.1.1",
126 | "webpack": "4.44.2",
127 | "webpack-dev-server": "3.11.1",
128 | "webpack-manifest-plugin": "2.2.0",
129 | "workbox-webpack-plugin": "5.1.4"
130 | },
131 | "bin": {
132 | "react-scripts": "bin/react-scripts.js"
133 | },
134 | "engines": {
135 | "node": "^10.12.0 || >=12.0.0"
136 | },
137 | "optionalDependencies": {
138 | "fsevents": "^2.1.3"
139 | },
140 | "peerDependencies": {
141 | "react": ">= 16",
142 | "typescript": "^3.2.1 || ^4"
143 | },
144 | "peerDependenciesMeta": {
145 | "typescript": {
146 | "optional": true
147 | }
148 | }
149 | },
150 | "node_modules/@babel/code-frame": {
151 | "version": "7.12.13",
152 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
153 | "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
154 | "dev": true,
155 | "peer": true,
156 | "dependencies": {
157 | "@babel/highlight": "^7.12.13"
158 | }
159 | },
160 | "node_modules/@babel/compat-data": {
161 | "version": "7.14.0",
162 | "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz",
163 | "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==",
164 | "dev": true,
165 | "peer": true
166 | },
167 | "node_modules/@babel/core": {
168 | "version": "7.14.3",
169 | "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.3.tgz",
170 | "integrity": "sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==",
171 | "dev": true,
172 | "peer": true,
173 | "dependencies": {
174 | "@babel/code-frame": "^7.12.13",
175 | "@babel/generator": "^7.14.3",
176 | "@babel/helper-compilation-targets": "^7.13.16",
177 | "@babel/helper-module-transforms": "^7.14.2",
178 | "@babel/helpers": "^7.14.0",
179 | "@babel/parser": "^7.14.3",
180 | "@babel/template": "^7.12.13",
181 | "@babel/traverse": "^7.14.2",
182 | "@babel/types": "^7.14.2",
183 | "convert-source-map": "^1.7.0",
184 | "debug": "^4.1.0",
185 | "gensync": "^1.0.0-beta.2",
186 | "json5": "^2.1.2",
187 | "semver": "^6.3.0",
188 | "source-map": "^0.5.0"
189 | },
190 | "engines": {
191 | "node": ">=6.9.0"
192 | },
193 | "funding": {
194 | "type": "opencollective",
195 | "url": "https://opencollective.com/babel"
196 | }
197 | },
198 | "node_modules/@babel/generator": {
199 | "version": "7.14.3",
200 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz",
201 | "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==",
202 | "dev": true,
203 | "peer": true,
204 | "dependencies": {
205 | "@babel/types": "^7.14.2",
206 | "jsesc": "^2.5.1",
207 | "source-map": "^0.5.0"
208 | }
209 | },
210 | "node_modules/@babel/helper-compilation-targets": {
211 | "version": "7.13.16",
212 | "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz",
213 | "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==",
214 | "dev": true,
215 | "peer": true,
216 | "dependencies": {
217 | "@babel/compat-data": "^7.13.15",
218 | "@babel/helper-validator-option": "^7.12.17",
219 | "browserslist": "^4.14.5",
220 | "semver": "^6.3.0"
221 | },
222 | "peerDependencies": {
223 | "@babel/core": "^7.0.0"
224 | }
225 | },
226 | "node_modules/@babel/helper-function-name": {
227 | "version": "7.14.2",
228 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
229 | "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
230 | "dev": true,
231 | "peer": true,
232 | "dependencies": {
233 | "@babel/helper-get-function-arity": "^7.12.13",
234 | "@babel/template": "^7.12.13",
235 | "@babel/types": "^7.14.2"
236 | }
237 | },
238 | "node_modules/@babel/helper-get-function-arity": {
239 | "version": "7.12.13",
240 | "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
241 | "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
242 | "dev": true,
243 | "peer": true,
244 | "dependencies": {
245 | "@babel/types": "^7.12.13"
246 | }
247 | },
248 | "node_modules/@babel/helper-member-expression-to-functions": {
249 | "version": "7.13.12",
250 | "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz",
251 | "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==",
252 | "dev": true,
253 | "peer": true,
254 | "dependencies": {
255 | "@babel/types": "^7.13.12"
256 | }
257 | },
258 | "node_modules/@babel/helper-module-imports": {
259 | "version": "7.13.12",
260 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz",
261 | "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==",
262 | "dev": true,
263 | "peer": true,
264 | "dependencies": {
265 | "@babel/types": "^7.13.12"
266 | }
267 | },
268 | "node_modules/@babel/helper-module-transforms": {
269 | "version": "7.14.2",
270 | "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz",
271 | "integrity": "sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==",
272 | "dev": true,
273 | "peer": true,
274 | "dependencies": {
275 | "@babel/helper-module-imports": "^7.13.12",
276 | "@babel/helper-replace-supers": "^7.13.12",
277 | "@babel/helper-simple-access": "^7.13.12",
278 | "@babel/helper-split-export-declaration": "^7.12.13",
279 | "@babel/helper-validator-identifier": "^7.14.0",
280 | "@babel/template": "^7.12.13",
281 | "@babel/traverse": "^7.14.2",
282 | "@babel/types": "^7.14.2"
283 | }
284 | },
285 | "node_modules/@babel/helper-optimise-call-expression": {
286 | "version": "7.12.13",
287 | "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz",
288 | "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==",
289 | "dev": true,
290 | "peer": true,
291 | "dependencies": {
292 | "@babel/types": "^7.12.13"
293 | }
294 | },
295 | "node_modules/@babel/helper-plugin-utils": {
296 | "version": "7.13.0",
297 | "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz",
298 | "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==",
299 | "dev": true
300 | },
301 | "node_modules/@babel/helper-replace-supers": {
302 | "version": "7.14.3",
303 | "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.3.tgz",
304 | "integrity": "sha512-Rlh8qEWZSTfdz+tgNV/N4gz1a0TMNwCUcENhMjHTHKp3LseYH5Jha0NSlyTQWMnjbYcwFt+bqAMqSLHVXkQ6UA==",
305 | "dev": true,
306 | "peer": true,
307 | "dependencies": {
308 | "@babel/helper-member-expression-to-functions": "^7.13.12",
309 | "@babel/helper-optimise-call-expression": "^7.12.13",
310 | "@babel/traverse": "^7.14.2",
311 | "@babel/types": "^7.14.2"
312 | }
313 | },
314 | "node_modules/@babel/helper-simple-access": {
315 | "version": "7.13.12",
316 | "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz",
317 | "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==",
318 | "dev": true,
319 | "peer": true,
320 | "dependencies": {
321 | "@babel/types": "^7.13.12"
322 | }
323 | },
324 | "node_modules/@babel/helper-split-export-declaration": {
325 | "version": "7.12.13",
326 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
327 | "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
328 | "dev": true,
329 | "peer": true,
330 | "dependencies": {
331 | "@babel/types": "^7.12.13"
332 | }
333 | },
334 | "node_modules/@babel/helper-validator-identifier": {
335 | "version": "7.14.0",
336 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
337 | "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
338 | "dev": true,
339 | "peer": true
340 | },
341 | "node_modules/@babel/helper-validator-option": {
342 | "version": "7.12.17",
343 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz",
344 | "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==",
345 | "dev": true,
346 | "peer": true
347 | },
348 | "node_modules/@babel/helpers": {
349 | "version": "7.14.0",
350 | "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz",
351 | "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==",
352 | "dev": true,
353 | "peer": true,
354 | "dependencies": {
355 | "@babel/template": "^7.12.13",
356 | "@babel/traverse": "^7.14.0",
357 | "@babel/types": "^7.14.0"
358 | }
359 | },
360 | "node_modules/@babel/highlight": {
361 | "version": "7.14.0",
362 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
363 | "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
364 | "dev": true,
365 | "peer": true,
366 | "dependencies": {
367 | "@babel/helper-validator-identifier": "^7.14.0",
368 | "chalk": "^2.0.0",
369 | "js-tokens": "^4.0.0"
370 | }
371 | },
372 | "node_modules/@babel/parser": {
373 | "version": "7.14.3",
374 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz",
375 | "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==",
376 | "dev": true,
377 | "peer": true,
378 | "bin": {
379 | "parser": "bin/babel-parser.js"
380 | },
381 | "engines": {
382 | "node": ">=6.0.0"
383 | }
384 | },
385 | "node_modules/@babel/plugin-syntax-object-rest-spread": {
386 | "version": "7.8.3",
387 | "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
388 | "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
389 | "dev": true,
390 | "dependencies": {
391 | "@babel/helper-plugin-utils": "^7.8.0"
392 | },
393 | "peerDependencies": {
394 | "@babel/core": "^7.0.0-0"
395 | }
396 | },
397 | "node_modules/@babel/runtime": {
398 | "version": "7.14.0",
399 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz",
400 | "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==",
401 | "dev": true,
402 | "dependencies": {
403 | "regenerator-runtime": "^0.13.4"
404 | }
405 | },
406 | "node_modules/@babel/template": {
407 | "version": "7.12.13",
408 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
409 | "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
410 | "dev": true,
411 | "peer": true,
412 | "dependencies": {
413 | "@babel/code-frame": "^7.12.13",
414 | "@babel/parser": "^7.12.13",
415 | "@babel/types": "^7.12.13"
416 | }
417 | },
418 | "node_modules/@babel/traverse": {
419 | "version": "7.14.2",
420 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz",
421 | "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==",
422 | "dev": true,
423 | "peer": true,
424 | "dependencies": {
425 | "@babel/code-frame": "^7.12.13",
426 | "@babel/generator": "^7.14.2",
427 | "@babel/helper-function-name": "^7.14.2",
428 | "@babel/helper-split-export-declaration": "^7.12.13",
429 | "@babel/parser": "^7.14.2",
430 | "@babel/types": "^7.14.2",
431 | "debug": "^4.1.0",
432 | "globals": "^11.1.0"
433 | }
434 | },
435 | "node_modules/@babel/types": {
436 | "version": "7.14.2",
437 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz",
438 | "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==",
439 | "dev": true,
440 | "peer": true,
441 | "dependencies": {
442 | "@babel/helper-validator-identifier": "^7.14.0",
443 | "to-fast-properties": "^2.0.0"
444 | }
445 | },
446 | "node_modules/@madzadev/audio-player": {
447 | "resolved": "..",
448 | "link": true
449 | },
450 | "node_modules/@types/hast": {
451 | "version": "2.3.1",
452 | "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.1.tgz",
453 | "integrity": "sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q==",
454 | "dev": true,
455 | "dependencies": {
456 | "@types/unist": "*"
457 | }
458 | },
459 | "node_modules/@types/unist": {
460 | "version": "2.0.3",
461 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
462 | "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==",
463 | "dev": true
464 | },
465 | "node_modules/ansi-styles": {
466 | "version": "3.2.1",
467 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
468 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
469 | "dev": true,
470 | "peer": true,
471 | "dependencies": {
472 | "color-convert": "^1.9.0"
473 | },
474 | "engines": {
475 | "node": ">=4"
476 | }
477 | },
478 | "node_modules/browserslist": {
479 | "version": "4.16.6",
480 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
481 | "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
482 | "dev": true,
483 | "peer": true,
484 | "dependencies": {
485 | "caniuse-lite": "^1.0.30001219",
486 | "colorette": "^1.2.2",
487 | "electron-to-chromium": "^1.3.723",
488 | "escalade": "^3.1.1",
489 | "node-releases": "^1.1.71"
490 | },
491 | "bin": {
492 | "browserslist": "cli.js"
493 | },
494 | "engines": {
495 | "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
496 | },
497 | "funding": {
498 | "type": "opencollective",
499 | "url": "https://opencollective.com/browserslist"
500 | }
501 | },
502 | "node_modules/caniuse-lite": {
503 | "version": "1.0.30001228",
504 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz",
505 | "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==",
506 | "dev": true,
507 | "peer": true,
508 | "funding": {
509 | "type": "opencollective",
510 | "url": "https://opencollective.com/browserslist"
511 | }
512 | },
513 | "node_modules/chalk": {
514 | "version": "2.4.2",
515 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
516 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
517 | "dev": true,
518 | "peer": true,
519 | "dependencies": {
520 | "ansi-styles": "^3.2.1",
521 | "escape-string-regexp": "^1.0.5",
522 | "supports-color": "^5.3.0"
523 | },
524 | "engines": {
525 | "node": ">=4"
526 | }
527 | },
528 | "node_modules/character-entities": {
529 | "version": "1.2.4",
530 | "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
531 | "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
532 | "dev": true,
533 | "funding": {
534 | "type": "github",
535 | "url": "https://github.com/sponsors/wooorm"
536 | }
537 | },
538 | "node_modules/character-entities-legacy": {
539 | "version": "1.1.4",
540 | "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
541 | "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
542 | "dev": true,
543 | "funding": {
544 | "type": "github",
545 | "url": "https://github.com/sponsors/wooorm"
546 | }
547 | },
548 | "node_modules/character-reference-invalid": {
549 | "version": "1.1.4",
550 | "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
551 | "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
552 | "dev": true,
553 | "funding": {
554 | "type": "github",
555 | "url": "https://github.com/sponsors/wooorm"
556 | }
557 | },
558 | "node_modules/clipboard": {
559 | "version": "2.0.8",
560 | "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz",
561 | "integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==",
562 | "dev": true,
563 | "optional": true,
564 | "dependencies": {
565 | "good-listener": "^1.2.2",
566 | "select": "^1.1.2",
567 | "tiny-emitter": "^2.0.0"
568 | }
569 | },
570 | "node_modules/color-convert": {
571 | "version": "1.9.3",
572 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
573 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
574 | "dev": true,
575 | "peer": true,
576 | "dependencies": {
577 | "color-name": "1.1.3"
578 | }
579 | },
580 | "node_modules/color-name": {
581 | "version": "1.1.3",
582 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
583 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
584 | "dev": true,
585 | "peer": true
586 | },
587 | "node_modules/colorette": {
588 | "version": "1.2.2",
589 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
590 | "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
591 | "dev": true,
592 | "peer": true
593 | },
594 | "node_modules/comma-separated-tokens": {
595 | "version": "1.0.8",
596 | "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
597 | "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==",
598 | "dev": true,
599 | "funding": {
600 | "type": "github",
601 | "url": "https://github.com/sponsors/wooorm"
602 | }
603 | },
604 | "node_modules/convert-source-map": {
605 | "version": "1.7.0",
606 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
607 | "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
608 | "dev": true,
609 | "peer": true,
610 | "dependencies": {
611 | "safe-buffer": "~5.1.1"
612 | }
613 | },
614 | "node_modules/debug": {
615 | "version": "4.3.1",
616 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
617 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
618 | "dev": true,
619 | "peer": true,
620 | "dependencies": {
621 | "ms": "2.1.2"
622 | },
623 | "engines": {
624 | "node": ">=6.0"
625 | },
626 | "peerDependenciesMeta": {
627 | "supports-color": {
628 | "optional": true
629 | }
630 | }
631 | },
632 | "node_modules/delegate": {
633 | "version": "3.2.0",
634 | "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
635 | "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
636 | "dev": true,
637 | "optional": true
638 | },
639 | "node_modules/electron-to-chromium": {
640 | "version": "1.3.735",
641 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.735.tgz",
642 | "integrity": "sha512-cp7MWzC3NseUJV2FJFgaiesdrS+A8ZUjX5fLAxdRlcaPDkaPGFplX930S5vf84yqDp4LjuLdKouWuVOTwUfqHQ==",
643 | "dev": true,
644 | "peer": true
645 | },
646 | "node_modules/escalade": {
647 | "version": "3.1.1",
648 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
649 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
650 | "dev": true,
651 | "peer": true,
652 | "engines": {
653 | "node": ">=6"
654 | }
655 | },
656 | "node_modules/escape-string-regexp": {
657 | "version": "1.0.5",
658 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
659 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
660 | "dev": true,
661 | "peer": true,
662 | "engines": {
663 | "node": ">=0.8.0"
664 | }
665 | },
666 | "node_modules/fault": {
667 | "version": "1.0.4",
668 | "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
669 | "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
670 | "dev": true,
671 | "dependencies": {
672 | "format": "^0.2.0"
673 | },
674 | "funding": {
675 | "type": "github",
676 | "url": "https://github.com/sponsors/wooorm"
677 | }
678 | },
679 | "node_modules/format": {
680 | "version": "0.2.2",
681 | "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
682 | "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=",
683 | "dev": true,
684 | "engines": {
685 | "node": ">=0.4.x"
686 | }
687 | },
688 | "node_modules/gensync": {
689 | "version": "1.0.0-beta.2",
690 | "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
691 | "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
692 | "dev": true,
693 | "peer": true,
694 | "engines": {
695 | "node": ">=6.9.0"
696 | }
697 | },
698 | "node_modules/globals": {
699 | "version": "11.12.0",
700 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
701 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
702 | "dev": true,
703 | "peer": true,
704 | "engines": {
705 | "node": ">=4"
706 | }
707 | },
708 | "node_modules/good-listener": {
709 | "version": "1.2.2",
710 | "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
711 | "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
712 | "dev": true,
713 | "optional": true,
714 | "dependencies": {
715 | "delegate": "^3.1.2"
716 | }
717 | },
718 | "node_modules/has-flag": {
719 | "version": "3.0.0",
720 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
721 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
722 | "dev": true,
723 | "peer": true,
724 | "engines": {
725 | "node": ">=4"
726 | }
727 | },
728 | "node_modules/hast-util-parse-selector": {
729 | "version": "2.2.5",
730 | "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
731 | "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==",
732 | "dev": true,
733 | "funding": {
734 | "type": "opencollective",
735 | "url": "https://opencollective.com/unified"
736 | }
737 | },
738 | "node_modules/hastscript": {
739 | "version": "6.0.0",
740 | "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
741 | "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
742 | "dev": true,
743 | "dependencies": {
744 | "@types/hast": "^2.0.0",
745 | "comma-separated-tokens": "^1.0.0",
746 | "hast-util-parse-selector": "^2.0.0",
747 | "property-information": "^5.0.0",
748 | "space-separated-tokens": "^1.0.0"
749 | },
750 | "funding": {
751 | "type": "opencollective",
752 | "url": "https://opencollective.com/unified"
753 | }
754 | },
755 | "node_modules/highlight.js": {
756 | "version": "10.7.2",
757 | "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz",
758 | "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==",
759 | "dev": true,
760 | "engines": {
761 | "node": "*"
762 | }
763 | },
764 | "node_modules/is-alphabetical": {
765 | "version": "1.0.4",
766 | "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
767 | "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
768 | "dev": true,
769 | "funding": {
770 | "type": "github",
771 | "url": "https://github.com/sponsors/wooorm"
772 | }
773 | },
774 | "node_modules/is-alphanumerical": {
775 | "version": "1.0.4",
776 | "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
777 | "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
778 | "dev": true,
779 | "dependencies": {
780 | "is-alphabetical": "^1.0.0",
781 | "is-decimal": "^1.0.0"
782 | },
783 | "funding": {
784 | "type": "github",
785 | "url": "https://github.com/sponsors/wooorm"
786 | }
787 | },
788 | "node_modules/is-decimal": {
789 | "version": "1.0.4",
790 | "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
791 | "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
792 | "dev": true,
793 | "funding": {
794 | "type": "github",
795 | "url": "https://github.com/sponsors/wooorm"
796 | }
797 | },
798 | "node_modules/is-hexadecimal": {
799 | "version": "1.0.4",
800 | "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
801 | "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
802 | "dev": true,
803 | "funding": {
804 | "type": "github",
805 | "url": "https://github.com/sponsors/wooorm"
806 | }
807 | },
808 | "node_modules/js-tokens": {
809 | "version": "4.0.0",
810 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
811 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
812 | "dev": true,
813 | "peer": true
814 | },
815 | "node_modules/jsesc": {
816 | "version": "2.5.2",
817 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
818 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
819 | "dev": true,
820 | "peer": true,
821 | "bin": {
822 | "jsesc": "bin/jsesc"
823 | },
824 | "engines": {
825 | "node": ">=4"
826 | }
827 | },
828 | "node_modules/json5": {
829 | "version": "2.2.0",
830 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
831 | "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
832 | "dev": true,
833 | "peer": true,
834 | "dependencies": {
835 | "minimist": "^1.2.5"
836 | },
837 | "bin": {
838 | "json5": "lib/cli.js"
839 | },
840 | "engines": {
841 | "node": ">=6"
842 | }
843 | },
844 | "node_modules/lowlight": {
845 | "version": "1.20.0",
846 | "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
847 | "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
848 | "dev": true,
849 | "dependencies": {
850 | "fault": "^1.0.0",
851 | "highlight.js": "~10.7.0"
852 | },
853 | "funding": {
854 | "type": "github",
855 | "url": "https://github.com/sponsors/wooorm"
856 | }
857 | },
858 | "node_modules/minimist": {
859 | "version": "1.2.5",
860 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
861 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
862 | "dev": true,
863 | "peer": true
864 | },
865 | "node_modules/ms": {
866 | "version": "2.1.2",
867 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
868 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
869 | "dev": true,
870 | "peer": true
871 | },
872 | "node_modules/node-releases": {
873 | "version": "1.1.72",
874 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz",
875 | "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==",
876 | "dev": true,
877 | "peer": true
878 | },
879 | "node_modules/parse-entities": {
880 | "version": "2.0.0",
881 | "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
882 | "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
883 | "dev": true,
884 | "dependencies": {
885 | "character-entities": "^1.0.0",
886 | "character-entities-legacy": "^1.0.0",
887 | "character-reference-invalid": "^1.0.0",
888 | "is-alphanumerical": "^1.0.0",
889 | "is-decimal": "^1.0.0",
890 | "is-hexadecimal": "^1.0.0"
891 | },
892 | "funding": {
893 | "type": "github",
894 | "url": "https://github.com/sponsors/wooorm"
895 | }
896 | },
897 | "node_modules/prismjs": {
898 | "version": "1.23.0",
899 | "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz",
900 | "integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==",
901 | "dev": true,
902 | "optionalDependencies": {
903 | "clipboard": "^2.0.0"
904 | }
905 | },
906 | "node_modules/property-information": {
907 | "version": "5.6.0",
908 | "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
909 | "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
910 | "dev": true,
911 | "dependencies": {
912 | "xtend": "^4.0.0"
913 | },
914 | "funding": {
915 | "type": "github",
916 | "url": "https://github.com/sponsors/wooorm"
917 | }
918 | },
919 | "node_modules/react": {
920 | "resolved": "../node_modules/react",
921 | "link": true
922 | },
923 | "node_modules/react-dom": {
924 | "resolved": "../node_modules/react-dom",
925 | "link": true
926 | },
927 | "node_modules/react-scripts": {
928 | "resolved": "../node_modules/react-scripts",
929 | "link": true
930 | },
931 | "node_modules/react-syntax-highlighter": {
932 | "version": "15.4.3",
933 | "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.4.3.tgz",
934 | "integrity": "sha512-TnhGgZKXr5o8a63uYdRTzeb8ijJOgRGe0qjrE0eK/gajtdyqnSO6LqB3vW16hHB0cFierYSoy/AOJw8z1Dui8g==",
935 | "dev": true,
936 | "dependencies": {
937 | "@babel/runtime": "^7.3.1",
938 | "highlight.js": "^10.4.1",
939 | "lowlight": "^1.17.0",
940 | "prismjs": "^1.22.0",
941 | "refractor": "^3.2.0"
942 | },
943 | "peerDependencies": {
944 | "react": ">= 0.14.0"
945 | }
946 | },
947 | "node_modules/refractor": {
948 | "version": "3.3.1",
949 | "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.3.1.tgz",
950 | "integrity": "sha512-vaN6R56kLMuBszHSWlwTpcZ8KTMG6aUCok4GrxYDT20UIOXxOc5o6oDc8tNTzSlH3m2sI+Eu9Jo2kVdDcUTWYw==",
951 | "dev": true,
952 | "dependencies": {
953 | "hastscript": "^6.0.0",
954 | "parse-entities": "^2.0.0",
955 | "prismjs": "~1.23.0"
956 | },
957 | "funding": {
958 | "type": "github",
959 | "url": "https://github.com/sponsors/wooorm"
960 | }
961 | },
962 | "node_modules/regenerator-runtime": {
963 | "version": "0.13.7",
964 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
965 | "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
966 | "dev": true
967 | },
968 | "node_modules/safe-buffer": {
969 | "version": "5.1.2",
970 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
971 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
972 | "dev": true,
973 | "peer": true
974 | },
975 | "node_modules/select": {
976 | "version": "1.1.2",
977 | "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
978 | "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
979 | "dev": true,
980 | "optional": true
981 | },
982 | "node_modules/semver": {
983 | "version": "6.3.0",
984 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
985 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
986 | "dev": true,
987 | "peer": true,
988 | "bin": {
989 | "semver": "bin/semver.js"
990 | }
991 | },
992 | "node_modules/source-map": {
993 | "version": "0.5.7",
994 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
995 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
996 | "dev": true,
997 | "peer": true,
998 | "engines": {
999 | "node": ">=0.10.0"
1000 | }
1001 | },
1002 | "node_modules/space-separated-tokens": {
1003 | "version": "1.1.5",
1004 | "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
1005 | "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==",
1006 | "dev": true,
1007 | "funding": {
1008 | "type": "github",
1009 | "url": "https://github.com/sponsors/wooorm"
1010 | }
1011 | },
1012 | "node_modules/supports-color": {
1013 | "version": "5.5.0",
1014 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1015 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1016 | "dev": true,
1017 | "peer": true,
1018 | "dependencies": {
1019 | "has-flag": "^3.0.0"
1020 | },
1021 | "engines": {
1022 | "node": ">=4"
1023 | }
1024 | },
1025 | "node_modules/tiny-emitter": {
1026 | "version": "2.1.0",
1027 | "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
1028 | "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
1029 | "dev": true,
1030 | "optional": true
1031 | },
1032 | "node_modules/to-fast-properties": {
1033 | "version": "2.0.0",
1034 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
1035 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
1036 | "dev": true,
1037 | "peer": true,
1038 | "engines": {
1039 | "node": ">=4"
1040 | }
1041 | },
1042 | "node_modules/xtend": {
1043 | "version": "4.0.2",
1044 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
1045 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
1046 | "dev": true,
1047 | "engines": {
1048 | "node": ">=0.4"
1049 | }
1050 | }
1051 | },
1052 | "dependencies": {
1053 | "@babel/code-frame": {
1054 | "version": "7.12.13",
1055 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
1056 | "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
1057 | "dev": true,
1058 | "peer": true,
1059 | "requires": {
1060 | "@babel/highlight": "^7.12.13"
1061 | }
1062 | },
1063 | "@babel/compat-data": {
1064 | "version": "7.14.0",
1065 | "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz",
1066 | "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==",
1067 | "dev": true,
1068 | "peer": true
1069 | },
1070 | "@babel/core": {
1071 | "version": "7.14.3",
1072 | "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.3.tgz",
1073 | "integrity": "sha512-jB5AmTKOCSJIZ72sd78ECEhuPiDMKlQdDI/4QRI6lzYATx5SSogS1oQA2AoPecRCknm30gHi2l+QVvNUu3wZAg==",
1074 | "dev": true,
1075 | "peer": true,
1076 | "requires": {
1077 | "@babel/code-frame": "^7.12.13",
1078 | "@babel/generator": "^7.14.3",
1079 | "@babel/helper-compilation-targets": "^7.13.16",
1080 | "@babel/helper-module-transforms": "^7.14.2",
1081 | "@babel/helpers": "^7.14.0",
1082 | "@babel/parser": "^7.14.3",
1083 | "@babel/template": "^7.12.13",
1084 | "@babel/traverse": "^7.14.2",
1085 | "@babel/types": "^7.14.2",
1086 | "convert-source-map": "^1.7.0",
1087 | "debug": "^4.1.0",
1088 | "gensync": "^1.0.0-beta.2",
1089 | "json5": "^2.1.2",
1090 | "semver": "^6.3.0",
1091 | "source-map": "^0.5.0"
1092 | }
1093 | },
1094 | "@babel/generator": {
1095 | "version": "7.14.3",
1096 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz",
1097 | "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==",
1098 | "dev": true,
1099 | "peer": true,
1100 | "requires": {
1101 | "@babel/types": "^7.14.2",
1102 | "jsesc": "^2.5.1",
1103 | "source-map": "^0.5.0"
1104 | }
1105 | },
1106 | "@babel/helper-compilation-targets": {
1107 | "version": "7.13.16",
1108 | "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz",
1109 | "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==",
1110 | "dev": true,
1111 | "peer": true,
1112 | "requires": {
1113 | "@babel/compat-data": "^7.13.15",
1114 | "@babel/helper-validator-option": "^7.12.17",
1115 | "browserslist": "^4.14.5",
1116 | "semver": "^6.3.0"
1117 | }
1118 | },
1119 | "@babel/helper-function-name": {
1120 | "version": "7.14.2",
1121 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz",
1122 | "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==",
1123 | "dev": true,
1124 | "peer": true,
1125 | "requires": {
1126 | "@babel/helper-get-function-arity": "^7.12.13",
1127 | "@babel/template": "^7.12.13",
1128 | "@babel/types": "^7.14.2"
1129 | }
1130 | },
1131 | "@babel/helper-get-function-arity": {
1132 | "version": "7.12.13",
1133 | "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
1134 | "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
1135 | "dev": true,
1136 | "peer": true,
1137 | "requires": {
1138 | "@babel/types": "^7.12.13"
1139 | }
1140 | },
1141 | "@babel/helper-member-expression-to-functions": {
1142 | "version": "7.13.12",
1143 | "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz",
1144 | "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==",
1145 | "dev": true,
1146 | "peer": true,
1147 | "requires": {
1148 | "@babel/types": "^7.13.12"
1149 | }
1150 | },
1151 | "@babel/helper-module-imports": {
1152 | "version": "7.13.12",
1153 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz",
1154 | "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==",
1155 | "dev": true,
1156 | "peer": true,
1157 | "requires": {
1158 | "@babel/types": "^7.13.12"
1159 | }
1160 | },
1161 | "@babel/helper-module-transforms": {
1162 | "version": "7.14.2",
1163 | "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.2.tgz",
1164 | "integrity": "sha512-OznJUda/soKXv0XhpvzGWDnml4Qnwp16GN+D/kZIdLsWoHj05kyu8Rm5kXmMef+rVJZ0+4pSGLkeixdqNUATDA==",
1165 | "dev": true,
1166 | "peer": true,
1167 | "requires": {
1168 | "@babel/helper-module-imports": "^7.13.12",
1169 | "@babel/helper-replace-supers": "^7.13.12",
1170 | "@babel/helper-simple-access": "^7.13.12",
1171 | "@babel/helper-split-export-declaration": "^7.12.13",
1172 | "@babel/helper-validator-identifier": "^7.14.0",
1173 | "@babel/template": "^7.12.13",
1174 | "@babel/traverse": "^7.14.2",
1175 | "@babel/types": "^7.14.2"
1176 | }
1177 | },
1178 | "@babel/helper-optimise-call-expression": {
1179 | "version": "7.12.13",
1180 | "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz",
1181 | "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==",
1182 | "dev": true,
1183 | "peer": true,
1184 | "requires": {
1185 | "@babel/types": "^7.12.13"
1186 | }
1187 | },
1188 | "@babel/helper-plugin-utils": {
1189 | "version": "7.13.0",
1190 | "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz",
1191 | "integrity": "sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==",
1192 | "dev": true
1193 | },
1194 | "@babel/helper-replace-supers": {
1195 | "version": "7.14.3",
1196 | "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.3.tgz",
1197 | "integrity": "sha512-Rlh8qEWZSTfdz+tgNV/N4gz1a0TMNwCUcENhMjHTHKp3LseYH5Jha0NSlyTQWMnjbYcwFt+bqAMqSLHVXkQ6UA==",
1198 | "dev": true,
1199 | "peer": true,
1200 | "requires": {
1201 | "@babel/helper-member-expression-to-functions": "^7.13.12",
1202 | "@babel/helper-optimise-call-expression": "^7.12.13",
1203 | "@babel/traverse": "^7.14.2",
1204 | "@babel/types": "^7.14.2"
1205 | }
1206 | },
1207 | "@babel/helper-simple-access": {
1208 | "version": "7.13.12",
1209 | "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz",
1210 | "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==",
1211 | "dev": true,
1212 | "peer": true,
1213 | "requires": {
1214 | "@babel/types": "^7.13.12"
1215 | }
1216 | },
1217 | "@babel/helper-split-export-declaration": {
1218 | "version": "7.12.13",
1219 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
1220 | "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
1221 | "dev": true,
1222 | "peer": true,
1223 | "requires": {
1224 | "@babel/types": "^7.12.13"
1225 | }
1226 | },
1227 | "@babel/helper-validator-identifier": {
1228 | "version": "7.14.0",
1229 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
1230 | "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
1231 | "dev": true,
1232 | "peer": true
1233 | },
1234 | "@babel/helper-validator-option": {
1235 | "version": "7.12.17",
1236 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz",
1237 | "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==",
1238 | "dev": true,
1239 | "peer": true
1240 | },
1241 | "@babel/helpers": {
1242 | "version": "7.14.0",
1243 | "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz",
1244 | "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==",
1245 | "dev": true,
1246 | "peer": true,
1247 | "requires": {
1248 | "@babel/template": "^7.12.13",
1249 | "@babel/traverse": "^7.14.0",
1250 | "@babel/types": "^7.14.0"
1251 | }
1252 | },
1253 | "@babel/highlight": {
1254 | "version": "7.14.0",
1255 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz",
1256 | "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==",
1257 | "dev": true,
1258 | "peer": true,
1259 | "requires": {
1260 | "@babel/helper-validator-identifier": "^7.14.0",
1261 | "chalk": "^2.0.0",
1262 | "js-tokens": "^4.0.0"
1263 | }
1264 | },
1265 | "@babel/parser": {
1266 | "version": "7.14.3",
1267 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz",
1268 | "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==",
1269 | "dev": true,
1270 | "peer": true
1271 | },
1272 | "@babel/plugin-syntax-object-rest-spread": {
1273 | "version": "7.8.3",
1274 | "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
1275 | "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
1276 | "dev": true,
1277 | "requires": {
1278 | "@babel/helper-plugin-utils": "^7.8.0"
1279 | }
1280 | },
1281 | "@babel/runtime": {
1282 | "version": "7.14.0",
1283 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz",
1284 | "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==",
1285 | "dev": true,
1286 | "requires": {
1287 | "regenerator-runtime": "^0.13.4"
1288 | }
1289 | },
1290 | "@babel/template": {
1291 | "version": "7.12.13",
1292 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
1293 | "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
1294 | "dev": true,
1295 | "peer": true,
1296 | "requires": {
1297 | "@babel/code-frame": "^7.12.13",
1298 | "@babel/parser": "^7.12.13",
1299 | "@babel/types": "^7.12.13"
1300 | }
1301 | },
1302 | "@babel/traverse": {
1303 | "version": "7.14.2",
1304 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz",
1305 | "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==",
1306 | "dev": true,
1307 | "peer": true,
1308 | "requires": {
1309 | "@babel/code-frame": "^7.12.13",
1310 | "@babel/generator": "^7.14.2",
1311 | "@babel/helper-function-name": "^7.14.2",
1312 | "@babel/helper-split-export-declaration": "^7.12.13",
1313 | "@babel/parser": "^7.14.2",
1314 | "@babel/types": "^7.14.2",
1315 | "debug": "^4.1.0",
1316 | "globals": "^11.1.0"
1317 | }
1318 | },
1319 | "@babel/types": {
1320 | "version": "7.14.2",
1321 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz",
1322 | "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==",
1323 | "dev": true,
1324 | "peer": true,
1325 | "requires": {
1326 | "@babel/helper-validator-identifier": "^7.14.0",
1327 | "to-fast-properties": "^2.0.0"
1328 | }
1329 | },
1330 | "@madzadev/audio-player": {
1331 | "version": "file:..",
1332 | "requires": {
1333 | "cross-env": "^7.0.2",
1334 | "microbundle-crl": "^0.13.10",
1335 | "npm-run-all": "^4.1.5",
1336 | "react": "^16.13.1",
1337 | "react-dom": "^16.13.1",
1338 | "react-scripts": "^4.0.3",
1339 | "styled-components": "^5.2.1"
1340 | },
1341 | "dependencies": {
1342 | "react": {
1343 | "version": "16.14.0",
1344 | "requires": {
1345 | "loose-envify": "^1.1.0",
1346 | "object-assign": "^4.1.1",
1347 | "prop-types": "^15.6.2"
1348 | }
1349 | },
1350 | "react-dom": {
1351 | "version": "16.14.0",
1352 | "requires": {
1353 | "loose-envify": "^1.1.0",
1354 | "object-assign": "^4.1.1",
1355 | "prop-types": "^15.6.2",
1356 | "scheduler": "^0.19.1"
1357 | }
1358 | },
1359 | "react-scripts": {
1360 | "version": "4.0.3",
1361 | "requires": {
1362 | "@babel/core": "7.12.3",
1363 | "@pmmmwh/react-refresh-webpack-plugin": "0.4.3",
1364 | "@svgr/webpack": "5.5.0",
1365 | "@typescript-eslint/eslint-plugin": "^4.5.0",
1366 | "@typescript-eslint/parser": "^4.5.0",
1367 | "babel-eslint": "^10.1.0",
1368 | "babel-jest": "^26.6.0",
1369 | "babel-loader": "8.1.0",
1370 | "babel-plugin-named-asset-import": "^0.3.7",
1371 | "babel-preset-react-app": "^10.0.0",
1372 | "bfj": "^7.0.2",
1373 | "camelcase": "^6.1.0",
1374 | "case-sensitive-paths-webpack-plugin": "2.3.0",
1375 | "css-loader": "4.3.0",
1376 | "dotenv": "8.2.0",
1377 | "dotenv-expand": "5.1.0",
1378 | "eslint": "^7.11.0",
1379 | "eslint-config-react-app": "^6.0.0",
1380 | "eslint-plugin-flowtype": "^5.2.0",
1381 | "eslint-plugin-import": "^2.22.1",
1382 | "eslint-plugin-jest": "^24.1.0",
1383 | "eslint-plugin-jsx-a11y": "^6.3.1",
1384 | "eslint-plugin-react": "^7.21.5",
1385 | "eslint-plugin-react-hooks": "^4.2.0",
1386 | "eslint-plugin-testing-library": "^3.9.2",
1387 | "eslint-webpack-plugin": "^2.5.2",
1388 | "file-loader": "6.1.1",
1389 | "fs-extra": "^9.0.1",
1390 | "fsevents": "^2.1.3",
1391 | "html-webpack-plugin": "4.5.0",
1392 | "identity-obj-proxy": "3.0.0",
1393 | "jest": "26.6.0",
1394 | "jest-circus": "26.6.0",
1395 | "jest-resolve": "26.6.0",
1396 | "jest-watch-typeahead": "0.6.1",
1397 | "mini-css-extract-plugin": "0.11.3",
1398 | "optimize-css-assets-webpack-plugin": "5.0.4",
1399 | "pnp-webpack-plugin": "1.6.4",
1400 | "postcss-flexbugs-fixes": "4.2.1",
1401 | "postcss-loader": "3.0.0",
1402 | "postcss-normalize": "8.0.1",
1403 | "postcss-preset-env": "6.7.0",
1404 | "postcss-safe-parser": "5.0.2",
1405 | "prompts": "2.4.0",
1406 | "react-app-polyfill": "^2.0.0",
1407 | "react-dev-utils": "^11.0.3",
1408 | "react-refresh": "^0.8.3",
1409 | "resolve": "1.18.1",
1410 | "resolve-url-loader": "^3.1.2",
1411 | "sass-loader": "^10.0.5",
1412 | "semver": "7.3.2",
1413 | "style-loader": "1.3.0",
1414 | "terser-webpack-plugin": "4.2.3",
1415 | "ts-pnp": "1.2.0",
1416 | "url-loader": "4.1.1",
1417 | "webpack": "4.44.2",
1418 | "webpack-dev-server": "3.11.1",
1419 | "webpack-manifest-plugin": "2.2.0",
1420 | "workbox-webpack-plugin": "5.1.4"
1421 | }
1422 | }
1423 | }
1424 | },
1425 | "@types/hast": {
1426 | "version": "2.3.1",
1427 | "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.1.tgz",
1428 | "integrity": "sha512-viwwrB+6xGzw+G1eWpF9geV3fnsDgXqHG+cqgiHrvQfDUW5hzhCyV7Sy3UJxhfRFBsgky2SSW33qi/YrIkjX5Q==",
1429 | "dev": true,
1430 | "requires": {
1431 | "@types/unist": "*"
1432 | }
1433 | },
1434 | "@types/unist": {
1435 | "version": "2.0.3",
1436 | "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
1437 | "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==",
1438 | "dev": true
1439 | },
1440 | "ansi-styles": {
1441 | "version": "3.2.1",
1442 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
1443 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
1444 | "dev": true,
1445 | "peer": true,
1446 | "requires": {
1447 | "color-convert": "^1.9.0"
1448 | }
1449 | },
1450 | "browserslist": {
1451 | "version": "4.16.6",
1452 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
1453 | "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
1454 | "dev": true,
1455 | "peer": true,
1456 | "requires": {
1457 | "caniuse-lite": "^1.0.30001219",
1458 | "colorette": "^1.2.2",
1459 | "electron-to-chromium": "^1.3.723",
1460 | "escalade": "^3.1.1",
1461 | "node-releases": "^1.1.71"
1462 | }
1463 | },
1464 | "caniuse-lite": {
1465 | "version": "1.0.30001228",
1466 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz",
1467 | "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==",
1468 | "dev": true,
1469 | "peer": true
1470 | },
1471 | "chalk": {
1472 | "version": "2.4.2",
1473 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
1474 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
1475 | "dev": true,
1476 | "peer": true,
1477 | "requires": {
1478 | "ansi-styles": "^3.2.1",
1479 | "escape-string-regexp": "^1.0.5",
1480 | "supports-color": "^5.3.0"
1481 | }
1482 | },
1483 | "character-entities": {
1484 | "version": "1.2.4",
1485 | "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz",
1486 | "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==",
1487 | "dev": true
1488 | },
1489 | "character-entities-legacy": {
1490 | "version": "1.1.4",
1491 | "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz",
1492 | "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==",
1493 | "dev": true
1494 | },
1495 | "character-reference-invalid": {
1496 | "version": "1.1.4",
1497 | "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz",
1498 | "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
1499 | "dev": true
1500 | },
1501 | "clipboard": {
1502 | "version": "2.0.8",
1503 | "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.8.tgz",
1504 | "integrity": "sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==",
1505 | "dev": true,
1506 | "optional": true,
1507 | "requires": {
1508 | "good-listener": "^1.2.2",
1509 | "select": "^1.1.2",
1510 | "tiny-emitter": "^2.0.0"
1511 | }
1512 | },
1513 | "color-convert": {
1514 | "version": "1.9.3",
1515 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
1516 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
1517 | "dev": true,
1518 | "peer": true,
1519 | "requires": {
1520 | "color-name": "1.1.3"
1521 | }
1522 | },
1523 | "color-name": {
1524 | "version": "1.1.3",
1525 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
1526 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
1527 | "dev": true,
1528 | "peer": true
1529 | },
1530 | "colorette": {
1531 | "version": "1.2.2",
1532 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
1533 | "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
1534 | "dev": true,
1535 | "peer": true
1536 | },
1537 | "comma-separated-tokens": {
1538 | "version": "1.0.8",
1539 | "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz",
1540 | "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==",
1541 | "dev": true
1542 | },
1543 | "convert-source-map": {
1544 | "version": "1.7.0",
1545 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
1546 | "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
1547 | "dev": true,
1548 | "peer": true,
1549 | "requires": {
1550 | "safe-buffer": "~5.1.1"
1551 | }
1552 | },
1553 | "debug": {
1554 | "version": "4.3.1",
1555 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
1556 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
1557 | "dev": true,
1558 | "peer": true,
1559 | "requires": {
1560 | "ms": "2.1.2"
1561 | }
1562 | },
1563 | "delegate": {
1564 | "version": "3.2.0",
1565 | "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
1566 | "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
1567 | "dev": true,
1568 | "optional": true
1569 | },
1570 | "electron-to-chromium": {
1571 | "version": "1.3.735",
1572 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.735.tgz",
1573 | "integrity": "sha512-cp7MWzC3NseUJV2FJFgaiesdrS+A8ZUjX5fLAxdRlcaPDkaPGFplX930S5vf84yqDp4LjuLdKouWuVOTwUfqHQ==",
1574 | "dev": true,
1575 | "peer": true
1576 | },
1577 | "escalade": {
1578 | "version": "3.1.1",
1579 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
1580 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
1581 | "dev": true,
1582 | "peer": true
1583 | },
1584 | "escape-string-regexp": {
1585 | "version": "1.0.5",
1586 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
1587 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
1588 | "dev": true,
1589 | "peer": true
1590 | },
1591 | "fault": {
1592 | "version": "1.0.4",
1593 | "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz",
1594 | "integrity": "sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA==",
1595 | "dev": true,
1596 | "requires": {
1597 | "format": "^0.2.0"
1598 | }
1599 | },
1600 | "format": {
1601 | "version": "0.2.2",
1602 | "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz",
1603 | "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=",
1604 | "dev": true
1605 | },
1606 | "gensync": {
1607 | "version": "1.0.0-beta.2",
1608 | "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
1609 | "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
1610 | "dev": true,
1611 | "peer": true
1612 | },
1613 | "globals": {
1614 | "version": "11.12.0",
1615 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
1616 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
1617 | "dev": true,
1618 | "peer": true
1619 | },
1620 | "good-listener": {
1621 | "version": "1.2.2",
1622 | "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
1623 | "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
1624 | "dev": true,
1625 | "optional": true,
1626 | "requires": {
1627 | "delegate": "^3.1.2"
1628 | }
1629 | },
1630 | "has-flag": {
1631 | "version": "3.0.0",
1632 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
1633 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
1634 | "dev": true,
1635 | "peer": true
1636 | },
1637 | "hast-util-parse-selector": {
1638 | "version": "2.2.5",
1639 | "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz",
1640 | "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==",
1641 | "dev": true
1642 | },
1643 | "hastscript": {
1644 | "version": "6.0.0",
1645 | "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz",
1646 | "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==",
1647 | "dev": true,
1648 | "requires": {
1649 | "@types/hast": "^2.0.0",
1650 | "comma-separated-tokens": "^1.0.0",
1651 | "hast-util-parse-selector": "^2.0.0",
1652 | "property-information": "^5.0.0",
1653 | "space-separated-tokens": "^1.0.0"
1654 | }
1655 | },
1656 | "highlight.js": {
1657 | "version": "10.7.2",
1658 | "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz",
1659 | "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==",
1660 | "dev": true
1661 | },
1662 | "is-alphabetical": {
1663 | "version": "1.0.4",
1664 | "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz",
1665 | "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==",
1666 | "dev": true
1667 | },
1668 | "is-alphanumerical": {
1669 | "version": "1.0.4",
1670 | "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz",
1671 | "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==",
1672 | "dev": true,
1673 | "requires": {
1674 | "is-alphabetical": "^1.0.0",
1675 | "is-decimal": "^1.0.0"
1676 | }
1677 | },
1678 | "is-decimal": {
1679 | "version": "1.0.4",
1680 | "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz",
1681 | "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==",
1682 | "dev": true
1683 | },
1684 | "is-hexadecimal": {
1685 | "version": "1.0.4",
1686 | "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz",
1687 | "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==",
1688 | "dev": true
1689 | },
1690 | "js-tokens": {
1691 | "version": "4.0.0",
1692 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1693 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1694 | "dev": true,
1695 | "peer": true
1696 | },
1697 | "jsesc": {
1698 | "version": "2.5.2",
1699 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
1700 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
1701 | "dev": true,
1702 | "peer": true
1703 | },
1704 | "json5": {
1705 | "version": "2.2.0",
1706 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
1707 | "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
1708 | "dev": true,
1709 | "peer": true,
1710 | "requires": {
1711 | "minimist": "^1.2.5"
1712 | }
1713 | },
1714 | "lowlight": {
1715 | "version": "1.20.0",
1716 | "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz",
1717 | "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==",
1718 | "dev": true,
1719 | "requires": {
1720 | "fault": "^1.0.0",
1721 | "highlight.js": "~10.7.0"
1722 | }
1723 | },
1724 | "minimist": {
1725 | "version": "1.2.5",
1726 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
1727 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
1728 | "dev": true,
1729 | "peer": true
1730 | },
1731 | "ms": {
1732 | "version": "2.1.2",
1733 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1734 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
1735 | "dev": true,
1736 | "peer": true
1737 | },
1738 | "node-releases": {
1739 | "version": "1.1.72",
1740 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz",
1741 | "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==",
1742 | "dev": true,
1743 | "peer": true
1744 | },
1745 | "parse-entities": {
1746 | "version": "2.0.0",
1747 | "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz",
1748 | "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==",
1749 | "dev": true,
1750 | "requires": {
1751 | "character-entities": "^1.0.0",
1752 | "character-entities-legacy": "^1.0.0",
1753 | "character-reference-invalid": "^1.0.0",
1754 | "is-alphanumerical": "^1.0.0",
1755 | "is-decimal": "^1.0.0",
1756 | "is-hexadecimal": "^1.0.0"
1757 | }
1758 | },
1759 | "prismjs": {
1760 | "version": "1.23.0",
1761 | "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.23.0.tgz",
1762 | "integrity": "sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA==",
1763 | "dev": true,
1764 | "requires": {
1765 | "clipboard": "^2.0.0"
1766 | }
1767 | },
1768 | "property-information": {
1769 | "version": "5.6.0",
1770 | "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz",
1771 | "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==",
1772 | "dev": true,
1773 | "requires": {
1774 | "xtend": "^4.0.0"
1775 | }
1776 | },
1777 | "react": {
1778 | "version": "file:../node_modules/react",
1779 | "requires": {
1780 | "loose-envify": "^1.1.0",
1781 | "object-assign": "^4.1.1",
1782 | "prop-types": "^15.6.2"
1783 | }
1784 | },
1785 | "react-dom": {
1786 | "version": "file:../node_modules/react-dom",
1787 | "requires": {
1788 | "loose-envify": "^1.1.0",
1789 | "object-assign": "^4.1.1",
1790 | "prop-types": "^15.6.2",
1791 | "scheduler": "^0.19.1"
1792 | }
1793 | },
1794 | "react-scripts": {
1795 | "version": "file:../node_modules/react-scripts",
1796 | "requires": {
1797 | "@babel/core": "7.12.3",
1798 | "@pmmmwh/react-refresh-webpack-plugin": "0.4.3",
1799 | "@svgr/webpack": "5.5.0",
1800 | "@typescript-eslint/eslint-plugin": "^4.5.0",
1801 | "@typescript-eslint/parser": "^4.5.0",
1802 | "babel-eslint": "^10.1.0",
1803 | "babel-jest": "^26.6.0",
1804 | "babel-loader": "8.1.0",
1805 | "babel-plugin-named-asset-import": "^0.3.7",
1806 | "babel-preset-react-app": "^10.0.0",
1807 | "bfj": "^7.0.2",
1808 | "camelcase": "^6.1.0",
1809 | "case-sensitive-paths-webpack-plugin": "2.3.0",
1810 | "css-loader": "4.3.0",
1811 | "dotenv": "8.2.0",
1812 | "dotenv-expand": "5.1.0",
1813 | "eslint": "^7.11.0",
1814 | "eslint-config-react-app": "^6.0.0",
1815 | "eslint-plugin-flowtype": "^5.2.0",
1816 | "eslint-plugin-import": "^2.22.1",
1817 | "eslint-plugin-jest": "^24.1.0",
1818 | "eslint-plugin-jsx-a11y": "^6.3.1",
1819 | "eslint-plugin-react": "^7.21.5",
1820 | "eslint-plugin-react-hooks": "^4.2.0",
1821 | "eslint-plugin-testing-library": "^3.9.2",
1822 | "eslint-webpack-plugin": "^2.5.2",
1823 | "file-loader": "6.1.1",
1824 | "fs-extra": "^9.0.1",
1825 | "fsevents": "^2.1.3",
1826 | "html-webpack-plugin": "4.5.0",
1827 | "identity-obj-proxy": "3.0.0",
1828 | "jest": "26.6.0",
1829 | "jest-circus": "26.6.0",
1830 | "jest-resolve": "26.6.0",
1831 | "jest-watch-typeahead": "0.6.1",
1832 | "mini-css-extract-plugin": "0.11.3",
1833 | "optimize-css-assets-webpack-plugin": "5.0.4",
1834 | "pnp-webpack-plugin": "1.6.4",
1835 | "postcss-flexbugs-fixes": "4.2.1",
1836 | "postcss-loader": "3.0.0",
1837 | "postcss-normalize": "8.0.1",
1838 | "postcss-preset-env": "6.7.0",
1839 | "postcss-safe-parser": "5.0.2",
1840 | "prompts": "2.4.0",
1841 | "react-app-polyfill": "^2.0.0",
1842 | "react-dev-utils": "^11.0.3",
1843 | "react-refresh": "^0.8.3",
1844 | "resolve": "1.18.1",
1845 | "resolve-url-loader": "^3.1.2",
1846 | "sass-loader": "^10.0.5",
1847 | "semver": "7.3.2",
1848 | "style-loader": "1.3.0",
1849 | "terser-webpack-plugin": "4.2.3",
1850 | "ts-pnp": "1.2.0",
1851 | "url-loader": "4.1.1",
1852 | "webpack": "4.44.2",
1853 | "webpack-dev-server": "3.11.1",
1854 | "webpack-manifest-plugin": "2.2.0",
1855 | "workbox-webpack-plugin": "5.1.4"
1856 | }
1857 | },
1858 | "react-syntax-highlighter": {
1859 | "version": "15.4.3",
1860 | "resolved": "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.4.3.tgz",
1861 | "integrity": "sha512-TnhGgZKXr5o8a63uYdRTzeb8ijJOgRGe0qjrE0eK/gajtdyqnSO6LqB3vW16hHB0cFierYSoy/AOJw8z1Dui8g==",
1862 | "dev": true,
1863 | "requires": {
1864 | "@babel/runtime": "^7.3.1",
1865 | "highlight.js": "^10.4.1",
1866 | "lowlight": "^1.17.0",
1867 | "prismjs": "^1.22.0",
1868 | "refractor": "^3.2.0"
1869 | }
1870 | },
1871 | "refractor": {
1872 | "version": "3.3.1",
1873 | "resolved": "https://registry.npmjs.org/refractor/-/refractor-3.3.1.tgz",
1874 | "integrity": "sha512-vaN6R56kLMuBszHSWlwTpcZ8KTMG6aUCok4GrxYDT20UIOXxOc5o6oDc8tNTzSlH3m2sI+Eu9Jo2kVdDcUTWYw==",
1875 | "dev": true,
1876 | "requires": {
1877 | "hastscript": "^6.0.0",
1878 | "parse-entities": "^2.0.0",
1879 | "prismjs": "~1.23.0"
1880 | }
1881 | },
1882 | "regenerator-runtime": {
1883 | "version": "0.13.7",
1884 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
1885 | "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==",
1886 | "dev": true
1887 | },
1888 | "safe-buffer": {
1889 | "version": "5.1.2",
1890 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
1891 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
1892 | "dev": true,
1893 | "peer": true
1894 | },
1895 | "select": {
1896 | "version": "1.1.2",
1897 | "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
1898 | "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
1899 | "dev": true,
1900 | "optional": true
1901 | },
1902 | "semver": {
1903 | "version": "6.3.0",
1904 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
1905 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
1906 | "dev": true,
1907 | "peer": true
1908 | },
1909 | "source-map": {
1910 | "version": "0.5.7",
1911 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
1912 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
1913 | "dev": true,
1914 | "peer": true
1915 | },
1916 | "space-separated-tokens": {
1917 | "version": "1.1.5",
1918 | "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz",
1919 | "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==",
1920 | "dev": true
1921 | },
1922 | "supports-color": {
1923 | "version": "5.5.0",
1924 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1925 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1926 | "dev": true,
1927 | "peer": true,
1928 | "requires": {
1929 | "has-flag": "^3.0.0"
1930 | }
1931 | },
1932 | "tiny-emitter": {
1933 | "version": "2.1.0",
1934 | "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
1935 | "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==",
1936 | "dev": true,
1937 | "optional": true
1938 | },
1939 | "to-fast-properties": {
1940 | "version": "2.0.0",
1941 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
1942 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
1943 | "dev": true,
1944 | "peer": true
1945 | },
1946 | "xtend": {
1947 | "version": "4.0.2",
1948 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
1949 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
1950 | "dev": true
1951 | }
1952 | }
1953 | }
1954 |
--------------------------------------------------------------------------------
/example/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@madzadev/audio-player-example",
3 | "homepage": ".",
4 | "version": "0.1.0",
5 | "private": true,
6 | "scripts": {
7 | "start": "node ../node_modules/react-scripts/bin/react-scripts.js start",
8 | "build": "node ../node_modules/react-scripts/bin/react-scripts.js build",
9 | "test": "node ../node_modules/react-scripts/bin/react-scripts.js test",
10 | "eject": "node ../node_modules/react-scripts/bin/react-scripts.js eject"
11 | },
12 | "dependencies": {
13 | "@madzadev/audio-player": "file:..",
14 | "react": "file:../node_modules/react",
15 | "react-dom": "file:../node_modules/react-dom",
16 | "react-scripts": "file:../node_modules/react-scripts"
17 | },
18 | "devDependencies": {
19 | "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
20 | "react-syntax-highlighter": "^15.4.3"
21 | },
22 | "eslintConfig": {
23 | "extends": "react-app"
24 | },
25 | "browserslist": [
26 | ">0.2%",
27 | "not dead",
28 | "not ie <= 11",
29 | "not op_mini all"
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/example/public/Madza-Chords_of_Life.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/audio-player/9d230022627b7304bb6bb2b92558eb0d123315a4/example/public/Madza-Chords_of_Life.mp3
--------------------------------------------------------------------------------
/example/public/Madza-Late_Night_Drive.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/audio-player/9d230022627b7304bb6bb2b92558eb0d123315a4/example/public/Madza-Late_Night_Drive.mp3
--------------------------------------------------------------------------------
/example/public/Madza-Persistence.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/audio-player/9d230022627b7304bb6bb2b92558eb0d123315a4/example/public/Madza-Persistence.mp3
--------------------------------------------------------------------------------
/example/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/audio-player/9d230022627b7304bb6bb2b92558eb0d123315a4/example/public/favicon.ico
--------------------------------------------------------------------------------
/example/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
16 |
17 |
18 |
27 | Audio Player by Madza
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/example/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "audio-player",
3 | "name": "@madzadev/audio-player-3",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/example/src/App.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Wrapper from "./components/Wrapper";
3 | import Header from "./components/Header";
4 | import Footer from "./components/Footer";
5 |
6 | import Player from "@madzadev/audio-player";
7 | import "@madzadev/audio-player/dist/index.css";
8 |
9 | import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
10 | import { coldarkDark } from "react-syntax-highlighter/dist/esm/styles/prism";
11 |
12 | const tracks = [
13 | {
14 | url: "https://audioplayer.madza.dev/Madza-Chords_of_Life.mp3",
15 | title: "Madza - Chords of Life",
16 | tags: ["house"],
17 | },
18 | {
19 | url: "https://audioplayer.madza.dev/Madza-Late_Night_Drive.mp3",
20 | title: "Madza - Late Night Drive",
21 | tags: ["dnb"],
22 | },
23 | {
24 | url: "https://audioplayer.madza.dev/Madza-Persistence.mp3",
25 | title: "Madza - Persistence",
26 | tags: ["dubstep"],
27 | },
28 | ];
29 |
30 | const App = () => {
31 | return (
32 |
33 |
34 |
35 | Installation
36 |
37 | {`npm install @madzadev/audio-player`}
38 |
39 |
40 | If you are using NPM v7 or above, you need to add{" "}
41 | --legacy-peer-deps
at the end of the command above.
42 |
43 | Usage
44 |
45 | {`import Player from '@madzadev/audio-player'
46 | import '@madzadev/audio-player/dist/index.css'`}
47 |
48 |
49 | {`const tracks = [
50 | {
51 | url: 'https://audioplayer.madza.dev/Madza-Chords_of_Life.mp3',
52 | title: 'Madza - Chords of Life',
53 | tags: ['house']
54 | },
55 | {
56 | url: 'https://audioplayer.madza.dev/Madza-Late_Night_Drive.mp3',
57 | title: 'Madza - Late Night Drive',
58 | tags: ['dnb']
59 | },
60 | {
61 | url: 'https://audioplayer.madza.dev/Madza-Persistence.mp3',
62 | title: 'Madza - Persistence',
63 | tags: ['dubstep']
64 | }
65 | ]`}
66 |
67 |
68 | {``}
69 |
70 |
71 | 'trackList'
is the mandatory prop and requires to pass in
72 | an array consisting of objects with url
, title
{" "}
73 | and tags
keys.
74 |
75 | Config for NextJS
76 |
77 | If you are working in NextJS, there are 3 additional steps:
78 |
79 |
80 | 1. npm i next-images next-transpile-modules
81 |
82 |
83 | 2. Create next.config.js
in your project's root
84 |
85 | 3. Paste this in the newly created config file:
86 |
87 | {`const withImages = require("next-images");
88 | const withTM = require("next-transpile-modules")(["@madzadev/audio-player"]);
89 |
90 | module.exports = withImages(withTM());`}
91 |
92 | Options
93 |
94 | The default values of available options props are displayed.
95 |
96 |
97 | {``}
104 |
105 | Color schemas
106 |
107 | You can further customize the player UI by editing the colors variable
108 | below.
109 |
110 |
111 | Pre-defined color schemes are planned in the future.
112 |
113 |
114 | {`const colors = \`html {
115 | --tagsBackground: #9440f3;
116 | --tagsText: #ffffff;
117 | --tagsBackgroundHoverActive: #2cc0a0;
118 | --tagsTextHoverActive: #ffffff;
119 | --searchBackground: #18191f;
120 | --searchText: #ffffff;
121 | --searchPlaceHolder: #575a77;
122 | --playerBackground: #18191f;
123 | --titleColor: #ffffff;
124 | --timeColor: #ffffff;
125 | --progressSlider: #9440f3;
126 | --progressUsed: #ffffff;
127 | --progressLeft: #151616;
128 | --volumeSlider: #9440f3;
129 | --volumeUsed: #ffffff;
130 | --volumeLeft: #151616;
131 | --playlistBackground: #18191f;
132 | --playlistText: #575a77;
133 | --playlistBackgroundHoverActive: #18191f;
134 | --playlistTextHoverActive: #ffffff;
135 | }\``}
136 |
137 |
138 | {``}
142 |
143 | Final notes
144 |
145 | It's recommended to use CMS like a{" "}
146 | Contentful or{" "}
147 | DatoCMS to manage your audio files
148 | and access them via API.
149 |
150 |
151 |
152 | );
153 | };
154 |
155 | export default App;
156 |
--------------------------------------------------------------------------------
/example/src/components/Footer.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styles from "./Footer.module.css";
3 |
4 | const Footer = () => {
5 | return (
6 |
31 | );
32 | };
33 |
34 | export default Footer;
35 |
--------------------------------------------------------------------------------
/example/src/components/Footer.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | margin-top: 30px;
3 | text-align: center;
4 | color: #303030;
5 | padding: 10px 20px;
6 | font-size: 18px;
7 | font-weight: bold;
8 | font-family: 'Nothing You Could Do', cursive;
9 | }
10 |
11 | .wrapper p {
12 | margin: 10px;
13 | }
14 |
--------------------------------------------------------------------------------
/example/src/components/Header.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import styles from './Header.module.css'
3 |
4 | const Header = () => {
5 | return (
6 |
7 |
Audio Player for your Music
8 |
9 | Based on hooks, requires React v.16.8+
10 |
11 |
12 | )
13 | }
14 |
15 | export default Header
16 |
--------------------------------------------------------------------------------
/example/src/components/Header.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | text-align: center;
3 | margin-bottom: 20px;
4 | }
5 |
6 | .title {
7 | margin: 0;
8 | font-size: 40px;
9 | }
10 |
11 | .description {
12 | margin: 0;
13 | font-size: 18px;
14 | }
15 |
--------------------------------------------------------------------------------
/example/src/components/Wrapper.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import styles from './Wrapper.module.css'
3 |
4 | const Wrapper = ({children}) => {
5 | return (
6 |
7 | {children}
8 |
9 | )
10 | }
11 |
12 | export default Wrapper
13 |
--------------------------------------------------------------------------------
/example/src/components/Wrapper.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | max-width: 1000px;
3 | margin: 0 auto;
4 | padding: 20px;
5 | }
6 |
--------------------------------------------------------------------------------
/example/src/index.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Montserrat&display=swap');
2 | @import url('https://fonts.googleapis.com/css2?family=Nothing+You+Could+Do&display=swap');
3 |
4 | body {
5 | margin: 0;
6 | padding: 0;
7 | font-family: 'Montserrat', sans-serif;
8 | background-color: #b8c6db;
9 | background-image: linear-gradient(315deg, #b8c6db 0%, #f5f7fa 74%);
10 | }
11 |
12 | h1,
13 | h2,
14 | h3,
15 | h4 {
16 | font-family: 'Montserrat', sans-serif;
17 | }
18 |
19 | .warning {
20 | padding-left: 10px;
21 | border-left: 5px solid tomato;
22 | }
23 |
24 | .note {
25 | padding-left: 10px;
26 | border-left: 5px solid rgb(255, 175, 55);
27 | }
28 |
29 | .link {
30 | color: rgb(103, 92, 253);
31 | }
32 |
33 | pre {
34 | font-family: 'Montserrat', sans-serif;
35 | font-size: 16px;
36 | }
37 |
38 | code {
39 | background-color: rgb(212, 212, 212);
40 | padding: 5px;
41 | }
42 |
--------------------------------------------------------------------------------
/example/src/index.js:
--------------------------------------------------------------------------------
1 | import './index.css'
2 |
3 | import React from 'react'
4 | import ReactDOM from 'react-dom'
5 | import App from './App'
6 |
7 | ReactDOM.render(, document.getElementById('root'))
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@madzadev/audio-player",
3 | "version": "1.1.11",
4 | "description": "React/NextJS audio player for your music, with custom controls, playlist, filters, and search functionality.",
5 | "keywords": [
6 | "react",
7 | "nextjs",
8 | "audio",
9 | "player",
10 | "mp3",
11 | "music"
12 | ],
13 | "author": "Madza (http://madza.dev)",
14 | "license": "MIT",
15 | "repository": {
16 | "type": "git",
17 | "url": "https://github.com/madzadev/audio-player.git"
18 | },
19 | "homepage": "https://audioplayer.madza.dev/",
20 | "bugs": {
21 | "url": "https://github.com/madzadev/audio-player/issues"
22 | },
23 | "main": "dist/index.js",
24 | "module": "dist/index.modern.js",
25 | "source": "src/index.js",
26 | "engines": {
27 | "node": ">=10"
28 | },
29 | "scripts": {
30 | "build": "microbundle-crl --no-compress --format modern,cjs",
31 | "start": "microbundle-crl watch --no-compress --format modern,cjs",
32 | "prepare": "run-s build",
33 | "predeploy": "cd example && npm install && npm run build"
34 | },
35 | "peerDependencies": {
36 | "react": "^16.8.0"
37 | },
38 | "devDependencies": {
39 | "cross-env": "^7.0.2",
40 | "microbundle-crl": "^0.13.10",
41 | "npm-run-all": "^4.1.5",
42 | "react": "^16.13.1",
43 | "react-dom": "^16.13.1",
44 | "react-scripts": "^4.0.3"
45 | },
46 | "files": [
47 | "dist"
48 | ],
49 | "dependencies": {
50 | "styled-components": "^5.2.1"
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/components/ButtonsBox.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import styles from './ButtonsBox.module.css'
3 |
4 | const ButtonsBox = ({ children }) => {
5 | return {children}
6 | }
7 |
8 | export default ButtonsBox
9 |
--------------------------------------------------------------------------------
/src/components/ButtonsBox.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | width: 100%;
3 | display: inline-grid;
4 | grid-template-columns: repeat(5, auto);
5 | place-items: center;
6 | }
7 |
8 | @media only screen and (max-width: 600px) {
9 | .wrapper {
10 | width: 100%;
11 | grid-template-columns: repeat(3, auto);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/LoopCurrent.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import styles from './LoopCurrent.module.css'
3 |
4 | const LoopCurrent = (props) => {
5 | return (
6 |
11 | )
12 | }
13 |
14 | export default LoopCurrent
15 |
--------------------------------------------------------------------------------
/src/components/LoopCurrent.module.css:
--------------------------------------------------------------------------------
1 | .loop_current {
2 | width: 26px;
3 | height: 26px;
4 | transition: transform 0.2s;
5 | }
6 |
7 | .loop_current:hover {
8 | cursor: pointer;
9 | transform: scale(1.2);
10 | }
11 |
12 | @media only screen and (max-width: 600px) {
13 | .loop_current {
14 | display: none;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/Next.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import styles from './Next.module.css'
3 |
4 | const Next = (props) => {
5 | return
6 | }
7 |
8 | export default Next
9 |
--------------------------------------------------------------------------------
/src/components/Next.module.css:
--------------------------------------------------------------------------------
1 | .next {
2 | width: 50px;
3 | height: 50px;
4 | transition: transform 0.2s;
5 | }
6 |
7 | .next:hover {
8 | cursor: pointer;
9 | transform: scale(1.2);
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/PageTemplate.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import styles from './PageTemplate.module.css'
3 |
4 | const PageTemplate = ({ children }) => {
5 | return {children}
6 | }
7 |
8 | export default PageTemplate
9 |
--------------------------------------------------------------------------------
/src/components/PageTemplate.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | width: 100%;
3 | margin: 0 auto;
4 | padding: 0;
5 | position: relative;
6 | }
7 |
8 | @media only screen and (max-width: 600px) {
9 | .wrapper {
10 | padding: 0;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/components/Pause.js:
--------------------------------------------------------------------------------
1 | import styles from './Pause.module.css'
2 | import React from 'react'
3 |
4 | const Pause = (props) => {
5 | return (
6 |
7 | )
8 | }
9 |
10 | export default Pause
11 |
--------------------------------------------------------------------------------
/src/components/Pause.module.css:
--------------------------------------------------------------------------------
1 | .pause {
2 | width: 60px;
3 | height: 60px;
4 | transition: transform 0.2s;
5 | }
6 |
7 | .pause:hover {
8 | cursor: pointer;
9 | transform: scale(1.2);
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/Play.js:
--------------------------------------------------------------------------------
1 | import styles from './Play.module.css'
2 | import React from 'react'
3 |
4 | const Play = (props) => {
5 | return
6 | }
7 |
8 | export default Play
9 |
--------------------------------------------------------------------------------
/src/components/Play.module.css:
--------------------------------------------------------------------------------
1 | .play {
2 | width: 60px;
3 | height: 60px;
4 | transition: transform 0.2s;
5 | }
6 |
7 | .play:hover {
8 | cursor: pointer;
9 | transform: scale(1.2);
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/PlayerTemplate.js:
--------------------------------------------------------------------------------
1 | import styles from './PlayerTemplate.module.css'
2 | import React from 'react'
3 |
4 | const PlayerTemplate = ({ children }) => {
5 | return {children}
6 | }
7 |
8 | export default PlayerTemplate
9 |
--------------------------------------------------------------------------------
/src/components/PlayerTemplate.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | width: 100%;
3 | border-radius: 10px;
4 | padding: 0 40px;
5 | margin: 0 auto;
6 | background-color: var(--playerBackground);
7 | overflow: auto;
8 | font-family: 'Quicksand', sans-serif;
9 | }
10 |
11 | @media only screen and (max-width: 768px) {
12 | .wrapper {
13 | width: 100%;
14 | }
15 | }
16 |
17 | @media only screen and (max-width: 600px) {
18 | .wrapper {
19 | padding: 0 20px;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/components/PlaylistItem.js:
--------------------------------------------------------------------------------
1 | import styles from './PlaylistItem.module.css'
2 | import React from 'react'
3 |
4 | const PlaylistItem = (props) => {
5 | return (
6 |
13 | {props.title}
14 |
15 | )
16 | }
17 |
18 | export default PlaylistItem
19 |
--------------------------------------------------------------------------------
/src/components/PlaylistItem.module.css:
--------------------------------------------------------------------------------
1 | .track {
2 | background-color: var(--playlistBackground);
3 | color: var(--playlistText);
4 | font-family: 'Poppins', sans-serif;
5 | text-align: center;
6 | font-size: 16px;
7 | margin: 5px 0;
8 | padding: 3px 0;
9 | cursor: pointer;
10 | border-radius: 5px;
11 | }
12 |
13 | .track:first-child {
14 | margin: 0;
15 | }
16 |
17 | .active {
18 | background-color: var(--playlistBackground);
19 | color: var(--playlistTextHoverActive);
20 | text-align: center;
21 | font-size: 18px;
22 | margin: 5px 0;
23 | padding: 3px 0;
24 | cursor: pointer;
25 |
26 | border-radius: 5px;
27 | }
28 |
29 | .active:first-child {
30 | margin: 0;
31 | }
32 |
33 | .track:hover {
34 | background-color: var(--playlistBackground);
35 | color: var(--playlistTextHoverActive);
36 | border-radius: 5px;
37 | }
38 |
--------------------------------------------------------------------------------
/src/components/PlaylistTemplate.js:
--------------------------------------------------------------------------------
1 | import styles from './PlaylistTemplate.module.css'
2 | import React from 'react'
3 |
4 | const PlaylistTemplate = ({ children }) => {
5 | return {children}
6 | }
7 |
8 | export default PlaylistTemplate
9 |
--------------------------------------------------------------------------------
/src/components/PlaylistTemplate.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | width: 100%;
3 | margin: 20px auto 20px auto;
4 | max-height: 425px;
5 | min-height: 120px;
6 | overflow-x: hidden;
7 | padding-right: 10px;
8 | font-family: "Quicksand", sans-serif;
9 | }
10 |
11 | /* width */
12 | .wrapper::-webkit-scrollbar {
13 | width: 5px;
14 | }
15 |
16 | /* Track */
17 | .wrapper::-webkit-scrollbar-track {
18 | border-radius: 10px;
19 | }
20 |
21 | /* Handle */
22 | .wrapper::-webkit-scrollbar-thumb {
23 | background: var(--primaryText);
24 | border-radius: 10px;
25 | }
26 |
27 | @media only screen and (min-width: 768px) {
28 | .wrapper {
29 | width: 90%;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/components/Previous.js:
--------------------------------------------------------------------------------
1 | import styles from './Previous.module.css'
2 | import React from 'react'
3 |
4 | const Previous = (props) => {
5 | return (
6 |
7 | )
8 | }
9 |
10 | export default Previous
11 |
--------------------------------------------------------------------------------
/src/components/Previous.module.css:
--------------------------------------------------------------------------------
1 | .previous {
2 | width: 50px;
3 | height: 50px;
4 | transition: transform 0.2s;
5 | }
6 |
7 | .previous:hover {
8 | cursor: pointer;
9 | transform: scale(1.2);
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/Progress.js:
--------------------------------------------------------------------------------
1 | import styles from "./Progress.module.css";
2 | import React from "react";
3 |
4 | const Progress = (props) => {
5 | return (
6 |
7 |
24 |
25 | );
26 | };
27 |
28 | export default Progress;
29 |
--------------------------------------------------------------------------------
/src/components/Progress.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | display: grid;
3 | place-items: center;
4 | width: 100%;
5 | margin-bottom: 20px;
6 | }
7 |
8 | .slider {
9 | -webkit-appearance: none;
10 | width: 100%;
11 | height: 4px;
12 | border-radius: 5px;
13 | outline: none;
14 | opacity: 1;
15 | -webkit-transition: 0.2s;
16 | transition: opacity 0.2s;
17 | }
18 |
19 | .slider::-webkit-slider-thumb {
20 | -webkit-appearance: none;
21 | appearance: none;
22 | width: 25px;
23 | height: 25px;
24 | border-radius: 50%;
25 | background: var(--progressSlider);
26 | cursor: pointer;
27 | }
28 |
29 | .slider::-webkit-slider-thumb:hover {
30 | background: var(--progressSlider);
31 | }
32 |
33 | .slider::-moz-range-thumb {
34 | width: 20px;
35 | height: 20px;
36 | border-radius: 50%;
37 | background: var(--progressSlider);
38 | cursor: pointer;
39 | }
40 |
41 | @media only screen and (max-width: 600px) {
42 | .container {
43 | margin: 40px 0;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/components/Search.js:
--------------------------------------------------------------------------------
1 | import styles from './Search.module.css'
2 | import React from 'react'
3 |
4 | const Search = ({ onChange, value, placeholder }) => {
5 | return (
6 |
7 |
14 |
15 | )
16 | }
17 |
18 | export default Search
19 |
--------------------------------------------------------------------------------
/src/components/Search.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | text-align: center;
3 | }
4 |
5 | .search {
6 | font-family: 'Quicksand', sans-serif;
7 | height: 40px;
8 | border: none;
9 | font-size: 18px;
10 | width: 100%;
11 | margin: 0 auto 10px auto;
12 | background-color: var(--searchBackground);
13 | color: var(--searchText);
14 | padding-left: 20px;
15 | border-radius: 10px;
16 | }
17 |
18 | .search::placeholder {
19 | color: var(--searchPlaceHolder);
20 | opacity: 1;
21 | }
22 |
23 | .search:-ms-input-placeholder {
24 | color: var(--searchPlaceHolder);
25 | }
26 |
27 | .search::-ms-input-placeholder {
28 | color: var(--searchPlaceHolder);
29 | }
30 |
--------------------------------------------------------------------------------
/src/components/Shuffle.js:
--------------------------------------------------------------------------------
1 | import styles from './Shuffle.module.css'
2 | import React from 'react'
3 |
4 | const Shuffle = (props) => {
5 | return (
6 |
7 | )
8 | }
9 |
10 | export default Shuffle
11 |
--------------------------------------------------------------------------------
/src/components/Shuffle.module.css:
--------------------------------------------------------------------------------
1 | .shuffle {
2 | width: 26px;
3 | height: 26px;
4 | transition: transform 0.2s;
5 | }
6 |
7 | .shuffle:hover {
8 | cursor: pointer;
9 | transform: scale(1.2);
10 | }
11 |
12 | @media only screen and (max-width: 600px) {
13 | .shuffle {
14 | display: none;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/TagItem.js:
--------------------------------------------------------------------------------
1 | import styles from './TagItem.module.css'
2 | import React from 'react'
3 |
4 | const TagItem = (props) => {
5 | return (
6 |
10 | {props.tag}
11 |
12 | )
13 | }
14 |
15 | export default TagItem
16 |
--------------------------------------------------------------------------------
/src/components/TagItem.module.css:
--------------------------------------------------------------------------------
1 | .tag {
2 | background-color: var(--tagsBackground);
3 | color: var(--tagsText);
4 | height: 40px;
5 | min-width: 100px;
6 | display: inline-grid;
7 | place-items: center;
8 | margin: 5px 5px;
9 | transition: transform 0.2s;
10 | padding: 0 10px;
11 | font-family: 'Varela Round', sans-serif;
12 | border-radius: 10px;
13 | font-size: 18px;
14 | }
15 |
16 | .active {
17 | background-color: var(--tagsBackgroundHoverActive);
18 | color: var(--tagsTextHoverActive);
19 | height: 40px;
20 | min-width: 100px;
21 | display: inline-grid;
22 | place-items: center;
23 | margin: 0 5px;
24 | transition: transform 0.3s;
25 | padding: 0 10px;
26 | font-family: 'Varela Round', sans-serif;
27 | cursor: pointer;
28 | border-radius: 10px;
29 | font-size: 18px;
30 | }
31 |
32 | .tag:hover {
33 | background-color: var(--tagsBackgroundHoverActive);
34 | color: var(--tagsTextHoverActive);
35 | cursor: pointer;
36 | transform: scale(1.1);
37 | }
38 |
--------------------------------------------------------------------------------
/src/components/TagsTemplate.js:
--------------------------------------------------------------------------------
1 | import styles from './TagsTemplate.module.css'
2 | import React from 'react'
3 |
4 | const TagsTemplate = ({ children }) => {
5 | return {children}
6 | }
7 |
8 | export default TagsTemplate
9 |
--------------------------------------------------------------------------------
/src/components/TagsTemplate.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | display: none;
3 | }
4 |
5 | @media only screen and (min-width: 768px) {
6 | .wrapper {
7 | width: 100%;
8 | margin: 20px auto;
9 | height: auto;
10 | color: var(--primaryText);
11 | display: inline-block;
12 | text-align: center;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/components/Time.js:
--------------------------------------------------------------------------------
1 | import styles from './Time.module.css'
2 | import React from 'react'
3 |
4 | const Time = (props) => {
5 | return {props.time}
6 | }
7 |
8 | export default Time
9 |
--------------------------------------------------------------------------------
/src/components/Time.module.css:
--------------------------------------------------------------------------------
1 | .time {
2 | font-family: 'Varela Round', sans-serif;
3 | color: var(--timeColor);
4 | text-align: right;
5 | font-size: 30px;
6 | margin: 0;
7 | }
8 |
9 | @media only screen and (max-width: 600px) {
10 | .time {
11 | width: 100%;
12 | margin: 0 auto;
13 | display: none;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/components/Title.js:
--------------------------------------------------------------------------------
1 | import styles from './Title.module.css'
2 | import React from 'react'
3 |
4 | const Title = (props) => {
5 | return {props.title}
6 | }
7 |
8 | export default Title
9 |
--------------------------------------------------------------------------------
/src/components/Title.module.css:
--------------------------------------------------------------------------------
1 | .title {
2 | color: var(--titleColor);
3 | font-size: 28px;
4 | margin: 0;
5 | }
6 |
7 | @media only screen and (max-width: 600px) {
8 | .title {
9 | width: 100%;
10 | margin-bottom: 0;
11 | text-align: center;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/Volume.js:
--------------------------------------------------------------------------------
1 | import styles from './Volume.module.css'
2 | import React from 'react'
3 |
4 | const Volume = (props) => {
5 | return (
6 |
7 |
21 |
22 | )
23 | }
24 |
25 | export default Volume
26 |
--------------------------------------------------------------------------------
/src/components/Volume.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | display: grid;
3 | place-items: center;
4 | width: 100%;
5 | min-height: 60px;
6 | }
7 |
8 | .slider {
9 | -webkit-appearance: none;
10 | width: 70%;
11 | height: 3px;
12 | border-radius: 5px;
13 | background: var(--volumeSlider);
14 | outline: none;
15 | opacity: 1;
16 | -webkit-transition: 0.2s;
17 | transition: opacity 0.2s;
18 | }
19 |
20 | .slider::-webkit-slider-thumb {
21 | -webkit-appearance: none;
22 | appearance: none;
23 | width: 20px;
24 | height: 20px;
25 | border-radius: 50%;
26 | background: var(--volumeSlider);
27 | cursor: pointer;
28 | }
29 |
30 | .slider::-webkit-slider-thumb:hover {
31 | background: var(--volumeSlider);
32 | }
33 |
34 | .slider::-moz-range-thumb {
35 | width: 20px;
36 | height: 20px;
37 | border-radius: 50%;
38 | background: var(--volumeSlider);
39 | cursor: pointer;
40 | }
41 |
42 | @media only screen and (max-width: 800px) {
43 | .wrapper {
44 | display: none;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/icons/loop_current.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/audio-player/9d230022627b7304bb6bb2b92558eb0d123315a4/src/icons/loop_current.png
--------------------------------------------------------------------------------
/src/icons/loop_none.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/audio-player/9d230022627b7304bb6bb2b92558eb0d123315a4/src/icons/loop_none.png
--------------------------------------------------------------------------------
/src/icons/next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/audio-player/9d230022627b7304bb6bb2b92558eb0d123315a4/src/icons/next.png
--------------------------------------------------------------------------------
/src/icons/pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/audio-player/9d230022627b7304bb6bb2b92558eb0d123315a4/src/icons/pause.png
--------------------------------------------------------------------------------
/src/icons/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/audio-player/9d230022627b7304bb6bb2b92558eb0d123315a4/src/icons/play.png
--------------------------------------------------------------------------------
/src/icons/previous.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/audio-player/9d230022627b7304bb6bb2b92558eb0d123315a4/src/icons/previous.png
--------------------------------------------------------------------------------
/src/icons/shuffle_all.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/audio-player/9d230022627b7304bb6bb2b92558eb0d123315a4/src/icons/shuffle_all.png
--------------------------------------------------------------------------------
/src/icons/shuffle_none.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/NFhook/audio-player/9d230022627b7304bb6bb2b92558eb0d123315a4/src/icons/shuffle_none.png
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import styles from "./styles/Player.module.css";
2 | import { createGlobalStyle } from "styled-components";
3 | import React, { useState, useEffect, useRef } from "react";
4 |
5 | import PageTemplate from "./components/PageTemplate";
6 | import PlayerTemplate from "./components/PlayerTemplate";
7 | import Title from "./components/Title";
8 | import Time from "./components/Time";
9 | import Progress from "./components/Progress";
10 | import ButtonsBox from "./components/ButtonsBox";
11 | import LoopCurrent from "./components/LoopCurrent";
12 | import Previous from "./components/Previous";
13 | import Play from "./components/Play";
14 | import Pause from "./components/Pause";
15 | import Next from "./components/Next";
16 | import Shuffle from "./components/Shuffle";
17 | import Volume from "./components/Volume";
18 | import PlaylistTemplate from "./components/PlaylistTemplate";
19 | import PlaylistItem from "./components/PlaylistItem";
20 | import TagsTemplate from "./components/TagsTemplate";
21 | import TagItem from "./components/TagItem";
22 | import Search from "./components/Search";
23 |
24 | import loopCurrentBtn from "icons/loop_current.png";
25 | import loopNoneBtn from "icons/loop_none.png";
26 | import previousBtn from "icons/previous.png";
27 | import playBtn from "icons/play.png";
28 | import pauseBtn from "icons/pause.png";
29 | import nextBtn from "icons/next.png";
30 | import shuffleAllBtn from "icons/shuffle_all.png";
31 | import shuffleNoneBtn from "icons/shuffle_none.png";
32 |
33 | const colors = `html{
34 | --tagsBackground: #9440f3;
35 | --tagsText: #ffffff;
36 | --tagsBackgroundHoverActive: #2cc0a0;
37 | --tagsTextHoverActive: #ffffff;
38 | --searchBackground: #18191f;
39 | --searchText: #ffffff;
40 | --searchPlaceHolder: #575a77;
41 | --playerBackground: #18191f;
42 | --titleColor: #ffffff;
43 | --timeColor: #ffffff;
44 | --progressSlider: #9440f3;
45 | --progressUsed: #ffffff;
46 | --progressLeft: #151616;
47 | --volumeSlider: #9440f3;
48 | --volumeUsed: #ffffff;
49 | --volumeLeft: #151616;
50 | --playlistBackground: #18191f;
51 | --playlistText: #575a77;
52 | --playlistBackgroundHoverActive: #18191f;
53 | --playlistTextHoverActive: #ffffff;
54 | }`;
55 |
56 | const Player = ({
57 | trackList,
58 | includeTags = true,
59 | includeSearch = true,
60 | showPlaylist = true,
61 | autoPlayNextTrack = true,
62 | customColorScheme = colors,
63 | }) => {
64 | const [query, updateQuery] = useState("");
65 |
66 | let playlist = [];
67 |
68 | const [audio, setAudio] = useState(null);
69 | const [active, setActive] = useState(false);
70 | const [title, setTitle] = useState("");
71 | const [length, setLength] = useState(0);
72 | const [time, setTime] = useState(0);
73 | const [slider, setSlider] = useState(1);
74 | const [drag, setDrag] = useState(0);
75 | const [volume, setVolume] = useState(0.8);
76 | let [end, setEnd] = useState(0);
77 | const [shuffled, setShuffled] = useState(false);
78 | const [looped, setLooped] = useState(false);
79 |
80 | const [filter, setFilter] = useState([]);
81 | let [curTrack, setCurTrack] = useState(0);
82 |
83 | const GlobalStyles = createGlobalStyle`
84 | ${customColorScheme}
85 | `;
86 |
87 | const fmtMSS = (s) => new Date(1000 * s).toISOString().substr(15, 4);
88 |
89 | useEffect(() => {
90 | const audio = new Audio(trackList[curTrack].url);
91 |
92 | const setAudioData = () => {
93 | setLength(audio.duration);
94 | setTime(audio.currentTime);
95 | };
96 |
97 | const setAudioTime = () => {
98 | const curTime = audio.currentTime;
99 | setTime(curTime);
100 | setSlider(curTime ? ((curTime * 100) / audio.duration).toFixed(1) : 0);
101 | };
102 |
103 | const setAudioVolume = () => setVolume(audio.volume);
104 |
105 | const setAudioEnd = () => setEnd((end += 1));
106 |
107 | // events on audio object
108 | audio.addEventListener("loadeddata", setAudioData);
109 | audio.addEventListener("timeupdate", setAudioTime);
110 | audio.addEventListener("volumechange", setAudioVolume);
111 | audio.addEventListener("ended", setAudioEnd);
112 |
113 | setAudio(audio);
114 | setTitle(trackList[curTrack].title);
115 |
116 | return () => {
117 | audio.pause();
118 | };
119 | }, []);
120 |
121 | const tags = [];
122 | trackList.forEach((track) => {
123 | track.tags.forEach((tag) => {
124 | if (!tags.includes(tag)) {
125 | tags.push(tag);
126 | }
127 | });
128 | });
129 |
130 | const shufflePlaylist = (arr) => {
131 | if (arr.length === 1) return arr;
132 | const rand = Math.floor(Math.random() * arr.length);
133 | return [arr[rand], ...shufflePlaylist(arr.filter((_, i) => i != rand))];
134 | };
135 |
136 | const isInitialMount = useRef(true);
137 | useEffect(() => {
138 | if (isInitialMount.current) {
139 | isInitialMount.current = false;
140 | } else {
141 | if (shuffled) {
142 | playlist = shufflePlaylist(playlist);
143 | }
144 | !looped && autoPlayNextTrack ? next() : play();
145 | }
146 | }, [end]);
147 |
148 | useEffect(() => {
149 | if (audio != null) {
150 | audio.volume = volume;
151 | }
152 | }, [volume]);
153 |
154 | useEffect(() => {
155 | if (audio != null) {
156 | pause();
157 | const val = Math.round((drag * audio.duration) / 100);
158 | audio.currentTime = val;
159 | }
160 | }, [drag]);
161 |
162 | const play = () => {
163 | setActive(true);
164 | audio.play();
165 | };
166 |
167 | const pause = () => {
168 | setActive(false);
169 | audio.pause();
170 | };
171 |
172 | const loop = () => {
173 | setLooped(!looped);
174 | };
175 |
176 | useEffect(() => {
177 | if (audio != null) {
178 | audio.src = trackList[curTrack].url;
179 | setTitle(trackList[curTrack].title);
180 | play();
181 | }
182 | }, [curTrack]);
183 |
184 | const previous = () => {
185 | const index = playlist.indexOf(curTrack);
186 | index !== 0
187 | ? setCurTrack((curTrack = playlist[index - 1]))
188 | : setCurTrack((curTrack = playlist[playlist.length - 1]));
189 | };
190 |
191 | const next = () => {
192 | const index = playlist.indexOf(curTrack);
193 | index !== playlist.length - 1
194 | ? setCurTrack((curTrack = playlist[index + 1]))
195 | : setCurTrack((curTrack = playlist[0]));
196 | };
197 |
198 | const shuffle = () => {
199 | setShuffled(!shuffled);
200 | };
201 |
202 | const playlistItemClickHandler = (e) => {
203 | const num = Number(e.currentTarget.getAttribute("data-key"));
204 | const index = playlist.indexOf(num);
205 | setCurTrack((curTrack = playlist[index]));
206 | play();
207 | };
208 |
209 | const isInitialFilter = useRef(true);
210 | useEffect(() => {
211 | if (isInitialFilter.current) {
212 | isInitialFilter.current = false;
213 | } else {
214 | if (!playlist.includes(curTrack)) {
215 | setCurTrack((curTrack = playlist[0]));
216 | }
217 | }
218 | }, [filter]);
219 |
220 | const tagClickHandler = (e) => {
221 | const tag = e.currentTarget.innerHTML;
222 | if (!filter.includes(tag)) {
223 | setFilter([...filter, tag]);
224 | } else {
225 | const filteredArray = filter.filter((item) => item !== tag);
226 | setFilter([...filteredArray]);
227 | }
228 | };
229 |
230 | return (
231 |
232 |
233 | {includeTags && (
234 |
235 | {tags.map((tag, index) => {
236 | return (
237 |
245 | );
246 | })}
247 |
248 | )}
249 | {includeSearch && (
250 | updateQuery(e.target.value.toLowerCase())}
253 | placeholder={`Search ${trackList.length} tracks...`}
254 | />
255 | )}
256 |
257 |
258 |
259 |
264 |
265 |
266 |
301 |
302 | {showPlaylist && (
303 |
304 | {trackList
305 | .sort((a, b) => (a.title > b.title ? 1 : -1))
306 | .map((el, index) => {
307 | if (
308 | filter.length === 0 ||
309 | filter.some((filter) => el.tags.includes(filter))
310 | ) {
311 | if (el.title.toLowerCase().includes(query.toLowerCase())) {
312 | playlist.push(index);
313 | return (
314 |
322 | );
323 | }
324 | }
325 | })}
326 |
327 | )}
328 |
329 | );
330 | };
331 |
332 | export default Player;
333 |
--------------------------------------------------------------------------------
/src/styles/Player.module.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Varela+Round&display=swap');
2 | @import url('https://fonts.googleapis.com/css2?family=Quicksand:wght@500&display=swap');
3 | @import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
4 |
5 | html,
6 | body {
7 | padding: 0;
8 | margin: 0;
9 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
10 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
11 | }
12 |
13 | a {
14 | color: inherit;
15 | text-decoration: none;
16 | }
17 |
18 | * {
19 | box-sizing: border-box;
20 | }
21 |
22 | .title_time_wrapper {
23 | display: grid;
24 | grid-template-columns: auto 200px;
25 | margin: 30px 0 20px 0;
26 | }
27 |
28 | .buttons_volume_wrapper {
29 | display: grid;
30 | grid-template-columns: auto 30%;
31 | margin-bottom: 30px;
32 | }
33 |
34 | @media only screen and (max-width: 800px) {
35 | .title_time_wrapper {
36 | grid-template-columns: 100%;
37 | }
38 |
39 | .buttons_volume_wrapper {
40 | grid-template-columns: 100%;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------