├── .gitignore
├── Dockerfile
├── README.md
├── lib
├── anime_parser.js
├── api.js
├── helpers
│ ├── extractors
│ │ ├── fembed.js
│ │ ├── goload.js
│ │ └── streamsb.js
│ └── random.js
├── types
│ └── index.d.ts
└── utils.js
├── package-lock.json
├── package.json
├── render.yaml
└── vercel.json
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16 as builder
2 |
3 | LABEL version="1.0.0"
4 | LABEL description="anime API docker image"
5 | LABEL org.opencontainers.image.source https://github.com/kirixenyt/anime-api
6 |
7 | # update packages, to reduce risk of vulnerabilities
8 | RUN apt-get update && apt-get upgrade -y && apt-get autoclean -y && apt-get autoremove -y
9 |
10 | # set a non privileged user to use when running this image
11 | RUN groupadd -r nodejs && useradd -g nodejs -s /bin/bash -d /home/nodejs -m nodejs
12 | USER nodejs
13 | # set right (secure) folder permissions
14 | RUN mkdir -p /home/nodejs/app/node_modules && chown -R nodejs:nodejs /home/nodejs/app
15 |
16 | WORKDIR /home/nodejs/app
17 |
18 | # set default node env
19 | ARG NODE_ENV=development
20 | ARG PORT=3000
21 | # ARG NODE_ENV=production
22 | # to be able to run tests (for example in CI), do not set production as environment
23 | ENV NODE_ENV=${NODE_ENV}
24 | ENV PORT=${PORT}
25 |
26 | ENV NPM_CONFIG_LOGLEVEL=warn
27 |
28 | # copy project definition/dependencies files, for better reuse of layers
29 | COPY --chown=nodejs:nodejs package*.json ./
30 |
31 | # install dependencies here, for better reuse of layers
32 | RUN npm install && npm update && npm cache clean --force
33 |
34 | # copy all sources in the container (exclusions in .dockerignore file)
35 | COPY --chown=nodejs:nodejs . .
36 |
37 | # exposed port/s
38 | EXPOSE 3000
39 |
40 | HEALTHCHECK --interval=30s --timeout=10s --start-period=5s CMD npm run healthcheck-manual
41 |
42 | CMD [ "npm", "start" ]
43 |
44 | # end.
45 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Anime API
2 |
3 |
4 | ### Broken
5 | **`As you all know, Gogoanime is currently broken and doesn't update episodes anymore.`**
6 |
7 |
8 | Details
9 | Gogoanime is experiencing issues with updating episodes, which is why the API may not return the most recent content.
10 |
11 | Kindly note that no complaints be made regarding the lack of updates as I can't do anything.
12 |
13 |
14 | ### Intro
15 |
16 | Modified api of [Gogoanime-api](https://github.com/riimuru/gogoanime-api)
17 |
18 | ### Installing
19 |
20 | Clone the Repository and run
21 |
22 |
23 | ```
24 | git clone https://github.com/kirixen/gogo-api.git
25 | cd gogo-api
26 | npm install
27 | ```
28 | start the server with the following command:
29 | ```
30 | npm start
31 | ```
32 |
33 | Now the server is running on http://localhost:3000
34 |
35 | ### Render
36 | Host your own api on render using the button below.
37 |
38 | [](https://render.com/deploy?repo=https://github.com/Kirixen/gogo-api)
39 |
40 | ### Vercel
41 |
42 | [](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fkirixen%gogo-api)
43 |
44 | Note : if u have an error after clickin the above button then fork the repo and deploy it through vercel itself
45 |
46 | [](https://discord.gg/VsPXjNRcbw)
47 |
48 |
--------------------------------------------------------------------------------
/lib/anime_parser.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import cheerio from 'cheerio';
3 |
4 | import {
5 | generateEncryptAjaxParameters,
6 | decryptEncryptAjaxResponse,
7 | } from './helpers/extractors/goload.js';
8 | import { extractStreamSB } from './helpers/extractors/streamsb.js';
9 | import { extractFembed } from './helpers/extractors/fembed.js';
10 | import { USER_AGENT, renameKey } from './utils.js';
11 |
12 | const BASE_URL = 'https://gogoanime3.co';
13 | const BASE_URL3 = 'https://anitaku.pe/home.html';
14 | const BASE_URL2 = 'https://anitaku.pe/';
15 | const ajax_url = 'https://ajax.gogocdn.net/';
16 | const anime_info_url = 'https://gogoanime3.net/category/';
17 | const anime_movies_path = '/anime-movies.html';
18 | const popular_path = '/popular.html';
19 | const new_season_path = '/new-season.html';
20 | const search_path = '/search.html';
21 | const popular_ongoing_url = `${ajax_url}ajax/page-recent-release-ongoing.html`;
22 | const recent_release_url = `${ajax_url}ajax/page-recent-release.html`;
23 | const list_episodes_url = `${ajax_url}ajax/load-list-episode`;
24 | const seasons_url = 'https://anitaku.pe/sub-category/';
25 |
26 | const Referer = 'https://gogoplay.io/';
27 | const goload_stream_url = 'https://embtaku.pro/streaming.php';
28 | export const DownloadReferer = 'https://embtaku.pro/';
29 |
30 | const disqus_iframe = (episodeId) =>
31 | `https://disqus.com/embed/comments/?base=default&f=gogoanimetv&t_u=https%3A%2F%2Fgogoanime.vc%2F${episodeId}&s_o=default#version=cfefa856cbcd7efb87102e7242c9a829`;
32 | const disqus_api = (threadId, page) =>
33 | `https://disqus.com/api/3.0/threads/listPostsThreaded?limit=100&thread=${threadId}&forum=gogoanimetv&order=popular&cursor=${page}:0:0&api_key=E8Uh5l5fHZ6gD8U3KycjAIAk46f68Zw7C6eW8WSjZvCLXebZ7p0r1yrYDrLilk2F`;
34 |
35 | const Genres = [
36 | 'action',
37 | 'adventure',
38 | 'cars',
39 | 'comedy',
40 | 'crime',
41 | 'dementia',
42 | 'demons',
43 | 'drama',
44 | 'dub',
45 | 'ecchi',
46 | 'family',
47 | 'fantasy',
48 | 'game',
49 | 'gourmet',
50 | 'harem',
51 | 'hentai',
52 | 'historical',
53 | 'horror',
54 | 'josei',
55 | 'kids',
56 | 'magic',
57 | 'martial-arts',
58 | 'mecha',
59 | 'military',
60 | 'Mmusic',
61 | 'mystery',
62 | 'parody',
63 | 'police',
64 | 'psychological',
65 | 'romance',
66 | 'samurai',
67 | 'school',
68 | 'sci-fi',
69 | 'seinen',
70 | 'shoujo',
71 | 'shoujo-ai',
72 | 'shounen',
73 | 'shounen-ai',
74 | 'slice-of-life',
75 | 'space',
76 | 'sports',
77 | 'super-power',
78 | 'supernatural',
79 | 'suspense',
80 | 'thriller',
81 | 'vampire',
82 | 'yaoi',
83 | 'yuri',
84 | 'isekai',
85 | ];
86 |
87 | const cachedDownloadLinks = {};
88 |
89 | export const scrapeFembed = async ({ id }) => {
90 | try {
91 | const epPage = await axios.get(BASE_URL2 + id);
92 | const $ = cheerio.load(epPage.data);
93 |
94 | const server = $('.xstreamcdn > a:nth-child(1)').attr('data-video');
95 | const serverUrl = new URL(server);
96 |
97 | const sources = await extractFembed(serverUrl.href);
98 |
99 | if (!sources) return { error: 'No sources found!! Try different source.' };
100 |
101 | return sources;
102 | } catch (e) {
103 | return { error: e.message };
104 | }
105 | };
106 |
107 | export const scrapeStreamSB = async ({ id }) => {
108 | try {
109 | const epPage = await axios.get(BASE_URL2 + id);
110 | const $ = cheerio.load(epPage.data);
111 |
112 | const server = $(
113 | 'div.anime_video_body > div.anime_muti_link > ul > li.streamsb > a'
114 | ).attr('data-video');
115 | const serverUrl = new URL(server);
116 |
117 | const res = await extractStreamSB(serverUrl.href);
118 |
119 | if (!res.stream_data) return { error: 'No sources found!! Try different source.' };
120 |
121 | return {
122 | headers: { Referer: serverUrl.href, 'User-Agent': USER_AGENT },
123 | data: [{ file: res.stream_data.file }, { backup: res.stream_data.backup }],
124 | };
125 | } catch (err) {
126 | console.log(err);
127 | return { error: err.message };
128 | }
129 | };
130 |
131 |
132 | export const scrapeMP4 = async ({ id }) => {
133 | let sources = [];
134 | let sources_bk = [];
135 | try {
136 | let epPage, server, $, serverUrl;
137 |
138 | if (id) {
139 | epPage = await axios.get(BASE_URL2 + id);
140 | $ = cheerio.load(epPage.data);
141 |
142 | server = $('#load_anime > div > div > iframe').attr('src');
143 | serverUrl = new URL(server);
144 | } else throw Error("Episode id not found")
145 |
146 | const goGoServerPage = await axios.get(serverUrl.href, {
147 | headers: { 'User-Agent': USER_AGENT },
148 | });
149 | const $$ = cheerio.load(goGoServerPage.data);
150 |
151 | const params = await generateEncryptAjaxParameters(
152 | $$,
153 | serverUrl.searchParams.get('id')
154 | );
155 |
156 | const fetchRes = await axios.get(
157 | `
158 | ${serverUrl.protocol}//${serverUrl.hostname}/encrypt-ajax.php?${params}`, {
159 | headers: {
160 | 'User-Agent': USER_AGENT,
161 | 'X-Requested-With': 'XMLHttpRequest',
162 | },
163 | }
164 | );
165 |
166 | const res = decryptEncryptAjaxResponse(fetchRes.data);
167 |
168 | if (!res.source) return { error: 'No sources found!! Try different source.' };
169 |
170 | res.source.forEach((source) => sources.push(source));
171 | res.source_bk.forEach((source) => sources_bk.push(source));
172 |
173 | return {
174 | Referer: serverUrl.href,
175 | sources: sources,
176 | sources_bk: sources_bk,
177 | };
178 | } catch (err) {
179 | return { error: err };
180 | }
181 | };
182 |
183 | export const scrapeSearch = async ({ list = [], keyw, page = 1 }) => {
184 | try {
185 | const searchPage = await axios.get(
186 | `${BASE_URL2 + search_path}?keyword=${keyw}&page=${page}`
187 | );
188 | const $ = cheerio.load(searchPage.data);
189 |
190 | $('div.last_episodes > ul > li').each((i, el) => {
191 | list.push({
192 | anime_id: $(el).find('p.name > a').attr('href').split('/')[2],
193 | name: $(el).find('p.name > a').attr('title'),
194 | img_url: $(el).find('div > a > img').attr('src'),
195 | status: $(el).find('p.released').text().trim(),
196 | });
197 | });
198 |
199 | if (list.length === 0) {
200 | return { error: 'No results found' };
201 | }
202 |
203 | return list;
204 | } catch (err) {
205 | console.log(err);
206 | return { error: err };
207 | }
208 | };
209 |
210 | export const scrapeRecentRelease = async ({ list = [], page = 1, type = 1 }) => {
211 | try {
212 | const mainPage = await axios.get(`
213 | ${recent_release_url}?page=${page}&type=${type}
214 | `);
215 | const $ = cheerio.load(mainPage.data);
216 |
217 | $('div.last_episodes.loaddub > ul > li').each((i, el) => {
218 | list.push({
219 | animeId: $(el).find('p.name > a').attr('href').split('/')[1].split('-episode-')[0],
220 | episodeId: $(el).find('p.name > a').attr('href').split('/')[1],
221 | name: $(el).find('p.name > a').attr('title'),
222 | episodeNum: $(el).find('p.episode').text().replace('Episode ', '').trim(),
223 | subOrDub: $(el).find('div > a > div').attr('class').replace('type ic-', ''),
224 | imgUrl: $(el).find('div > a > img').attr('src')
225 | });
226 | });
227 | return list;
228 | } catch (err) {
229 | console.log(err);
230 | return { error: err };
231 | }
232 | };
233 |
234 |
235 |
236 | export const scrapeAnimeList = async ({ list = [], page = 1 }) => {
237 | try {
238 | const AnimeList = await axios.get(`${BASE_URL2}/anime-list.html?page=${page}`);
239 | const $ = cheerio.load(AnimeList.data);
240 |
241 | $('div.anime_list_body > ul.listing > li').each((i, el) => {
242 | list.push({
243 | animeTitle: $(el).find('a').html().replace(/"/g, ""),
244 | animeId: $(el).find('a').attr('href').replace("/category/", ""),
245 | liTitle: $(el).attr('title')
246 | });
247 | });
248 | return list;
249 | } catch (err) {
250 | console.log(err);
251 | return { error: err };
252 | }
253 | };
254 |
255 | export const scrapeAnimeAZ = async ({ list = [], aph, page = 1 }) => {
256 | try {
257 | const AnimeAZ = await axios.get(`${BASE_URL2}/anime-list-${aph}?page=${page}`);
258 | const $ = cheerio.load(AnimeAZ.data);
259 |
260 | $('div.anime_list_body > ul.listing > li').each((i, el) => {
261 | list.push({
262 | animeTitle: $(el).find('a').html().replace(/"/g, ""),
263 | animeId: $(el).find('a').attr('href').replace("/category/", ""),
264 | liTitle: $(el).attr('title')
265 | });
266 | });
267 | return list;
268 | } catch (err) {
269 | console.log(err);
270 | return { error: err };
271 | }
272 | };
273 |
274 | export const scrapeRecentlyAdded = async ({ list = [], page = 1 }) => {
275 | try {
276 | const RecentlyAdded = await axios.get(`${BASE_URL3}?page=${page}`);
277 | const $ = cheerio.load(RecentlyAdded.data);
278 |
279 | $('div.added_series_body.final ul.listing li').each((i, el) => {
280 | list.push({
281 | animeId: $(el).find('a').attr('href').split('/')[2],
282 | animeName: $(el).find('a').text()
283 | });
284 | });
285 | return list;
286 | } catch (err) {
287 | console.log(err);
288 | return { error: err };
289 | }
290 | };
291 |
292 | export const scrapeOngoingSeries = async ({ list = [], page = 1 }) => {
293 | try {
294 | const OngoingSeries = await axios.get(`${BASE_URL3}?page=${page}`);
295 | const $ = cheerio.load(OngoingSeries.data);
296 |
297 | $('nav.menu_series.cron ul li').each((i, el) => {
298 | list.push({
299 | animeId: $(el).find('a').attr('href').split('/')[2],
300 | animeName: $(el).find('a').text()
301 | });
302 | });
303 | return list;
304 | } catch (err) {
305 | console.log(err);
306 | return { error: err };
307 | }
308 | };
309 |
310 | export const scrapeNewSeason = async ({ list = [], page = 1 }) => {
311 | try {
312 | const popularPage = await axios.get(`
313 | ${BASE_URL2 + new_season_path}?page=${page}
314 | `);
315 | const $ = cheerio.load(popularPage.data);
316 |
317 | $('div.last_episodes > ul > li').each((i, el) => {
318 | list.push({
319 | animeId: $(el).find('p.name > a').attr('href').split('/')[2],
320 | animeTitle: $(el).find('p.name > a').attr('title'),
321 | imgUrl: $(el).find('div > a > img').attr('src'),
322 | status: $(el).find('p.released').text().trim()
323 | });
324 | });
325 | return list;
326 | } catch (err) {
327 | console.log(err);
328 | return { error: err };
329 | }
330 | };
331 |
332 | export const scrapeOngoingAnime = async ({ list = [], page = 1 }) => {
333 | try {
334 | const OngoingAnime = await axios.get(`${BASE_URL2}/ongoing-anime.html?page=${page}`);
335 | const $ = cheerio.load(OngoingAnime.data);
336 |
337 | $('div.main_body div.last_episodes ul.items li').each((i, el) => {
338 | list.push({
339 | animeId: $(el).find('p.name > a').attr('href').split('/')[2],
340 | animeTitle: $(el).find('p.name > a').attr('title'),
341 | imgUrl: $(el).find('div > a > img').attr('src'),
342 | status: $(el).find('p.released').text().trim()
343 | });
344 | });
345 | return list;
346 | } catch (err) {
347 | console.log(err);
348 | return { error: err };
349 | }
350 | };
351 |
352 | export const scrapeCompletedAnime = async ({ list = [], page = 1 }) => {
353 | try {
354 | const CompletedAnime = await axios.get(`${BASE_URL2}/completed-anime.html?page=${page}`);
355 | const $ = cheerio.load(CompletedAnime.data);
356 |
357 | $('div.main_body div.last_episodes ul.items li').each((i, el) => {
358 | list.push({
359 | animeId: $(el).find('p.name > a').attr('href').split('/')[2],
360 | animeTitle: $(el).find('p.name > a').attr('title'),
361 | imgUrl: $(el).find('div > a > img').attr('src'),
362 | status: $(el).find('p.released').text().trim()
363 | });
364 | });
365 | return list;
366 | } catch (err) {
367 | console.log(err);
368 | return { error: err };
369 | }
370 | };
371 |
372 | export const scrapePopularAnime = async ({ list = [], page = 1 }) => {
373 | try {
374 | const popularPage = await axios.get(`
375 | ${BASE_URL2 + popular_path}?page=${page}
376 | `);
377 | const $ = cheerio.load(popularPage.data);
378 |
379 | $('div.last_episodes > ul > li').each((i, el) => {
380 | list.push({
381 | animeId: $(el).find('p.name > a').attr('href').split('/')[2],
382 | animeTitle: $(el).find('p.name > a').attr('title'),
383 | imgUrl: $(el).find('div > a > img').attr('src'),
384 | status: $(el).find('p.released').text().trim()
385 | });
386 | });
387 | return list;
388 | } catch (err) {
389 | console.log(err);
390 | return { error: err };
391 | }
392 | };
393 |
394 | export const scrapeAnimeMovies = async ({ list = [], aph = '', page = 1 }) => {
395 | try {
396 | const popularPage = await axios.get(`
397 | ${BASE_URL2 + anime_movies_path}?aph=${aph.trim().toUpperCase()}&page=${page}
398 | `);
399 | const $ = cheerio.load(popularPage.data);
400 |
401 | $('div.last_episodes > ul > li').each((i, el) => {
402 | list.push({
403 | animeId: $(el).find('p.name > a').attr('href').split('/')[2],
404 | animeTitle: $(el).find('p.name > a').attr('title'),
405 | imgUrl: $(el).find('div > a > img').attr('src'),
406 | status: $(el).find('p.released').text().trim(),
407 | });
408 | });
409 | return list;
410 | } catch (err) {
411 | console.log(err);
412 | return { error: err };
413 | }
414 | };
415 |
416 | export const scrapeTopAiringAnime = async ({ list = [], page = 1 }) => {
417 | try {
418 | if (page == -1) {
419 | let pageNum = 1;
420 | let hasMore = true;
421 | while (hasMore) {
422 | const popular_page = await axios.get(`
423 | ${popular_ongoing_url}?page=${pageNum}
424 | `);
425 | const $ = cheerio.load(popular_page.data);
426 |
427 | if ($('div.added_series_body.popular > ul > li').length == 0) {
428 | hasMore = false;
429 | continue;
430 | }
431 | $('div.added_series_body.popular > ul > li').each((i, el) => {
432 | let genres = [];
433 | $(el)
434 | .find('p.genres > a')
435 | .each((i, el) => {
436 | genres.push($(el).attr('title'));
437 | });
438 | list.push({
439 | animeId: $(el).find('a:nth-child(1)').attr('href').split('/')[2],
440 | animeTitle: $(el).find('a:nth-child(1)').attr('title'),
441 | animeImg: $(el)
442 | .find('a:nth-child(1) > div')
443 | .attr('style')
444 | .match('(https?://.*.(?:png|jpg))')[0],
445 | latestEp: $(el).find('p:nth-child(4) > a').text().trim(),
446 | animeUrl: BASE_URL2 + '/' + $(el).find('a:nth-child(1)').attr('href'),
447 | genres: genres,
448 | });
449 | });
450 | pageNum++;
451 | }
452 | return list;
453 | }
454 |
455 | const popular_page = await axios.get(`
456 | ${popular_ongoing_url}?page=${page}
457 | `);
458 | const $ = cheerio.load(popular_page.data);
459 |
460 | $('div.added_series_body.popular > ul > li').each((i, el) => {
461 | let genres = [];
462 | $(el)
463 | .find('p.genres > a')
464 | .each((i, el) => {
465 | genres.push($(el).attr('title'));
466 | });
467 | list.push({
468 | animeId: $(el).find('a:nth-child(1)').attr('href').split('/')[2],
469 | animeTitle: $(el).find('a:nth-child(1)').attr('title'),
470 | animeImg: $(el)
471 | .find('a:nth-child(1) > div')
472 | .attr('style')
473 | .match('(https?://.*.(?:png|jpg))')[0],
474 | latestEp: $(el).find('p:nth-child(4) > a').text().trim(),
475 | animeUrl: BASE_URL2 + '/' + $(el).find('a:nth-child(1)').attr('href'),
476 | genres: genres,
477 | });
478 | });
479 |
480 | return list;
481 | } catch (err) {
482 | console.log(err);
483 | return { error: err };
484 | }
485 | };
486 |
487 | export const scrapeGenre = async ({ list = [], genre, page = 1 }) => {
488 | try {
489 | genre = genre.trim().replace(/ /g, '-').toLowerCase();
490 |
491 | if (Genres.indexOf(genre) > -1) {
492 | const genrePage = await axios.get(`${BASE_URL2}genre/${genre}?page=${page}`);
493 | const $ = cheerio.load(genrePage.data);
494 |
495 | $('div.last_episodes > ul > li').each((i, elem) => {
496 | list.push({
497 | animeId: $(elem).find('p.name > a').attr('href').split('/')[2],
498 | animeTitle: $(elem).find('p.name > a').attr('title'),
499 | animeImg: $(elem).find('div > a > img').attr('src'),
500 | releasedDate: $(elem).find('p.released').text().trim(),
501 | animeUrl: BASE_URL2 + '/' + $(elem).find('p.name > a').attr('href'),
502 | });
503 | });
504 | return list;
505 | }
506 | return { error: 'Genre Not Found' };
507 | } catch (err) {
508 | console.log(err);
509 | return { error: err };
510 | }
511 | };
512 |
513 | // scrapeGenre({ genre: "cars", page: 1 }).then((res) => console.log(res))
514 |
515 | /**
516 | * @param {string} id anime id.
517 | * @returns Resolves when the scraping is complete.
518 | * @example
519 | * scrapeGoGoAnimeInfo({id: "naruto"})
520 | * .then((res) => console.log(res)) // => The anime information is returned in an Object.
521 | * .catch((err) => console.log(err))
522 | *
523 | */
524 | export const scrapeAnimeDetails = async ({ id }) => {
525 | try {
526 | let epList = [];
527 |
528 | const animePageTest = await axios.get(`https://anitaku.pe/category/${id}`);
529 |
530 | const $ = cheerio.load(animePageTest.data);
531 |
532 | const animeTitle = $('div.anime_info_body_bg > h1').text();
533 | const animeImage = $('div.anime_info_body_bg > img').attr('src');
534 | const type = $('div.anime_info_body_bg > p.type > a').first().text();
535 | const synopsis = $('div.anime_info_body_bg > div.description')
536 | .map((i, el) => {
537 | const content = $(el).find('p').length > 0
538 | ? $(el).find('p').map((i, p) => $(p).text()).get().join(' ')
539 | : $(el).text();
540 | return content;
541 | })
542 | .get()
543 | .join(' ')
544 | .replace('Plot Summary: ', '');
545 | const genres = $('div.anime_info_body_bg > p.type:contains("Genre") > a')
546 | .map((i, el) => $(el).text())
547 | .get()
548 | .join(', ');
549 | const releasedDate = $('div.anime_info_body_bg > p.type:contains("Released")')
550 | .text()
551 | .replace('Released: ', '');
552 | const status = $('div.anime_info_body_bg > p:nth-child(9) > a').text();
553 | const otherName = $('div.anime_info_body_bg > p:nth-child(10) > a')
554 | .text()
555 | .replace('Other name: ', '')
556 | .replace(/;/g, ',');
557 |
558 | $('div.anime_info_body_bg > p:nth-child(6) > a').each((i, elem) => {
559 | genres.push($(elem).attr('title').trim());
560 | });
561 |
562 | const ep_start = $('#episode_page > li').first().find('a').attr('ep_start');
563 | const ep_end = $('#episode_page > li').last().find('a').attr('ep_end');
564 | const movie_id = $('#movie_id').attr('value');
565 | const alias = $('#alias_anime').attr('value');
566 | const episode_info_html = $('div.anime_info_episodes_next').html();
567 | const episode_page = $('ul#episode_page').html();
568 |
569 | const html = await axios.get(
570 | `${list_episodes_url}?ep_start=${ep_start}&ep_end=${ep_end}&id=${movie_id}&default_ep=${0}&alias=${alias}`
571 | );
572 | const $$ = cheerio.load(html.data);
573 |
574 | $$('#episode_related > li').each((i, el) => {
575 | epList.push({
576 | episodeId: $(el).find('a').attr('href').split('/')[1],
577 | episodeNum: $(el).find(`div.name`).text().replace('EP ', ''),
578 | });
579 | });
580 |
581 | return {
582 | name: animeTitle.toString(),
583 | type: type.toString(),
584 | released: releasedDate.toString(),
585 | status: status.toString(),
586 | genres: genres,
587 | othername: otherName,
588 | synopsis: synopsis.toString(),
589 | imageUrl: animeImage.toString(),
590 | totalEpisodes: ep_end,
591 | episode_id: epList.reverse(),
592 | episode_info_html: episode_info_html.trim(),
593 | episode_page: episode_page.toString().trim(),
594 | };
595 | } catch (err) {
596 | console.log(err);
597 | return { error: err };
598 | }
599 | };
600 |
601 | export const scrapeSeason = async ({ list = [], season, page = 1 }) => {
602 | try {
603 | const season_page = await axios.get(`${seasons_url}${season}?page=${page}`);
604 | const $ = cheerio.load(season_page.data);
605 |
606 | $('div.last_episodes > ul > li').each((i, el) => {
607 | list.push({
608 | animeId: $(el).find('div > a').attr('href').split('/')[2],
609 | animeTitle: $(el).find('div > a').attr('title'),
610 | imgUrl: $(el).find('div > a > img').attr('src'),
611 | status: $(el).find('p.released').html().trim(),
612 | });
613 | });
614 |
615 | return list;
616 | } catch (err) {
617 | console.log(err);
618 | return { error: err };
619 | }
620 | };
621 |
622 | export const scrapeThread = async ({ episodeId, page = 0 }) => {
623 | try {
624 | let threadId = null;
625 |
626 | const thread_page = await axios.get(disqus_iframe(decodeURIComponent(episodeId)));
627 | const $ = cheerio.load(thread_page.data, { xmlMode: true });
628 |
629 | const thread = JSON.parse($('#disqus-threadData')[0].children[0].data);
630 |
631 | if (thread.code === 0 && thread.cursor.total > 0) {
632 | threadId = thread.response.thread.id;
633 | }
634 |
635 | const thread_api_res = (await axios.get(disqus_api(threadId, page))).data;
636 |
637 | return {
638 | threadId: threadId,
639 | currentPage: page,
640 | hasNextPage: thread_api_res.cursor.hasNext,
641 | comments: thread_api_res.response,
642 | };
643 | } catch (err) {
644 | if (err.response.status === 400) {
645 | return { error: 'Invalid page. Try again.' };
646 | }
647 | return { error: err };
648 | }
649 | };
650 |
651 |
652 | export const scrapeWatchAnime = async ({ id }) => {
653 | try {
654 | let genres = [];
655 | let epList = [];
656 |
657 | const WatchAnime = await axios.get(`https://anitaku.pe/${id}`);
658 |
659 | const $ = cheerio.load(WatchAnime.data);
660 |
661 | const anime_category = $('div.anime-info a').attr('href').replace('/category/', '')
662 | const episode_page = $('ul#episode_page').html()
663 | const movie_id = $('#movie_id').attr('value');
664 | const alias = $('#alias_anime').attr('value');
665 | const episode_link = $('div.play-video > iframe').attr('src')
666 | const gogoserver = $('li.vidcdn > a').attr('data-video')
667 | const streamsb = $('li.streamsb > a').attr('data-video')
668 | const xstreamcdn = $('li.xstreamcdn > a').attr('data-video')
669 | const anime_name_with_ep = $('div.title_name h2').text()
670 | const ep_num = $('div.anime_video_body > input.default_ep').attr('value')
671 | const download = $('li.dowloads a').attr('href')
672 | const nextEpText = $('div.anime_video_body_episodes_r a').text()
673 | const nextEpLink = $('div.anime_video_body_episodes_r > a').attr('href')
674 | const prevEpText = $('div.anime_video_body_episodes_l a').text()
675 | const prevEpLink = $('div.anime_video_body_episodes_l > a').attr('href')
676 |
677 | return {
678 | video: episode_link,
679 | gogoserver: gogoserver,
680 | streamsb: streamsb,
681 | xstreamcdn: xstreamcdn,
682 | animeNameWithEP: anime_name_with_ep.toString(),
683 | ep_num: ep_num,
684 | ep_download: download,
685 | anime_info: anime_category,
686 | movie_id: movie_id,
687 | alias: alias,
688 | episode_page: episode_page,
689 | nextEpText: nextEpText,
690 | nextEpLink: nextEpLink,
691 | prevEpLink: prevEpLink,
692 | prevEpText: prevEpText,
693 |
694 | };
695 | } catch (err) {
696 | console.log(err);
697 | return { error: err };
698 | }
699 | };
700 |
701 | export const scrapeSearchPage = async ({ keyw, page }) => {
702 | try {
703 | const SearchPage = await axios.get(`${BASE_URL2 + search_path}?keyword=${keyw}&page=${page}`);
704 |
705 | const $ = cheerio.load(SearchPage.data);
706 |
707 | const pagination = $('ul.pagination-list').html()
708 |
709 | return {
710 | pagination: pagination.replace("selected", "active"),
711 | }
712 | } catch (err) {
713 | console.log(err);
714 | return { error: err };
715 | }
716 | };
717 |
718 | export const scrapePopularPage = async ({ page }) => {
719 | try {
720 | const PopularPage = await axios.get(`${BASE_URL2}/popular.html?page=${page}`);
721 |
722 | const $ = cheerio.load(PopularPage.data);
723 |
724 | const pagination = $('ul.pagination-list').html()
725 |
726 | return {
727 | pagination: pagination.replace("selected", "active"),
728 | }
729 | } catch (err) {
730 | console.log(err);
731 | return { error: err };
732 | }
733 | };
734 |
735 | export const scrapeCompletedPage = async ({ page }) => {
736 | try {
737 | const CompletedPage = await axios.get(`${BASE_URL2}/completed-anime.html?page=${page}`);
738 |
739 | const $ = cheerio.load(CompletedPage.data);
740 |
741 | const pagination = $('ul.pagination-list').html()
742 |
743 | return {
744 | pagination: pagination.replace("selected", "active"),
745 | }
746 | } catch (err) {
747 | console.log(err);
748 | return { error: err };
749 | }
750 | };
751 |
752 | export const scrapeOngoingPage = async ({ page }) => {
753 | try {
754 | const OngoingPage = await axios.get(`${BASE_URL2}/ongoing-anime.html?page=${page}`);
755 |
756 | const $ = cheerio.load(OngoingPage.data);
757 |
758 | const pagination = $('ul.pagination-list').html()
759 |
760 | return {
761 | pagination: pagination.replace("selected", "active"),
762 | }
763 | } catch (err) {
764 | console.log(err);
765 | return { error: err };
766 | }
767 | };
768 |
769 | export const scrapeMoviePage = async ({ page }) => {
770 | try {
771 | const MoviePage = await axios.get(`${BASE_URL2}/anime-movies.html?aph=&page=${page}`);
772 |
773 | const $ = cheerio.load(MoviePage.data);
774 |
775 | const pagination = $('ul.pagination-list').html()
776 |
777 | return {
778 | pagination: pagination.replace("selected", "active"),
779 | }
780 | } catch (err) {
781 | console.log(err);
782 | return { error: err };
783 | }
784 | };
785 |
786 |
787 | export const scrapeSubCategoryPage = async ({ subCategory, page }) => {
788 | try {
789 | const SubCategoryPage = await axios.get(`${BASE_URL2}/sub-category/${subCategory}?page=${page}`);
790 |
791 | const $ = cheerio.load(SubCategoryPage.data);
792 |
793 | const pagination = $('ul.pagination-list').html()
794 |
795 | return {
796 | pagination: pagination.replace("selected", "active"),
797 | }
798 | } catch (err) {
799 | console.log(err);
800 | return { error: err };
801 | }
802 | };
803 |
804 | export const scrapeRecentPage = async ({ page, type }) => {
805 | try {
806 | const RecentPage = await axios.get(`${recent_release_url}?page=${page}&type=${type}`);
807 |
808 | const $ = cheerio.load(RecentPage.data);
809 |
810 | const pagination = $('ul.pagination-list').html()
811 |
812 | return {
813 | pagination: pagination.replace("selected", "active"),
814 | }
815 | } catch (err) {
816 | console.log(err);
817 | return { error: err };
818 | }
819 | };
820 |
821 | export const scrapeNewSeasonPage = async ({ page }) => {
822 | try {
823 | const NewSeasonPage = await axios.get(`${BASE_URL2}/new-season.html?page=${page}`);
824 |
825 | const $ = cheerio.load(NewSeasonPage.data);
826 |
827 | const pagination = $('ul.pagination-list').html()
828 |
829 | return {
830 | pagination: pagination.replace("selected", "active"),
831 | }
832 | } catch (err) {
833 | console.log(err);
834 | return { error: err };
835 | }
836 | };
837 |
838 | export const scrapeGenrePage = async ({ genre, page }) => {
839 | try {
840 | const GenrePage = await axios.get(`${BASE_URL2}/genre/${genre}?page=${page}`);
841 |
842 | const $ = cheerio.load(GenrePage.data);
843 |
844 | const pagination = $('ul.pagination-list').html()
845 |
846 | return {
847 | pagination: pagination.replace("selected", "active"),
848 | }
849 | } catch (err) {
850 | console.log(err);
851 | return { error: err };
852 | }
853 | };
854 |
855 | export const scrapeAnimeListPage = async ({ page }) => {
856 | try {
857 | const AnimeListPage = await axios.get(`${BASE_URL2}/anime-list.html?page=${page}`);
858 |
859 | const $ = cheerio.load(AnimeListPage.data);
860 |
861 | const pagination = $('ul.pagination-list').html()
862 |
863 | return {
864 | pagination: pagination.replace("selected", "active"),
865 | }
866 | } catch (err) {
867 | console.log(err);
868 | return { error: err };
869 | }
870 | };
871 |
872 | export const scrapeAnimeAZPage = async ({ aph, page = 1 }) => {
873 | try {
874 | const AnimeAZPage = await axios.get(`${BASE_URL2}/anime-list-${aph}?page=${page}`);
875 |
876 | const $ = cheerio.load(AnimeAZPage.data);
877 |
878 | const pagination = $('ul.pagination-list').html()
879 |
880 | return {
881 | pagination: pagination.replace("selected", "active"),
882 | }
883 | } catch (err) {
884 | console.log(err);
885 | return { error: err };
886 | }
887 | };
888 |
--------------------------------------------------------------------------------
/lib/api.js:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import cors from 'cors';
3 | import axios from 'axios';
4 |
5 | import {
6 | scrapeGenre,
7 | scrapeTopAiringAnime,
8 | scrapeAnimeMovies,
9 | scrapePopularAnime,
10 | scrapeRecentPage,
11 | scrapeOngoingSeries,
12 | scrapeAnimeList,
13 | scrapeRecentlyAdded,
14 | scrapeAnimeAZ,
15 | scrapeAnimeAZPage,
16 | scrapeNewSeason,
17 | scrapeAnimeListPage,
18 | scrapeMoviePage,
19 | scrapeGenrePage,
20 | scrapeSubCategoryPage,
21 | scrapeRecentRelease,
22 | scrapeOngoingAnime,
23 | scrapeNewSeasonPage,
24 | scrapeSearch,
25 | scrapePopularPage,
26 | scrapeSearchPage,
27 | scrapeAnimeDetails,
28 | scrapeOngoingPage,
29 | scrapeCompletedPage,
30 | scrapeSeason,
31 | scrapeCompletedAnime,
32 | scrapeMP4,
33 | scrapeStreamSB,
34 | scrapeWatchAnime,
35 | scrapeFembed,
36 | scrapeThread,
37 | DownloadReferer,
38 | } from './anime_parser.js';
39 |
40 | const port = process.env.PORT || 3000;
41 |
42 | const corsOptions = {
43 | origin: '*',
44 | credentails: true,
45 | optionSuccessStatus: 200,
46 | port: port,
47 | };
48 |
49 | const app = express();
50 |
51 | app.use(cors(corsOptions));
52 | app.use(express.json());
53 |
54 | app.get('/', (req, res) => {
55 | res.status(200).json('WORKING');
56 | });
57 |
58 | app.get('/search', async (req, res) => {
59 | try {
60 | const keyw = req.query.keyw;
61 | const page = req.query.page;
62 |
63 | if (!keyw) {
64 | return res.status(400).json({
65 | status: 400,
66 | error: 'Bad Request',
67 | message: 'Missing query parameter: keyw',
68 | });
69 | }
70 |
71 | const data = await scrapeSearch({ keyw: keyw, page: page });
72 |
73 | res.status(200).json(data);
74 | } catch (err) {
75 | res.status(500).json({
76 | status: 500,
77 | error: 'Internal Error',
78 | message: err,
79 | });
80 | }
81 | });
82 |
83 | app.get('/getRecentlyAdded', async (req, res) => {
84 | try {
85 | const page = req.query.page;
86 | const data = await scrapeRecentlyAdded({ page: page });
87 |
88 | res.status(200).json(data);
89 | } catch (err) {
90 | res.status(500).json({
91 | status: 500,
92 | error: 'Internal Error',
93 | message: err,
94 | });
95 | }
96 | });
97 |
98 | app.get('/getOngoingSeries', async (req, res) => {
99 | try {
100 | const page = req.query.page;
101 | const data = await scrapeOngoingSeries({ page: page });
102 |
103 | res.status(200).json(data);
104 | } catch (err) {
105 | res.status(500).json({
106 | status: 500,
107 | error: 'Internal Error',
108 | message: err,
109 | });
110 | }
111 | });
112 |
113 |
114 | app.get('/searchPage', async (req, res) => {
115 | try {
116 | const keyw = req.query.keyw;
117 | const page = req.query.page;
118 |
119 | if (!keyw) {
120 | return res.status(400).json({
121 | status: 400,
122 | error: 'Bad Request',
123 | message: 'Missing query parameter: keyw',
124 | });
125 | }
126 |
127 | const data = await scrapeSearchPage({ keyw: keyw, page: page });
128 |
129 | res.status(200).json(data);
130 | } catch (err) {
131 | res.status(500).json({
132 | status: 500,
133 | error: 'Internal Error',
134 | message: err,
135 | });
136 | }
137 | });
138 |
139 | app.get('/genrePage', async (req, res) => {
140 | try {
141 | const genre = req.query.genre;
142 | const page = req.query.page;
143 |
144 | if (!genre) {
145 | return res.status(400).json({
146 | status: 400,
147 | error: 'Bad Request',
148 | message: 'Missing query parameter: genre. etc: Fantasy',
149 | });
150 | }
151 |
152 | const data = await scrapeGenrePage({ genre: genre, page: page });
153 |
154 | res.status(200).json(data);
155 | } catch (err) {
156 | res.status(500).json({
157 | status: 500,
158 | error: 'Internal Error',
159 | message: err,
160 | });
161 | }
162 | });
163 |
164 | app.get('/anime-AZ-page', async (req, res) => {
165 | try {
166 | const aph = req.query.aph
167 | const page = req.query.page;
168 |
169 | if (!aph) {
170 | return res.status(400).json({
171 | status: 400,
172 | error: 'Bad Request',
173 | message: 'Missing query parameter: aph. etc: A',
174 | });
175 | }
176 |
177 | const data = await scrapeAnimeAZPage({ aph: aph, page: page });
178 |
179 | res.status(200).json(data);
180 | } catch (err) {
181 | res.status(500).json({
182 | status: 500,
183 | error: 'Internal Error',
184 | message: err,
185 | });
186 | }
187 | });
188 |
189 | app.get('/anime-list-page', async (req, res) => {
190 | try {
191 | const page = req.query.page;
192 |
193 | const data = await scrapeAnimeListPage({ page: page });
194 |
195 | res.status(200).json(data);
196 | } catch (err) {
197 | res.status(500).json({
198 | status: 500,
199 | error: 'Internal Error',
200 | message: err,
201 | });
202 | }
203 | });
204 |
205 | app.get('/animeList', async (req, res) => { //Todo: Fix
206 | try {
207 | const page = req.query.page;
208 |
209 | const data = await scrapeAnimeList({ page: page });
210 |
211 | res.status(200).json(data);
212 | } catch (err) {
213 | res.status(500).json({
214 | status: 500,
215 | error: 'Internal Error',
216 | message: err,
217 | });
218 | }
219 | });
220 |
221 | app.get('/animeListAZ', async (req, res) => {
222 | try {
223 | const aph = req.query.aph;
224 | const page = req.query.page;
225 |
226 | if (!aph) {
227 | return res.status(400).json({
228 | status: 400,
229 | error: 'Bad Request',
230 | message: 'Missing query parameter: aph. etc: A',
231 | });
232 | }
233 |
234 | const data = await scrapeAnimeAZ({ aph: aph, page: page });
235 |
236 | res.status(200).json(data);
237 | } catch (err) {
238 | res.status(500).json({
239 | status: 500,
240 | error: 'Internal Error',
241 | message: err,
242 | });
243 | }
244 | });
245 |
246 | app.get('/popularPage', async (req, res) => {
247 | try {
248 | const page = req.query.page;
249 |
250 | const data = await scrapePopularPage({ page: page });
251 |
252 | res.status(200).json(data);
253 | } catch (err) {
254 | res.status(500).json({
255 | status: 500,
256 | error: 'Internal Error',
257 | message: err,
258 | });
259 | }
260 | });
261 |
262 | app.get('/newSeasonPage', async (req, res) => {
263 | try {
264 | const page = req.query.page;
265 |
266 | const data = await scrapeNewSeasonPage({ page: page });
267 |
268 | res.status(200).json(data);
269 | } catch (err) {
270 | res.status(500).json({
271 | status: 500,
272 | error: 'Internal Error',
273 | message: err,
274 | });
275 | }
276 | });
277 |
278 | app.get('/completedPage', async (req, res) => {
279 | try {
280 | const page = req.query.page;
281 |
282 | const data = await scrapeCompletedPage({ page: page });
283 |
284 | res.status(200).json(data);
285 | } catch (err) {
286 | res.status(500).json({
287 | status: 500,
288 | error: 'Internal Error',
289 | message: err,
290 | });
291 | }
292 | });
293 |
294 | app.get('/ongoingPage', async (req, res) => {
295 | try {
296 | const page = req.query.page;
297 |
298 | const data = await scrapeOngoingPage({ page: page });
299 |
300 | res.status(200).json(data);
301 | } catch (err) {
302 | res.status(500).json({
303 | status: 500,
304 | error: 'Internal Error',
305 | message: err,
306 | });
307 | }
308 | });
309 |
310 | app.get('/moviePage', async (req, res) => {
311 | try {
312 | const page = req.query.page;
313 |
314 | const data = await scrapeMoviePage({ page: page });
315 |
316 | res.status(200).json(data);
317 | } catch (err) {
318 | res.status(500).json({
319 | status: 500,
320 | error: 'Internal Error',
321 | message: err,
322 | });
323 | }
324 | });
325 |
326 | app.get('/subCategoryPage', async (req, res) => { //ToDo: Fix
327 | try {
328 | const page = req.query.page;
329 | const subCategory = req.query.subCategory;
330 |
331 | const data = await scrapeSubCategoryPage({ page: page, subCategory: subCategory });
332 |
333 | res.status(200).json(data);
334 | } catch (err) {
335 | res.status(500).json({
336 | status: 500,
337 | error: 'Internal Error',
338 | message: err,
339 | });
340 | }
341 | });
342 |
343 | app.get('/recent-release-page', async (req, res) => {
344 | try {
345 | const page = req.query.page;
346 | const type = req.query.type;
347 |
348 | const data = await scrapeRecentPage({ page: page, type: type });
349 |
350 | res.status(200).json(data);
351 | } catch (err) {
352 | res.status(500).json({
353 | status: 500,
354 | error: 'Internal Error',
355 | message: err,
356 | });
357 | }
358 | });
359 |
360 | app.get('/recent-release', async (req, res) => {
361 | try {
362 | const page = req.query.page;
363 | const type = req.query.type;
364 |
365 | if (!page) {
366 | return res.status(400).json({
367 | status: 400,
368 | error: 'Bad Request',
369 | message: 'Missing query parameter: page',
370 | });
371 | }
372 |
373 | if (!type) {
374 | return res.status(400).json({
375 | status: 400,
376 | error: 'Bad Request',
377 | message: 'Missing query parameter: type. 1 = SUB, 2 = DUB',
378 | });
379 | }
380 |
381 | const data = await scrapeRecentRelease({ page: page, type: type });
382 |
383 | res.status(200).json(data);
384 | } catch (err) {
385 | res.status(500).json({
386 | status: 500,
387 | error: 'Internal Error',
388 | message: err,
389 | });
390 | }
391 | });
392 |
393 | app.get('/new-season', async (req, res) => {
394 | try {
395 | const page = req.query.page;
396 |
397 | const data = await scrapeNewSeason({ page: page });
398 |
399 | res.status(200).json(data);
400 | } catch (err) {
401 | res.status(500).json({
402 | status: 500,
403 | error: 'Internal Error',
404 | message: err,
405 | });
406 | }
407 | });
408 |
409 | app.get('/ongoing-anime', async (req, res) => {
410 | try {
411 | const page = req.query.page;
412 |
413 | const data = await scrapeOngoingAnime({ page: page });
414 |
415 | res.status(200).json(data);
416 | } catch (err) {
417 | res.status(500).json({
418 | status: 500,
419 | error: 'Internal Error',
420 | message: err,
421 | });
422 | }
423 | });
424 |
425 | app.get('/completed-anime', async (req, res) => {
426 | try {
427 | const page = req.query.page;
428 |
429 | const data = await scrapeCompletedAnime({ page: page });
430 |
431 | res.status(200).json(data);
432 | } catch (err) {
433 | res.status(500).json({
434 | status: 500,
435 | error: 'Internal Error',
436 | message: err,
437 | });
438 | }
439 | });
440 |
441 |
442 | app.get('/popular', async (req, res) => {
443 | try {
444 | const page = req.query.page;
445 |
446 | const data = await scrapePopularAnime({ page: page });
447 |
448 | res.status(200).json(data);
449 | } catch (err) {
450 | res.status(500).json({
451 | status: 500,
452 | error: 'Internal Error',
453 | message: err,
454 | });
455 | }
456 | });
457 |
458 | app.get('/anime-movies', async (req, res) => {
459 | try {
460 | const page = req.query.page;
461 | const alphabet = req.query.aph;
462 |
463 | const data = await scrapeAnimeMovies({ page: page, aph: alphabet });
464 |
465 | res.status(200).json(data);
466 | } catch (err) {
467 | res.status(500).send({
468 | status: 500,
469 | error: 'Internal Error',
470 | message: err,
471 | });
472 | }
473 | });
474 |
475 | app.get('/top-airing', async (req, res) => {
476 | try {
477 | const page = req.query.page;
478 |
479 | const data = await scrapeTopAiringAnime({ page: page });
480 |
481 | res.status(200).json(data);
482 | } catch (err) {
483 | res.status(500).send({
484 | status: 500,
485 | error: 'Internal Error',
486 | message: err,
487 | });
488 | }
489 | });
490 |
491 | app.get('/season/:season', async (req, res) => {
492 | try {
493 | const page = req.query.page;
494 | const season = req.params.season;
495 |
496 | const data = await scrapeSeason({ page: page, season: season });
497 |
498 | res.status(200).json(data);
499 | } catch (err) {
500 | res.status(500).send({
501 | status: 500,
502 | error: 'Internal Error',
503 | message: err, php
504 | });
505 | }
506 | });
507 |
508 | app.get('/genre/:genre', async (req, res) => {
509 | try {
510 | const genre = req.params.genre;
511 | const page = req.query.page;
512 |
513 | const data = await scrapeGenre({ genre: genre, page: page });
514 |
515 | res.status(200).json(data);
516 | } catch (err) {
517 | res.status(500).send({
518 | status: 500,
519 | error: 'Internal Error',
520 | message: err,
521 | });
522 | }
523 | });
524 |
525 | app.get('/getAnime/:id', async (req, res) => {
526 | try {
527 | const id = req.params.id;
528 |
529 | const data = await scrapeAnimeDetails({ id: id });
530 |
531 | res.status(200).json(data);
532 | } catch (err) {
533 | res.status(500).json({
534 | status: 500,
535 | error: 'Internal Error',
536 | message: err,
537 | });
538 | }
539 | });
540 |
541 | app.get('/fembed/watch/:id', async (req, res) => {
542 | try {
543 | const id = req.params.id;
544 |
545 | //const data = await scrapeFembed({ id: id });
546 |
547 | res.status(410).json({ message: 'Deprecated' });
548 | } catch (err) {
549 | res.status(500).json({
550 | status: 500,
551 | error: 'Internal Error',
552 | message: err,
553 | });
554 | }
555 | });
556 |
557 |
558 | app.get('/getEpisode/:id', async (req, res) => {
559 | try {
560 | const id = req.params.id;
561 |
562 | const data = await scrapeWatchAnime({ id: id });
563 |
564 | res.status(200).json(data);
565 | } catch (err) {
566 | res.status(500).json({
567 | status: 500,
568 | error: 'Internal Error',
569 | message: err,
570 | });
571 | }
572 | });
573 |
574 |
575 |
576 |
577 | app.get('/vidcdn/watch/:id', async (req, res) => {
578 | try {
579 | const id = req.params.id;
580 |
581 | const data = await scrapeMP4({ id: id });
582 |
583 | res.status(200).json(data);
584 | } catch (err) {
585 | res.status(500).json({
586 | status: 500,
587 | error: 'Internal Error',
588 | message: err,
589 | });
590 | }
591 | });
592 |
593 |
594 | app.get('/streamsb/watch/:id', async (req, res) => {
595 | try {
596 | const id = req.params.id;
597 |
598 | const data = await scrapeStreamSB({ id: id });
599 |
600 | res.status(200).json(data);
601 | } catch (err) {
602 | res.status(500).json({
603 | status: 500,
604 | error: 'Internal Error',
605 | message: err,
606 | });
607 | }
608 | });
609 |
610 | app.get('/thread/:episodeId', async (req, res) => {
611 | try {
612 | const episodeId = req.params.episodeId;
613 | const page = req.query.page;
614 |
615 | const data = await scrapeThread({ episodeId: episodeId, page: page });
616 |
617 | res.status(200).json(data);
618 | } catch (err) {
619 | res.status(500).json({
620 | status: 500,
621 | error: 'Internal Error',
622 | message: err,
623 | });
624 | }
625 | });
626 |
627 | app.get('/download-links/:episodeId', async (req, res) => {
628 | try {
629 | const episodeId = req.params.episodeId;
630 |
631 | //const data = await scrapeDownloadLinks({ episodeId: episodeId });
632 |
633 | res.status(410).json({ message: 'Deprecated' });
634 | } catch (err) {
635 | console.log(err);
636 | res.status(500).json({
637 | status: 500,
638 | error: 'Internal Error',
639 | message: err,
640 | });
641 | }
642 | });
643 |
644 | app.get('/download', async (req, res) => {
645 | try {
646 | const downloadLink = req.rawHeaders.find(
647 | (x) => x.includes('https://') && x.includes('.mp4')
648 | );
649 |
650 | if (!downloadLink) {
651 | return res.status(400).json({
652 | error: 'No downloadLink provided. Make sure to add the downloadLink in the headers.',
653 | });
654 | }
655 |
656 | await axios
657 | .get(downloadLink, {
658 | headers: { Referer: DownloadReferer },
659 | responseType: 'stream',
660 | })
661 | .then((stream) => {
662 | return new Promise((r, j) => {
663 | res.writeHead(200, {
664 | ...stream.headers,
665 | });
666 | stream.data.pipe(res);
667 | });
668 | });
669 |
670 | return res.status(200).json('Done Downloading.');
671 | } catch (err) {
672 | console.log(err);
673 | res.status(500).json({
674 | status: 500,
675 | error: 'Internal Error',
676 | message: err,
677 | });
678 | }
679 | });
680 |
681 | app.use((req, res) => {
682 | res.status(404).json({
683 | status: 404,
684 | error: 'Not Found',
685 | });
686 | });
687 |
688 |
689 |
690 |
691 | app.listen(port, () => {
692 | console.log('Express server listening on port %d in %s mode', port, app.settings.env);
693 | });
--------------------------------------------------------------------------------
/lib/helpers/extractors/fembed.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | export const extractFembed = async(url) => {
4 | try {
5 | url = new URL(url);
6 | const fembedApiUrl = url.href.replace('/v/', '/api/source/');
7 | const res = await axios.post(fembedApiUrl, {
8 | headers: {
9 | Referer: url.href,
10 | },
11 | });
12 |
13 | if (!res.data.success) return false;
14 |
15 | return {
16 | headers: {
17 | Referer: url.href,
18 | },
19 | data: res.data.data,
20 | };
21 | } catch (e) {
22 | return { error: 'No sources found!! Try different source\n\n' + e.message };
23 | }
24 | };
--------------------------------------------------------------------------------
/lib/helpers/extractors/goload.js:
--------------------------------------------------------------------------------
1 | import CryptoJS from 'crypto-js';
2 |
3 | const keys = {
4 | key: CryptoJS.enc.Utf8.parse('37911490979715163134003223491201'),
5 | second_key: CryptoJS.enc.Utf8.parse('54674138327930866480207815084989'),
6 | iv: CryptoJS.enc.Utf8.parse('3134003223491201'),
7 | };
8 |
9 | /**
10 | * Parses the embedded video URL to encrypt-ajax.php parameters
11 | * @param {cheerio} $ Cheerio object of the embedded video page
12 | * @param {string} id Id of the embedded video URL
13 | */
14 | export async function generateEncryptAjaxParameters($, id) {
15 | // encrypt the key
16 | const encrypted_key = CryptoJS.AES['encrypt'](id, keys.key, {
17 | iv: keys.iv,
18 | });
19 |
20 | const script = $("script[data-name='episode']").data().value;
21 | const token = CryptoJS.AES['decrypt'](script, keys.key, {
22 | iv: keys.iv,
23 | }).toString(CryptoJS.enc.Utf8);
24 |
25 | return 'id=' + encrypted_key + '&alias=' + id + '&' + token;
26 | }
27 | /**
28 | * Decrypts the encrypted-ajax.php response
29 | * @param {object} obj Response from the server
30 | */
31 | export function decryptEncryptAjaxResponse(obj) {
32 | const decrypted = CryptoJS.enc.Utf8.stringify(
33 | CryptoJS.AES.decrypt(obj.data, keys.second_key, {
34 | iv: keys.iv,
35 | })
36 | );
37 | return JSON.parse(decrypted);
38 | }
39 |
--------------------------------------------------------------------------------
/lib/helpers/extractors/streamsb.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | import { USER_AGENT } from '../../utils.js';
4 |
5 | const HOST = 'https://sbplay2.com/sources43';
6 |
7 | const PAYLOAD = (hex) =>
8 | `7361696b6f757c7c${hex}7c7c7361696b6f757c7c73747265616d7362/7361696b6f757c7c363136653639366436343663363136653639366436343663376337633631366536393664363436633631366536393664363436633763376336313665363936643634366336313665363936643634366337633763373337343732363536313664373336327c7c7361696b6f757c7c73747265616d7362`;
9 |
10 | export const extractStreamSB = async(url) => {
11 | url = new URL(url);
12 |
13 | const id = url.href.split('/e/').pop();
14 | let arrBytes = new TextEncoder().encode(id);
15 |
16 | const res = await axios.get(`${HOST}/${PAYLOAD(toHexString(Array.from(arrBytes)))}`, {
17 | headers: { watchsb: 'streamsb', 'User-Agent': USER_AGENT },
18 | });
19 |
20 | return res.data;
21 | };
22 |
23 | function toHexString(byteArray) {
24 | return Array.from(byteArray, function(byte) {
25 | return ('0' + (byte & 0xff).toString(16)).slice(-2);
26 | }).join('');
27 | }
--------------------------------------------------------------------------------
/lib/helpers/random.js:
--------------------------------------------------------------------------------
1 | function getRandomInt(min, max) {
2 | min = Math.ceil(min);
3 | max = Math.floor(max);
4 | return Math.floor(Math.random() * (max - min + 1)) + min;
5 | }
6 |
7 | function f_random(length) {
8 | var i = length,
9 | str = '';
10 | while (i > 0x0) {
11 | i--, (str += getRandomInt(0, 9));
12 | }
13 | return str;
14 | }
--------------------------------------------------------------------------------
/lib/types/index.d.ts:
--------------------------------------------------------------------------------
1 | export type AnimeList = {
2 | animeId?: string;
3 | animeTitle?: string;
4 | animeUrl?: string;
5 | animeImg?: string;
6 | status?: string;
7 | };
8 |
9 | export type GogoEpisode = {
10 | episodeId?: string;
11 | episodeNum?: number | string;
12 | episodeUrl?: string;
13 | };
14 |
15 | export type Gogoanime = {
16 | animeId?: string;
17 | type?: string;
18 | animeTitle?: string;
19 | animeImg?: string;
20 | status?: string;
21 | genres?: string[];
22 | otherNames?: string[] | string;
23 | synopsis?: string;
24 | totalEpisodes?: number | string;
25 | episodesList?: GogoEpisode[];
26 | };
27 |
28 | /**
29 | * @typedef {Object} AnimeList
30 | * @param {AnimeList[]} list out put of the anime list
31 | * @param {string} keyw query keyword to search
32 | * @param {string} page current page
33 | */
34 | export declare function scrapeSearch(
35 | list: AnimeList[] | null | undefined,
36 | keyw: string,
37 | page: number = 1
38 | ): Promise;
39 |
40 | /**
41 | *
42 | * @param animeId anime id to scrape the anime info
43 | * @returns {Gogoanime} anime info object
44 | */
45 | export declare function scrapeAnimeDetails(
46 | animeId: string
47 | ): Promise;
48 |
49 | // TODO: add more functions
50 |
--------------------------------------------------------------------------------
/lib/utils.js:
--------------------------------------------------------------------------------
1 | export const USER_AGENT =
2 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36';
3 | export const renameKey = (obj, oldKey, newKey) => {
4 | if (!obj.hasOwnProperty(oldKey)) return;
5 | const oldValue = obj[oldKey];
6 | delete obj[oldKey];
7 | obj[newKey] = oldValue;
8 | };
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gogoanime-api",
3 | "version": "1.0.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "gogoanime-api",
9 | "version": "1.0.0",
10 | "license": "ISC",
11 | "dependencies": {
12 | "axios": "^0.27.2",
13 | "cheerio": "^1.0.0-rc.10",
14 | "cors": "^2.8.5",
15 | "crypto-js": "^4.1.1",
16 | "express": "^4.17.1"
17 | },
18 | "devDependencies": {
19 | "nodemon": "^2.0.22"
20 | }
21 | },
22 | "node_modules/abbrev": {
23 | "version": "1.1.1",
24 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
25 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
26 | "dev": true
27 | },
28 | "node_modules/accepts": {
29 | "version": "1.3.8",
30 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
31 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
32 | "dependencies": {
33 | "mime-types": "~2.1.34",
34 | "negotiator": "0.6.3"
35 | },
36 | "engines": {
37 | "node": ">= 0.6"
38 | }
39 | },
40 | "node_modules/anymatch": {
41 | "version": "3.1.2",
42 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
43 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
44 | "dev": true,
45 | "dependencies": {
46 | "normalize-path": "^3.0.0",
47 | "picomatch": "^2.0.4"
48 | },
49 | "engines": {
50 | "node": ">= 8"
51 | }
52 | },
53 | "node_modules/array-flatten": {
54 | "version": "1.1.1",
55 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
56 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
57 | },
58 | "node_modules/asynckit": {
59 | "version": "0.4.0",
60 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
61 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
62 | },
63 | "node_modules/axios": {
64 | "version": "0.27.2",
65 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
66 | "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
67 | "dependencies": {
68 | "follow-redirects": "^1.14.9",
69 | "form-data": "^4.0.0"
70 | }
71 | },
72 | "node_modules/balanced-match": {
73 | "version": "1.0.2",
74 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
75 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
76 | "dev": true
77 | },
78 | "node_modules/binary-extensions": {
79 | "version": "2.2.0",
80 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
81 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
82 | "dev": true,
83 | "engines": {
84 | "node": ">=8"
85 | }
86 | },
87 | "node_modules/body-parser": {
88 | "version": "1.20.0",
89 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
90 | "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
91 | "dependencies": {
92 | "bytes": "3.1.2",
93 | "content-type": "~1.0.4",
94 | "debug": "2.6.9",
95 | "depd": "2.0.0",
96 | "destroy": "1.2.0",
97 | "http-errors": "2.0.0",
98 | "iconv-lite": "0.4.24",
99 | "on-finished": "2.4.1",
100 | "qs": "6.10.3",
101 | "raw-body": "2.5.1",
102 | "type-is": "~1.6.18",
103 | "unpipe": "1.0.0"
104 | },
105 | "engines": {
106 | "node": ">= 0.8",
107 | "npm": "1.2.8000 || >= 1.4.16"
108 | }
109 | },
110 | "node_modules/boolbase": {
111 | "version": "1.0.0",
112 | "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
113 | "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
114 | },
115 | "node_modules/brace-expansion": {
116 | "version": "1.1.11",
117 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
118 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
119 | "dev": true,
120 | "dependencies": {
121 | "balanced-match": "^1.0.0",
122 | "concat-map": "0.0.1"
123 | }
124 | },
125 | "node_modules/braces": {
126 | "version": "3.0.2",
127 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
128 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
129 | "dev": true,
130 | "dependencies": {
131 | "fill-range": "^7.0.1"
132 | },
133 | "engines": {
134 | "node": ">=8"
135 | }
136 | },
137 | "node_modules/bytes": {
138 | "version": "3.1.2",
139 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
140 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
141 | "engines": {
142 | "node": ">= 0.8"
143 | }
144 | },
145 | "node_modules/call-bind": {
146 | "version": "1.0.2",
147 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
148 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
149 | "dependencies": {
150 | "function-bind": "^1.1.1",
151 | "get-intrinsic": "^1.0.2"
152 | },
153 | "funding": {
154 | "url": "https://github.com/sponsors/ljharb"
155 | }
156 | },
157 | "node_modules/cheerio": {
158 | "version": "1.0.0-rc.12",
159 | "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
160 | "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
161 | "dependencies": {
162 | "cheerio-select": "^2.1.0",
163 | "dom-serializer": "^2.0.0",
164 | "domhandler": "^5.0.3",
165 | "domutils": "^3.0.1",
166 | "htmlparser2": "^8.0.1",
167 | "parse5": "^7.0.0",
168 | "parse5-htmlparser2-tree-adapter": "^7.0.0"
169 | },
170 | "engines": {
171 | "node": ">= 6"
172 | },
173 | "funding": {
174 | "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
175 | }
176 | },
177 | "node_modules/cheerio-select": {
178 | "version": "2.1.0",
179 | "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
180 | "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
181 | "dependencies": {
182 | "boolbase": "^1.0.0",
183 | "css-select": "^5.1.0",
184 | "css-what": "^6.1.0",
185 | "domelementtype": "^2.3.0",
186 | "domhandler": "^5.0.3",
187 | "domutils": "^3.0.1"
188 | },
189 | "funding": {
190 | "url": "https://github.com/sponsors/fb55"
191 | }
192 | },
193 | "node_modules/chokidar": {
194 | "version": "3.5.2",
195 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
196 | "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
197 | "dev": true,
198 | "dependencies": {
199 | "anymatch": "~3.1.2",
200 | "braces": "~3.0.2",
201 | "glob-parent": "~5.1.2",
202 | "is-binary-path": "~2.1.0",
203 | "is-glob": "~4.0.1",
204 | "normalize-path": "~3.0.0",
205 | "readdirp": "~3.6.0"
206 | },
207 | "engines": {
208 | "node": ">= 8.10.0"
209 | },
210 | "optionalDependencies": {
211 | "fsevents": "~2.3.2"
212 | }
213 | },
214 | "node_modules/combined-stream": {
215 | "version": "1.0.8",
216 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
217 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
218 | "dependencies": {
219 | "delayed-stream": "~1.0.0"
220 | },
221 | "engines": {
222 | "node": ">= 0.8"
223 | }
224 | },
225 | "node_modules/concat-map": {
226 | "version": "0.0.1",
227 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
228 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
229 | "dev": true
230 | },
231 | "node_modules/content-disposition": {
232 | "version": "0.5.4",
233 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
234 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
235 | "dependencies": {
236 | "safe-buffer": "5.2.1"
237 | },
238 | "engines": {
239 | "node": ">= 0.6"
240 | }
241 | },
242 | "node_modules/content-type": {
243 | "version": "1.0.4",
244 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
245 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
246 | "engines": {
247 | "node": ">= 0.6"
248 | }
249 | },
250 | "node_modules/cookie": {
251 | "version": "0.5.0",
252 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
253 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
254 | "engines": {
255 | "node": ">= 0.6"
256 | }
257 | },
258 | "node_modules/cookie-signature": {
259 | "version": "1.0.6",
260 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
261 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
262 | },
263 | "node_modules/cors": {
264 | "version": "2.8.5",
265 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
266 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
267 | "dependencies": {
268 | "object-assign": "^4",
269 | "vary": "^1"
270 | },
271 | "engines": {
272 | "node": ">= 0.10"
273 | }
274 | },
275 | "node_modules/crypto-js": {
276 | "version": "4.1.1",
277 | "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
278 | "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
279 | },
280 | "node_modules/css-select": {
281 | "version": "5.1.0",
282 | "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
283 | "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
284 | "dependencies": {
285 | "boolbase": "^1.0.0",
286 | "css-what": "^6.1.0",
287 | "domhandler": "^5.0.2",
288 | "domutils": "^3.0.1",
289 | "nth-check": "^2.0.1"
290 | },
291 | "funding": {
292 | "url": "https://github.com/sponsors/fb55"
293 | }
294 | },
295 | "node_modules/css-what": {
296 | "version": "6.1.0",
297 | "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
298 | "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
299 | "engines": {
300 | "node": ">= 6"
301 | },
302 | "funding": {
303 | "url": "https://github.com/sponsors/fb55"
304 | }
305 | },
306 | "node_modules/debug": {
307 | "version": "2.6.9",
308 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
309 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
310 | "dependencies": {
311 | "ms": "2.0.0"
312 | }
313 | },
314 | "node_modules/delayed-stream": {
315 | "version": "1.0.0",
316 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
317 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
318 | "engines": {
319 | "node": ">=0.4.0"
320 | }
321 | },
322 | "node_modules/depd": {
323 | "version": "2.0.0",
324 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
325 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
326 | "engines": {
327 | "node": ">= 0.8"
328 | }
329 | },
330 | "node_modules/destroy": {
331 | "version": "1.2.0",
332 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
333 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
334 | "engines": {
335 | "node": ">= 0.8",
336 | "npm": "1.2.8000 || >= 1.4.16"
337 | }
338 | },
339 | "node_modules/dom-serializer": {
340 | "version": "2.0.0",
341 | "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
342 | "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
343 | "dependencies": {
344 | "domelementtype": "^2.3.0",
345 | "domhandler": "^5.0.2",
346 | "entities": "^4.2.0"
347 | },
348 | "funding": {
349 | "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
350 | }
351 | },
352 | "node_modules/domelementtype": {
353 | "version": "2.3.0",
354 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
355 | "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
356 | "funding": [
357 | {
358 | "type": "github",
359 | "url": "https://github.com/sponsors/fb55"
360 | }
361 | ]
362 | },
363 | "node_modules/domhandler": {
364 | "version": "5.0.3",
365 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
366 | "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
367 | "dependencies": {
368 | "domelementtype": "^2.3.0"
369 | },
370 | "engines": {
371 | "node": ">= 4"
372 | },
373 | "funding": {
374 | "url": "https://github.com/fb55/domhandler?sponsor=1"
375 | }
376 | },
377 | "node_modules/domutils": {
378 | "version": "3.0.1",
379 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
380 | "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
381 | "dependencies": {
382 | "dom-serializer": "^2.0.0",
383 | "domelementtype": "^2.3.0",
384 | "domhandler": "^5.0.1"
385 | },
386 | "funding": {
387 | "url": "https://github.com/fb55/domutils?sponsor=1"
388 | }
389 | },
390 | "node_modules/ee-first": {
391 | "version": "1.1.1",
392 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
393 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
394 | },
395 | "node_modules/encodeurl": {
396 | "version": "1.0.2",
397 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
398 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
399 | "engines": {
400 | "node": ">= 0.8"
401 | }
402 | },
403 | "node_modules/entities": {
404 | "version": "4.3.0",
405 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
406 | "integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==",
407 | "engines": {
408 | "node": ">=0.12"
409 | },
410 | "funding": {
411 | "url": "https://github.com/fb55/entities?sponsor=1"
412 | }
413 | },
414 | "node_modules/escape-html": {
415 | "version": "1.0.3",
416 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
417 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
418 | },
419 | "node_modules/etag": {
420 | "version": "1.8.1",
421 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
422 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
423 | "engines": {
424 | "node": ">= 0.6"
425 | }
426 | },
427 | "node_modules/express": {
428 | "version": "4.18.1",
429 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
430 | "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
431 | "dependencies": {
432 | "accepts": "~1.3.8",
433 | "array-flatten": "1.1.1",
434 | "body-parser": "1.20.0",
435 | "content-disposition": "0.5.4",
436 | "content-type": "~1.0.4",
437 | "cookie": "0.5.0",
438 | "cookie-signature": "1.0.6",
439 | "debug": "2.6.9",
440 | "depd": "2.0.0",
441 | "encodeurl": "~1.0.2",
442 | "escape-html": "~1.0.3",
443 | "etag": "~1.8.1",
444 | "finalhandler": "1.2.0",
445 | "fresh": "0.5.2",
446 | "http-errors": "2.0.0",
447 | "merge-descriptors": "1.0.1",
448 | "methods": "~1.1.2",
449 | "on-finished": "2.4.1",
450 | "parseurl": "~1.3.3",
451 | "path-to-regexp": "0.1.7",
452 | "proxy-addr": "~2.0.7",
453 | "qs": "6.10.3",
454 | "range-parser": "~1.2.1",
455 | "safe-buffer": "5.2.1",
456 | "send": "0.18.0",
457 | "serve-static": "1.15.0",
458 | "setprototypeof": "1.2.0",
459 | "statuses": "2.0.1",
460 | "type-is": "~1.6.18",
461 | "utils-merge": "1.0.1",
462 | "vary": "~1.1.2"
463 | },
464 | "engines": {
465 | "node": ">= 0.10.0"
466 | }
467 | },
468 | "node_modules/fill-range": {
469 | "version": "7.0.1",
470 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
471 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
472 | "dev": true,
473 | "dependencies": {
474 | "to-regex-range": "^5.0.1"
475 | },
476 | "engines": {
477 | "node": ">=8"
478 | }
479 | },
480 | "node_modules/finalhandler": {
481 | "version": "1.2.0",
482 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
483 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
484 | "dependencies": {
485 | "debug": "2.6.9",
486 | "encodeurl": "~1.0.2",
487 | "escape-html": "~1.0.3",
488 | "on-finished": "2.4.1",
489 | "parseurl": "~1.3.3",
490 | "statuses": "2.0.1",
491 | "unpipe": "~1.0.0"
492 | },
493 | "engines": {
494 | "node": ">= 0.8"
495 | }
496 | },
497 | "node_modules/follow-redirects": {
498 | "version": "1.15.1",
499 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
500 | "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
501 | "funding": [
502 | {
503 | "type": "individual",
504 | "url": "https://github.com/sponsors/RubenVerborgh"
505 | }
506 | ],
507 | "engines": {
508 | "node": ">=4.0"
509 | },
510 | "peerDependenciesMeta": {
511 | "debug": {
512 | "optional": true
513 | }
514 | }
515 | },
516 | "node_modules/form-data": {
517 | "version": "4.0.0",
518 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
519 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
520 | "dependencies": {
521 | "asynckit": "^0.4.0",
522 | "combined-stream": "^1.0.8",
523 | "mime-types": "^2.1.12"
524 | },
525 | "engines": {
526 | "node": ">= 6"
527 | }
528 | },
529 | "node_modules/forwarded": {
530 | "version": "0.2.0",
531 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
532 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
533 | "engines": {
534 | "node": ">= 0.6"
535 | }
536 | },
537 | "node_modules/fresh": {
538 | "version": "0.5.2",
539 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
540 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
541 | "engines": {
542 | "node": ">= 0.6"
543 | }
544 | },
545 | "node_modules/fsevents": {
546 | "version": "2.3.2",
547 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
548 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
549 | "dev": true,
550 | "hasInstallScript": true,
551 | "optional": true,
552 | "os": [
553 | "darwin"
554 | ],
555 | "engines": {
556 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
557 | }
558 | },
559 | "node_modules/function-bind": {
560 | "version": "1.1.1",
561 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
562 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
563 | },
564 | "node_modules/get-intrinsic": {
565 | "version": "1.1.2",
566 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
567 | "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
568 | "dependencies": {
569 | "function-bind": "^1.1.1",
570 | "has": "^1.0.3",
571 | "has-symbols": "^1.0.3"
572 | },
573 | "funding": {
574 | "url": "https://github.com/sponsors/ljharb"
575 | }
576 | },
577 | "node_modules/glob-parent": {
578 | "version": "5.1.2",
579 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
580 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
581 | "dev": true,
582 | "dependencies": {
583 | "is-glob": "^4.0.1"
584 | },
585 | "engines": {
586 | "node": ">= 6"
587 | }
588 | },
589 | "node_modules/has": {
590 | "version": "1.0.3",
591 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
592 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
593 | "dependencies": {
594 | "function-bind": "^1.1.1"
595 | },
596 | "engines": {
597 | "node": ">= 0.4.0"
598 | }
599 | },
600 | "node_modules/has-flag": {
601 | "version": "3.0.0",
602 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
603 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
604 | "dev": true,
605 | "engines": {
606 | "node": ">=4"
607 | }
608 | },
609 | "node_modules/has-symbols": {
610 | "version": "1.0.3",
611 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
612 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
613 | "engines": {
614 | "node": ">= 0.4"
615 | },
616 | "funding": {
617 | "url": "https://github.com/sponsors/ljharb"
618 | }
619 | },
620 | "node_modules/htmlparser2": {
621 | "version": "8.0.1",
622 | "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
623 | "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
624 | "funding": [
625 | "https://github.com/fb55/htmlparser2?sponsor=1",
626 | {
627 | "type": "github",
628 | "url": "https://github.com/sponsors/fb55"
629 | }
630 | ],
631 | "dependencies": {
632 | "domelementtype": "^2.3.0",
633 | "domhandler": "^5.0.2",
634 | "domutils": "^3.0.1",
635 | "entities": "^4.3.0"
636 | }
637 | },
638 | "node_modules/http-errors": {
639 | "version": "2.0.0",
640 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
641 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
642 | "dependencies": {
643 | "depd": "2.0.0",
644 | "inherits": "2.0.4",
645 | "setprototypeof": "1.2.0",
646 | "statuses": "2.0.1",
647 | "toidentifier": "1.0.1"
648 | },
649 | "engines": {
650 | "node": ">= 0.8"
651 | }
652 | },
653 | "node_modules/iconv-lite": {
654 | "version": "0.4.24",
655 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
656 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
657 | "dependencies": {
658 | "safer-buffer": ">= 2.1.2 < 3"
659 | },
660 | "engines": {
661 | "node": ">=0.10.0"
662 | }
663 | },
664 | "node_modules/ignore-by-default": {
665 | "version": "1.0.1",
666 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
667 | "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=",
668 | "dev": true
669 | },
670 | "node_modules/inherits": {
671 | "version": "2.0.4",
672 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
673 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
674 | },
675 | "node_modules/ipaddr.js": {
676 | "version": "1.9.1",
677 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
678 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
679 | "engines": {
680 | "node": ">= 0.10"
681 | }
682 | },
683 | "node_modules/is-binary-path": {
684 | "version": "2.1.0",
685 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
686 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
687 | "dev": true,
688 | "dependencies": {
689 | "binary-extensions": "^2.0.0"
690 | },
691 | "engines": {
692 | "node": ">=8"
693 | }
694 | },
695 | "node_modules/is-extglob": {
696 | "version": "2.1.1",
697 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
698 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
699 | "dev": true,
700 | "engines": {
701 | "node": ">=0.10.0"
702 | }
703 | },
704 | "node_modules/is-glob": {
705 | "version": "4.0.3",
706 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
707 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
708 | "dev": true,
709 | "dependencies": {
710 | "is-extglob": "^2.1.1"
711 | },
712 | "engines": {
713 | "node": ">=0.10.0"
714 | }
715 | },
716 | "node_modules/is-number": {
717 | "version": "7.0.0",
718 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
719 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
720 | "dev": true,
721 | "engines": {
722 | "node": ">=0.12.0"
723 | }
724 | },
725 | "node_modules/media-typer": {
726 | "version": "0.3.0",
727 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
728 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
729 | "engines": {
730 | "node": ">= 0.6"
731 | }
732 | },
733 | "node_modules/merge-descriptors": {
734 | "version": "1.0.1",
735 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
736 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
737 | },
738 | "node_modules/methods": {
739 | "version": "1.1.2",
740 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
741 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
742 | "engines": {
743 | "node": ">= 0.6"
744 | }
745 | },
746 | "node_modules/mime": {
747 | "version": "1.6.0",
748 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
749 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
750 | "bin": {
751 | "mime": "cli.js"
752 | },
753 | "engines": {
754 | "node": ">=4"
755 | }
756 | },
757 | "node_modules/mime-db": {
758 | "version": "1.52.0",
759 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
760 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
761 | "engines": {
762 | "node": ">= 0.6"
763 | }
764 | },
765 | "node_modules/mime-types": {
766 | "version": "2.1.35",
767 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
768 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
769 | "dependencies": {
770 | "mime-db": "1.52.0"
771 | },
772 | "engines": {
773 | "node": ">= 0.6"
774 | }
775 | },
776 | "node_modules/minimatch": {
777 | "version": "3.1.2",
778 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
779 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
780 | "dev": true,
781 | "dependencies": {
782 | "brace-expansion": "^1.1.7"
783 | },
784 | "engines": {
785 | "node": "*"
786 | }
787 | },
788 | "node_modules/ms": {
789 | "version": "2.0.0",
790 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
791 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
792 | },
793 | "node_modules/negotiator": {
794 | "version": "0.6.3",
795 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
796 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
797 | "engines": {
798 | "node": ">= 0.6"
799 | }
800 | },
801 | "node_modules/nodemon": {
802 | "version": "2.0.22",
803 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
804 | "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==",
805 | "dev": true,
806 | "dependencies": {
807 | "chokidar": "^3.5.2",
808 | "debug": "^3.2.7",
809 | "ignore-by-default": "^1.0.1",
810 | "minimatch": "^3.1.2",
811 | "pstree.remy": "^1.1.8",
812 | "semver": "^5.7.1",
813 | "simple-update-notifier": "^1.0.7",
814 | "supports-color": "^5.5.0",
815 | "touch": "^3.1.0",
816 | "undefsafe": "^2.0.5"
817 | },
818 | "bin": {
819 | "nodemon": "bin/nodemon.js"
820 | },
821 | "engines": {
822 | "node": ">=8.10.0"
823 | },
824 | "funding": {
825 | "type": "opencollective",
826 | "url": "https://opencollective.com/nodemon"
827 | }
828 | },
829 | "node_modules/nodemon/node_modules/debug": {
830 | "version": "3.2.7",
831 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
832 | "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
833 | "dev": true,
834 | "dependencies": {
835 | "ms": "^2.1.1"
836 | }
837 | },
838 | "node_modules/nodemon/node_modules/ms": {
839 | "version": "2.1.3",
840 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
841 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
842 | "dev": true
843 | },
844 | "node_modules/nopt": {
845 | "version": "1.0.10",
846 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
847 | "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
848 | "dev": true,
849 | "dependencies": {
850 | "abbrev": "1"
851 | },
852 | "bin": {
853 | "nopt": "bin/nopt.js"
854 | },
855 | "engines": {
856 | "node": "*"
857 | }
858 | },
859 | "node_modules/normalize-path": {
860 | "version": "3.0.0",
861 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
862 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
863 | "dev": true,
864 | "engines": {
865 | "node": ">=0.10.0"
866 | }
867 | },
868 | "node_modules/nth-check": {
869 | "version": "2.1.1",
870 | "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
871 | "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
872 | "dependencies": {
873 | "boolbase": "^1.0.0"
874 | },
875 | "funding": {
876 | "url": "https://github.com/fb55/nth-check?sponsor=1"
877 | }
878 | },
879 | "node_modules/object-assign": {
880 | "version": "4.1.1",
881 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
882 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
883 | "engines": {
884 | "node": ">=0.10.0"
885 | }
886 | },
887 | "node_modules/object-inspect": {
888 | "version": "1.12.2",
889 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
890 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
891 | "funding": {
892 | "url": "https://github.com/sponsors/ljharb"
893 | }
894 | },
895 | "node_modules/on-finished": {
896 | "version": "2.4.1",
897 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
898 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
899 | "dependencies": {
900 | "ee-first": "1.1.1"
901 | },
902 | "engines": {
903 | "node": ">= 0.8"
904 | }
905 | },
906 | "node_modules/parse5": {
907 | "version": "7.0.0",
908 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz",
909 | "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==",
910 | "dependencies": {
911 | "entities": "^4.3.0"
912 | },
913 | "funding": {
914 | "url": "https://github.com/inikulin/parse5?sponsor=1"
915 | }
916 | },
917 | "node_modules/parse5-htmlparser2-tree-adapter": {
918 | "version": "7.0.0",
919 | "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
920 | "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
921 | "dependencies": {
922 | "domhandler": "^5.0.2",
923 | "parse5": "^7.0.0"
924 | },
925 | "funding": {
926 | "url": "https://github.com/inikulin/parse5?sponsor=1"
927 | }
928 | },
929 | "node_modules/parseurl": {
930 | "version": "1.3.3",
931 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
932 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
933 | "engines": {
934 | "node": ">= 0.8"
935 | }
936 | },
937 | "node_modules/path-to-regexp": {
938 | "version": "0.1.7",
939 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
940 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
941 | },
942 | "node_modules/picomatch": {
943 | "version": "2.3.0",
944 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
945 | "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
946 | "dev": true,
947 | "engines": {
948 | "node": ">=8.6"
949 | },
950 | "funding": {
951 | "url": "https://github.com/sponsors/jonschlinkert"
952 | }
953 | },
954 | "node_modules/proxy-addr": {
955 | "version": "2.0.7",
956 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
957 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
958 | "dependencies": {
959 | "forwarded": "0.2.0",
960 | "ipaddr.js": "1.9.1"
961 | },
962 | "engines": {
963 | "node": ">= 0.10"
964 | }
965 | },
966 | "node_modules/pstree.remy": {
967 | "version": "1.1.8",
968 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
969 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
970 | "dev": true
971 | },
972 | "node_modules/qs": {
973 | "version": "6.10.3",
974 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
975 | "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
976 | "dependencies": {
977 | "side-channel": "^1.0.4"
978 | },
979 | "engines": {
980 | "node": ">=0.6"
981 | },
982 | "funding": {
983 | "url": "https://github.com/sponsors/ljharb"
984 | }
985 | },
986 | "node_modules/range-parser": {
987 | "version": "1.2.1",
988 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
989 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
990 | "engines": {
991 | "node": ">= 0.6"
992 | }
993 | },
994 | "node_modules/raw-body": {
995 | "version": "2.5.1",
996 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
997 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
998 | "dependencies": {
999 | "bytes": "3.1.2",
1000 | "http-errors": "2.0.0",
1001 | "iconv-lite": "0.4.24",
1002 | "unpipe": "1.0.0"
1003 | },
1004 | "engines": {
1005 | "node": ">= 0.8"
1006 | }
1007 | },
1008 | "node_modules/readdirp": {
1009 | "version": "3.6.0",
1010 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
1011 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
1012 | "dev": true,
1013 | "dependencies": {
1014 | "picomatch": "^2.2.1"
1015 | },
1016 | "engines": {
1017 | "node": ">=8.10.0"
1018 | }
1019 | },
1020 | "node_modules/safe-buffer": {
1021 | "version": "5.2.1",
1022 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1023 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
1024 | "funding": [
1025 | {
1026 | "type": "github",
1027 | "url": "https://github.com/sponsors/feross"
1028 | },
1029 | {
1030 | "type": "patreon",
1031 | "url": "https://www.patreon.com/feross"
1032 | },
1033 | {
1034 | "type": "consulting",
1035 | "url": "https://feross.org/support"
1036 | }
1037 | ]
1038 | },
1039 | "node_modules/safer-buffer": {
1040 | "version": "2.1.2",
1041 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1042 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1043 | },
1044 | "node_modules/semver": {
1045 | "version": "5.7.1",
1046 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
1047 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
1048 | "dev": true,
1049 | "bin": {
1050 | "semver": "bin/semver"
1051 | }
1052 | },
1053 | "node_modules/send": {
1054 | "version": "0.18.0",
1055 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
1056 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
1057 | "dependencies": {
1058 | "debug": "2.6.9",
1059 | "depd": "2.0.0",
1060 | "destroy": "1.2.0",
1061 | "encodeurl": "~1.0.2",
1062 | "escape-html": "~1.0.3",
1063 | "etag": "~1.8.1",
1064 | "fresh": "0.5.2",
1065 | "http-errors": "2.0.0",
1066 | "mime": "1.6.0",
1067 | "ms": "2.1.3",
1068 | "on-finished": "2.4.1",
1069 | "range-parser": "~1.2.1",
1070 | "statuses": "2.0.1"
1071 | },
1072 | "engines": {
1073 | "node": ">= 0.8.0"
1074 | }
1075 | },
1076 | "node_modules/send/node_modules/ms": {
1077 | "version": "2.1.3",
1078 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1079 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
1080 | },
1081 | "node_modules/serve-static": {
1082 | "version": "1.15.0",
1083 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
1084 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
1085 | "dependencies": {
1086 | "encodeurl": "~1.0.2",
1087 | "escape-html": "~1.0.3",
1088 | "parseurl": "~1.3.3",
1089 | "send": "0.18.0"
1090 | },
1091 | "engines": {
1092 | "node": ">= 0.8.0"
1093 | }
1094 | },
1095 | "node_modules/setprototypeof": {
1096 | "version": "1.2.0",
1097 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1098 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
1099 | },
1100 | "node_modules/side-channel": {
1101 | "version": "1.0.4",
1102 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
1103 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
1104 | "dependencies": {
1105 | "call-bind": "^1.0.0",
1106 | "get-intrinsic": "^1.0.2",
1107 | "object-inspect": "^1.9.0"
1108 | },
1109 | "funding": {
1110 | "url": "https://github.com/sponsors/ljharb"
1111 | }
1112 | },
1113 | "node_modules/simple-update-notifier": {
1114 | "version": "1.0.7",
1115 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz",
1116 | "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==",
1117 | "dev": true,
1118 | "dependencies": {
1119 | "semver": "~7.0.0"
1120 | },
1121 | "engines": {
1122 | "node": ">=8.10.0"
1123 | }
1124 | },
1125 | "node_modules/simple-update-notifier/node_modules/semver": {
1126 | "version": "7.0.0",
1127 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
1128 | "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
1129 | "dev": true,
1130 | "bin": {
1131 | "semver": "bin/semver.js"
1132 | }
1133 | },
1134 | "node_modules/statuses": {
1135 | "version": "2.0.1",
1136 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
1137 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
1138 | "engines": {
1139 | "node": ">= 0.8"
1140 | }
1141 | },
1142 | "node_modules/supports-color": {
1143 | "version": "5.5.0",
1144 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1145 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1146 | "dev": true,
1147 | "dependencies": {
1148 | "has-flag": "^3.0.0"
1149 | },
1150 | "engines": {
1151 | "node": ">=4"
1152 | }
1153 | },
1154 | "node_modules/to-regex-range": {
1155 | "version": "5.0.1",
1156 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1157 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1158 | "dev": true,
1159 | "dependencies": {
1160 | "is-number": "^7.0.0"
1161 | },
1162 | "engines": {
1163 | "node": ">=8.0"
1164 | }
1165 | },
1166 | "node_modules/toidentifier": {
1167 | "version": "1.0.1",
1168 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1169 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1170 | "engines": {
1171 | "node": ">=0.6"
1172 | }
1173 | },
1174 | "node_modules/touch": {
1175 | "version": "3.1.0",
1176 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
1177 | "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
1178 | "dev": true,
1179 | "dependencies": {
1180 | "nopt": "~1.0.10"
1181 | },
1182 | "bin": {
1183 | "nodetouch": "bin/nodetouch.js"
1184 | }
1185 | },
1186 | "node_modules/type-is": {
1187 | "version": "1.6.18",
1188 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
1189 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
1190 | "dependencies": {
1191 | "media-typer": "0.3.0",
1192 | "mime-types": "~2.1.24"
1193 | },
1194 | "engines": {
1195 | "node": ">= 0.6"
1196 | }
1197 | },
1198 | "node_modules/undefsafe": {
1199 | "version": "2.0.5",
1200 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
1201 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
1202 | "dev": true
1203 | },
1204 | "node_modules/unpipe": {
1205 | "version": "1.0.0",
1206 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1207 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1208 | "engines": {
1209 | "node": ">= 0.8"
1210 | }
1211 | },
1212 | "node_modules/utils-merge": {
1213 | "version": "1.0.1",
1214 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
1215 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
1216 | "engines": {
1217 | "node": ">= 0.4.0"
1218 | }
1219 | },
1220 | "node_modules/vary": {
1221 | "version": "1.1.2",
1222 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
1223 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
1224 | "engines": {
1225 | "node": ">= 0.8"
1226 | }
1227 | }
1228 | },
1229 | "dependencies": {
1230 | "abbrev": {
1231 | "version": "1.1.1",
1232 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
1233 | "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
1234 | "dev": true
1235 | },
1236 | "accepts": {
1237 | "version": "1.3.8",
1238 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
1239 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
1240 | "requires": {
1241 | "mime-types": "~2.1.34",
1242 | "negotiator": "0.6.3"
1243 | }
1244 | },
1245 | "anymatch": {
1246 | "version": "3.1.2",
1247 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
1248 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
1249 | "dev": true,
1250 | "requires": {
1251 | "normalize-path": "^3.0.0",
1252 | "picomatch": "^2.0.4"
1253 | }
1254 | },
1255 | "array-flatten": {
1256 | "version": "1.1.1",
1257 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
1258 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
1259 | },
1260 | "asynckit": {
1261 | "version": "0.4.0",
1262 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
1263 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
1264 | },
1265 | "axios": {
1266 | "version": "0.27.2",
1267 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
1268 | "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
1269 | "requires": {
1270 | "follow-redirects": "^1.14.9",
1271 | "form-data": "^4.0.0"
1272 | }
1273 | },
1274 | "balanced-match": {
1275 | "version": "1.0.2",
1276 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
1277 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
1278 | "dev": true
1279 | },
1280 | "binary-extensions": {
1281 | "version": "2.2.0",
1282 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
1283 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
1284 | "dev": true
1285 | },
1286 | "body-parser": {
1287 | "version": "1.20.0",
1288 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
1289 | "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
1290 | "requires": {
1291 | "bytes": "3.1.2",
1292 | "content-type": "~1.0.4",
1293 | "debug": "2.6.9",
1294 | "depd": "2.0.0",
1295 | "destroy": "1.2.0",
1296 | "http-errors": "2.0.0",
1297 | "iconv-lite": "0.4.24",
1298 | "on-finished": "2.4.1",
1299 | "qs": "6.10.3",
1300 | "raw-body": "2.5.1",
1301 | "type-is": "~1.6.18",
1302 | "unpipe": "1.0.0"
1303 | }
1304 | },
1305 | "boolbase": {
1306 | "version": "1.0.0",
1307 | "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
1308 | "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
1309 | },
1310 | "brace-expansion": {
1311 | "version": "1.1.11",
1312 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
1313 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
1314 | "dev": true,
1315 | "requires": {
1316 | "balanced-match": "^1.0.0",
1317 | "concat-map": "0.0.1"
1318 | }
1319 | },
1320 | "braces": {
1321 | "version": "3.0.2",
1322 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
1323 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
1324 | "dev": true,
1325 | "requires": {
1326 | "fill-range": "^7.0.1"
1327 | }
1328 | },
1329 | "bytes": {
1330 | "version": "3.1.2",
1331 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
1332 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
1333 | },
1334 | "call-bind": {
1335 | "version": "1.0.2",
1336 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
1337 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
1338 | "requires": {
1339 | "function-bind": "^1.1.1",
1340 | "get-intrinsic": "^1.0.2"
1341 | }
1342 | },
1343 | "cheerio": {
1344 | "version": "1.0.0-rc.12",
1345 | "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
1346 | "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
1347 | "requires": {
1348 | "cheerio-select": "^2.1.0",
1349 | "dom-serializer": "^2.0.0",
1350 | "domhandler": "^5.0.3",
1351 | "domutils": "^3.0.1",
1352 | "htmlparser2": "^8.0.1",
1353 | "parse5": "^7.0.0",
1354 | "parse5-htmlparser2-tree-adapter": "^7.0.0"
1355 | }
1356 | },
1357 | "cheerio-select": {
1358 | "version": "2.1.0",
1359 | "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
1360 | "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
1361 | "requires": {
1362 | "boolbase": "^1.0.0",
1363 | "css-select": "^5.1.0",
1364 | "css-what": "^6.1.0",
1365 | "domelementtype": "^2.3.0",
1366 | "domhandler": "^5.0.3",
1367 | "domutils": "^3.0.1"
1368 | }
1369 | },
1370 | "chokidar": {
1371 | "version": "3.5.2",
1372 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
1373 | "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
1374 | "dev": true,
1375 | "requires": {
1376 | "anymatch": "~3.1.2",
1377 | "braces": "~3.0.2",
1378 | "fsevents": "~2.3.2",
1379 | "glob-parent": "~5.1.2",
1380 | "is-binary-path": "~2.1.0",
1381 | "is-glob": "~4.0.1",
1382 | "normalize-path": "~3.0.0",
1383 | "readdirp": "~3.6.0"
1384 | }
1385 | },
1386 | "combined-stream": {
1387 | "version": "1.0.8",
1388 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
1389 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
1390 | "requires": {
1391 | "delayed-stream": "~1.0.0"
1392 | }
1393 | },
1394 | "concat-map": {
1395 | "version": "0.0.1",
1396 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
1397 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
1398 | "dev": true
1399 | },
1400 | "content-disposition": {
1401 | "version": "0.5.4",
1402 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
1403 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
1404 | "requires": {
1405 | "safe-buffer": "5.2.1"
1406 | }
1407 | },
1408 | "content-type": {
1409 | "version": "1.0.4",
1410 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
1411 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
1412 | },
1413 | "cookie": {
1414 | "version": "0.5.0",
1415 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
1416 | "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="
1417 | },
1418 | "cookie-signature": {
1419 | "version": "1.0.6",
1420 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
1421 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
1422 | },
1423 | "cors": {
1424 | "version": "2.8.5",
1425 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
1426 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
1427 | "requires": {
1428 | "object-assign": "^4",
1429 | "vary": "^1"
1430 | }
1431 | },
1432 | "crypto-js": {
1433 | "version": "4.1.1",
1434 | "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.1.1.tgz",
1435 | "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw=="
1436 | },
1437 | "css-select": {
1438 | "version": "5.1.0",
1439 | "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
1440 | "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
1441 | "requires": {
1442 | "boolbase": "^1.0.0",
1443 | "css-what": "^6.1.0",
1444 | "domhandler": "^5.0.2",
1445 | "domutils": "^3.0.1",
1446 | "nth-check": "^2.0.1"
1447 | }
1448 | },
1449 | "css-what": {
1450 | "version": "6.1.0",
1451 | "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
1452 | "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="
1453 | },
1454 | "debug": {
1455 | "version": "2.6.9",
1456 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
1457 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
1458 | "requires": {
1459 | "ms": "2.0.0"
1460 | }
1461 | },
1462 | "delayed-stream": {
1463 | "version": "1.0.0",
1464 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
1465 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
1466 | },
1467 | "depd": {
1468 | "version": "2.0.0",
1469 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
1470 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
1471 | },
1472 | "destroy": {
1473 | "version": "1.2.0",
1474 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
1475 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
1476 | },
1477 | "dom-serializer": {
1478 | "version": "2.0.0",
1479 | "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
1480 | "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
1481 | "requires": {
1482 | "domelementtype": "^2.3.0",
1483 | "domhandler": "^5.0.2",
1484 | "entities": "^4.2.0"
1485 | }
1486 | },
1487 | "domelementtype": {
1488 | "version": "2.3.0",
1489 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
1490 | "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
1491 | },
1492 | "domhandler": {
1493 | "version": "5.0.3",
1494 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
1495 | "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
1496 | "requires": {
1497 | "domelementtype": "^2.3.0"
1498 | }
1499 | },
1500 | "domutils": {
1501 | "version": "3.0.1",
1502 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
1503 | "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
1504 | "requires": {
1505 | "dom-serializer": "^2.0.0",
1506 | "domelementtype": "^2.3.0",
1507 | "domhandler": "^5.0.1"
1508 | }
1509 | },
1510 | "ee-first": {
1511 | "version": "1.1.1",
1512 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
1513 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
1514 | },
1515 | "encodeurl": {
1516 | "version": "1.0.2",
1517 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
1518 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
1519 | },
1520 | "entities": {
1521 | "version": "4.3.0",
1522 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
1523 | "integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg=="
1524 | },
1525 | "escape-html": {
1526 | "version": "1.0.3",
1527 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
1528 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
1529 | },
1530 | "etag": {
1531 | "version": "1.8.1",
1532 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
1533 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="
1534 | },
1535 | "express": {
1536 | "version": "4.18.1",
1537 | "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz",
1538 | "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==",
1539 | "requires": {
1540 | "accepts": "~1.3.8",
1541 | "array-flatten": "1.1.1",
1542 | "body-parser": "1.20.0",
1543 | "content-disposition": "0.5.4",
1544 | "content-type": "~1.0.4",
1545 | "cookie": "0.5.0",
1546 | "cookie-signature": "1.0.6",
1547 | "debug": "2.6.9",
1548 | "depd": "2.0.0",
1549 | "encodeurl": "~1.0.2",
1550 | "escape-html": "~1.0.3",
1551 | "etag": "~1.8.1",
1552 | "finalhandler": "1.2.0",
1553 | "fresh": "0.5.2",
1554 | "http-errors": "2.0.0",
1555 | "merge-descriptors": "1.0.1",
1556 | "methods": "~1.1.2",
1557 | "on-finished": "2.4.1",
1558 | "parseurl": "~1.3.3",
1559 | "path-to-regexp": "0.1.7",
1560 | "proxy-addr": "~2.0.7",
1561 | "qs": "6.10.3",
1562 | "range-parser": "~1.2.1",
1563 | "safe-buffer": "5.2.1",
1564 | "send": "0.18.0",
1565 | "serve-static": "1.15.0",
1566 | "setprototypeof": "1.2.0",
1567 | "statuses": "2.0.1",
1568 | "type-is": "~1.6.18",
1569 | "utils-merge": "1.0.1",
1570 | "vary": "~1.1.2"
1571 | }
1572 | },
1573 | "fill-range": {
1574 | "version": "7.0.1",
1575 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
1576 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
1577 | "dev": true,
1578 | "requires": {
1579 | "to-regex-range": "^5.0.1"
1580 | }
1581 | },
1582 | "finalhandler": {
1583 | "version": "1.2.0",
1584 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz",
1585 | "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==",
1586 | "requires": {
1587 | "debug": "2.6.9",
1588 | "encodeurl": "~1.0.2",
1589 | "escape-html": "~1.0.3",
1590 | "on-finished": "2.4.1",
1591 | "parseurl": "~1.3.3",
1592 | "statuses": "2.0.1",
1593 | "unpipe": "~1.0.0"
1594 | }
1595 | },
1596 | "follow-redirects": {
1597 | "version": "1.15.1",
1598 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
1599 | "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA=="
1600 | },
1601 | "form-data": {
1602 | "version": "4.0.0",
1603 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
1604 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
1605 | "requires": {
1606 | "asynckit": "^0.4.0",
1607 | "combined-stream": "^1.0.8",
1608 | "mime-types": "^2.1.12"
1609 | }
1610 | },
1611 | "forwarded": {
1612 | "version": "0.2.0",
1613 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
1614 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
1615 | },
1616 | "fresh": {
1617 | "version": "0.5.2",
1618 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
1619 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="
1620 | },
1621 | "fsevents": {
1622 | "version": "2.3.2",
1623 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
1624 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
1625 | "dev": true,
1626 | "optional": true
1627 | },
1628 | "function-bind": {
1629 | "version": "1.1.1",
1630 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
1631 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
1632 | },
1633 | "get-intrinsic": {
1634 | "version": "1.1.2",
1635 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
1636 | "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
1637 | "requires": {
1638 | "function-bind": "^1.1.1",
1639 | "has": "^1.0.3",
1640 | "has-symbols": "^1.0.3"
1641 | }
1642 | },
1643 | "glob-parent": {
1644 | "version": "5.1.2",
1645 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
1646 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
1647 | "dev": true,
1648 | "requires": {
1649 | "is-glob": "^4.0.1"
1650 | }
1651 | },
1652 | "has": {
1653 | "version": "1.0.3",
1654 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
1655 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
1656 | "requires": {
1657 | "function-bind": "^1.1.1"
1658 | }
1659 | },
1660 | "has-flag": {
1661 | "version": "3.0.0",
1662 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
1663 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
1664 | "dev": true
1665 | },
1666 | "has-symbols": {
1667 | "version": "1.0.3",
1668 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
1669 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
1670 | },
1671 | "htmlparser2": {
1672 | "version": "8.0.1",
1673 | "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
1674 | "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
1675 | "requires": {
1676 | "domelementtype": "^2.3.0",
1677 | "domhandler": "^5.0.2",
1678 | "domutils": "^3.0.1",
1679 | "entities": "^4.3.0"
1680 | }
1681 | },
1682 | "http-errors": {
1683 | "version": "2.0.0",
1684 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
1685 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
1686 | "requires": {
1687 | "depd": "2.0.0",
1688 | "inherits": "2.0.4",
1689 | "setprototypeof": "1.2.0",
1690 | "statuses": "2.0.1",
1691 | "toidentifier": "1.0.1"
1692 | }
1693 | },
1694 | "iconv-lite": {
1695 | "version": "0.4.24",
1696 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
1697 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
1698 | "requires": {
1699 | "safer-buffer": ">= 2.1.2 < 3"
1700 | }
1701 | },
1702 | "ignore-by-default": {
1703 | "version": "1.0.1",
1704 | "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
1705 | "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=",
1706 | "dev": true
1707 | },
1708 | "inherits": {
1709 | "version": "2.0.4",
1710 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1711 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
1712 | },
1713 | "ipaddr.js": {
1714 | "version": "1.9.1",
1715 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
1716 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
1717 | },
1718 | "is-binary-path": {
1719 | "version": "2.1.0",
1720 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
1721 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
1722 | "dev": true,
1723 | "requires": {
1724 | "binary-extensions": "^2.0.0"
1725 | }
1726 | },
1727 | "is-extglob": {
1728 | "version": "2.1.1",
1729 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1730 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
1731 | "dev": true
1732 | },
1733 | "is-glob": {
1734 | "version": "4.0.3",
1735 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
1736 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
1737 | "dev": true,
1738 | "requires": {
1739 | "is-extglob": "^2.1.1"
1740 | }
1741 | },
1742 | "is-number": {
1743 | "version": "7.0.0",
1744 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1745 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1746 | "dev": true
1747 | },
1748 | "media-typer": {
1749 | "version": "0.3.0",
1750 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
1751 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="
1752 | },
1753 | "merge-descriptors": {
1754 | "version": "1.0.1",
1755 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
1756 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
1757 | },
1758 | "methods": {
1759 | "version": "1.1.2",
1760 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
1761 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
1762 | },
1763 | "mime": {
1764 | "version": "1.6.0",
1765 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
1766 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
1767 | },
1768 | "mime-db": {
1769 | "version": "1.52.0",
1770 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1771 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
1772 | },
1773 | "mime-types": {
1774 | "version": "2.1.35",
1775 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1776 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1777 | "requires": {
1778 | "mime-db": "1.52.0"
1779 | }
1780 | },
1781 | "minimatch": {
1782 | "version": "3.1.2",
1783 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
1784 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
1785 | "dev": true,
1786 | "requires": {
1787 | "brace-expansion": "^1.1.7"
1788 | }
1789 | },
1790 | "ms": {
1791 | "version": "2.0.0",
1792 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
1793 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
1794 | },
1795 | "negotiator": {
1796 | "version": "0.6.3",
1797 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
1798 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
1799 | },
1800 | "nodemon": {
1801 | "version": "2.0.22",
1802 | "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz",
1803 | "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==",
1804 | "dev": true,
1805 | "requires": {
1806 | "chokidar": "^3.5.2",
1807 | "debug": "^3.2.7",
1808 | "ignore-by-default": "^1.0.1",
1809 | "minimatch": "^3.1.2",
1810 | "pstree.remy": "^1.1.8",
1811 | "semver": "^5.7.1",
1812 | "simple-update-notifier": "^1.0.7",
1813 | "supports-color": "^5.5.0",
1814 | "touch": "^3.1.0",
1815 | "undefsafe": "^2.0.5"
1816 | },
1817 | "dependencies": {
1818 | "debug": {
1819 | "version": "3.2.7",
1820 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
1821 | "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
1822 | "dev": true,
1823 | "requires": {
1824 | "ms": "^2.1.1"
1825 | }
1826 | },
1827 | "ms": {
1828 | "version": "2.1.3",
1829 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1830 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1831 | "dev": true
1832 | }
1833 | }
1834 | },
1835 | "nopt": {
1836 | "version": "1.0.10",
1837 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
1838 | "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
1839 | "dev": true,
1840 | "requires": {
1841 | "abbrev": "1"
1842 | }
1843 | },
1844 | "normalize-path": {
1845 | "version": "3.0.0",
1846 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1847 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1848 | "dev": true
1849 | },
1850 | "nth-check": {
1851 | "version": "2.1.1",
1852 | "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
1853 | "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
1854 | "requires": {
1855 | "boolbase": "^1.0.0"
1856 | }
1857 | },
1858 | "object-assign": {
1859 | "version": "4.1.1",
1860 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
1861 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
1862 | },
1863 | "object-inspect": {
1864 | "version": "1.12.2",
1865 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
1866 | "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
1867 | },
1868 | "on-finished": {
1869 | "version": "2.4.1",
1870 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
1871 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
1872 | "requires": {
1873 | "ee-first": "1.1.1"
1874 | }
1875 | },
1876 | "parse5": {
1877 | "version": "7.0.0",
1878 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz",
1879 | "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==",
1880 | "requires": {
1881 | "entities": "^4.3.0"
1882 | }
1883 | },
1884 | "parse5-htmlparser2-tree-adapter": {
1885 | "version": "7.0.0",
1886 | "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
1887 | "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
1888 | "requires": {
1889 | "domhandler": "^5.0.2",
1890 | "parse5": "^7.0.0"
1891 | }
1892 | },
1893 | "parseurl": {
1894 | "version": "1.3.3",
1895 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1896 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
1897 | },
1898 | "path-to-regexp": {
1899 | "version": "0.1.7",
1900 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1901 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
1902 | },
1903 | "picomatch": {
1904 | "version": "2.3.0",
1905 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
1906 | "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
1907 | "dev": true
1908 | },
1909 | "proxy-addr": {
1910 | "version": "2.0.7",
1911 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
1912 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
1913 | "requires": {
1914 | "forwarded": "0.2.0",
1915 | "ipaddr.js": "1.9.1"
1916 | }
1917 | },
1918 | "pstree.remy": {
1919 | "version": "1.1.8",
1920 | "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
1921 | "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
1922 | "dev": true
1923 | },
1924 | "qs": {
1925 | "version": "6.10.3",
1926 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
1927 | "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
1928 | "requires": {
1929 | "side-channel": "^1.0.4"
1930 | }
1931 | },
1932 | "range-parser": {
1933 | "version": "1.2.1",
1934 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
1935 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
1936 | },
1937 | "raw-body": {
1938 | "version": "2.5.1",
1939 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
1940 | "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
1941 | "requires": {
1942 | "bytes": "3.1.2",
1943 | "http-errors": "2.0.0",
1944 | "iconv-lite": "0.4.24",
1945 | "unpipe": "1.0.0"
1946 | }
1947 | },
1948 | "readdirp": {
1949 | "version": "3.6.0",
1950 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
1951 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
1952 | "dev": true,
1953 | "requires": {
1954 | "picomatch": "^2.2.1"
1955 | }
1956 | },
1957 | "safe-buffer": {
1958 | "version": "5.2.1",
1959 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
1960 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
1961 | },
1962 | "safer-buffer": {
1963 | "version": "2.1.2",
1964 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1965 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
1966 | },
1967 | "semver": {
1968 | "version": "5.7.1",
1969 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
1970 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
1971 | "dev": true
1972 | },
1973 | "send": {
1974 | "version": "0.18.0",
1975 | "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
1976 | "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==",
1977 | "requires": {
1978 | "debug": "2.6.9",
1979 | "depd": "2.0.0",
1980 | "destroy": "1.2.0",
1981 | "encodeurl": "~1.0.2",
1982 | "escape-html": "~1.0.3",
1983 | "etag": "~1.8.1",
1984 | "fresh": "0.5.2",
1985 | "http-errors": "2.0.0",
1986 | "mime": "1.6.0",
1987 | "ms": "2.1.3",
1988 | "on-finished": "2.4.1",
1989 | "range-parser": "~1.2.1",
1990 | "statuses": "2.0.1"
1991 | },
1992 | "dependencies": {
1993 | "ms": {
1994 | "version": "2.1.3",
1995 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1996 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
1997 | }
1998 | }
1999 | },
2000 | "serve-static": {
2001 | "version": "1.15.0",
2002 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz",
2003 | "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==",
2004 | "requires": {
2005 | "encodeurl": "~1.0.2",
2006 | "escape-html": "~1.0.3",
2007 | "parseurl": "~1.3.3",
2008 | "send": "0.18.0"
2009 | }
2010 | },
2011 | "setprototypeof": {
2012 | "version": "1.2.0",
2013 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
2014 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
2015 | },
2016 | "side-channel": {
2017 | "version": "1.0.4",
2018 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
2019 | "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
2020 | "requires": {
2021 | "call-bind": "^1.0.0",
2022 | "get-intrinsic": "^1.0.2",
2023 | "object-inspect": "^1.9.0"
2024 | }
2025 | },
2026 | "simple-update-notifier": {
2027 | "version": "1.0.7",
2028 | "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.0.7.tgz",
2029 | "integrity": "sha512-BBKgR84BJQJm6WjWFMHgLVuo61FBDSj1z/xSFUIozqO6wO7ii0JxCqlIud7Enr/+LhlbNI0whErq96P2qHNWew==",
2030 | "dev": true,
2031 | "requires": {
2032 | "semver": "~7.0.0"
2033 | },
2034 | "dependencies": {
2035 | "semver": {
2036 | "version": "7.0.0",
2037 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
2038 | "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
2039 | "dev": true
2040 | }
2041 | }
2042 | },
2043 | "statuses": {
2044 | "version": "2.0.1",
2045 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
2046 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
2047 | },
2048 | "supports-color": {
2049 | "version": "5.5.0",
2050 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
2051 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
2052 | "dev": true,
2053 | "requires": {
2054 | "has-flag": "^3.0.0"
2055 | }
2056 | },
2057 | "to-regex-range": {
2058 | "version": "5.0.1",
2059 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
2060 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
2061 | "dev": true,
2062 | "requires": {
2063 | "is-number": "^7.0.0"
2064 | }
2065 | },
2066 | "toidentifier": {
2067 | "version": "1.0.1",
2068 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
2069 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="
2070 | },
2071 | "touch": {
2072 | "version": "3.1.0",
2073 | "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
2074 | "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
2075 | "dev": true,
2076 | "requires": {
2077 | "nopt": "~1.0.10"
2078 | }
2079 | },
2080 | "type-is": {
2081 | "version": "1.6.18",
2082 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
2083 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
2084 | "requires": {
2085 | "media-typer": "0.3.0",
2086 | "mime-types": "~2.1.24"
2087 | }
2088 | },
2089 | "undefsafe": {
2090 | "version": "2.0.5",
2091 | "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
2092 | "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
2093 | "dev": true
2094 | },
2095 | "unpipe": {
2096 | "version": "1.0.0",
2097 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
2098 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="
2099 | },
2100 | "utils-merge": {
2101 | "version": "1.0.1",
2102 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
2103 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
2104 | },
2105 | "vary": {
2106 | "version": "1.1.2",
2107 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
2108 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
2109 | }
2110 | }
2111 | }
2112 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gogoanime-api",
3 | "version": "1.0.0",
4 | "description": "Anime Streaming, Discovery API made with Cheerio and Express. Uses data from Gogoanime",
5 | "main": "lib/anime_parser.js",
6 | "type": "module",
7 | "types": "lib/types/index.d.ts",
8 | "scripts": {
9 | "start": "node lib/api.js",
10 | "dev": "nodemon lib/api.js",
11 | "test": "echo \"Error: no test specified\" && exit 1"
12 | },
13 | "keywords": [
14 | "anime",
15 | "streaming",
16 | "discovery",
17 | "api",
18 | "gogoanime"
19 | ],
20 | "author": "https://github.com/riimuru",
21 | "license": "ISC",
22 | "dependencies": {
23 | "axios": "^0.27.2",
24 | "cheerio": "^1.0.0-rc.10",
25 | "cors": "^2.8.5",
26 | "crypto-js": "^4.1.1",
27 | "express": "^4.17.1"
28 | },
29 | "devDependencies": {
30 | "nodemon": "^2.0.22"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/render.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | - type: web
3 | name: animeapi
4 | env: docker
5 | repo: https://github.com/kirixen/gogo-api.git
6 | plan: free
7 | branch: main
8 | envVars:
9 | - key: PORT
10 | value: 3000
11 |
--------------------------------------------------------------------------------
/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "builds": [
4 | {
5 | "src": "/lib/api.js",
6 | "use": "@vercel/node"
7 | }
8 | ],
9 | "routes": [
10 | {
11 | "src": "/(.*)",
12 | "dest": "/lib/api.js"
13 | }
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------