diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index efacc6d9..496ec3e7 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -3,6 +3,12 @@ description: File a bug report! # title: "(Bug): " labels: ["bug"] body: + - type: checkboxes + attributes: + label: Have you tried to find similar open issues? + options: + - label: "Yes, this issue is not a duplicate" + required: true - type: input attributes: label: Browser diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..84bce597 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v12.18.4 \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2a65ac17..62a4e6cf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,5 @@ -Read this in other languages: [Français](CONTRIBUTINGfr.md) +Read this in other languages: [русский](CONTRIBUTINGru.md), [Nederlands](CONTRIBUTINGnl.md), [Français](CONTRIBUTINGfr.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md) + # Welcome To Return YouTube Dislikes contributing guide diff --git a/CONTRIBUTINGfr.md b/CONTRIBUTINGfr.md index 95ece722..7ceafe60 100644 --- a/CONTRIBUTINGfr.md +++ b/CONTRIBUTINGfr.md @@ -1,4 +1,6 @@ -Lisez ceci dans d'autres langues : [English](CONTRIBUTING.md) + +Lisez ceci dans d'autres langues : [English](CONTRIBUTING.md), [русский](CONTRIBUTINGru.md), Nederlands](CONTRIBUTINGnl.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md) + # Bienvenue dans le guide de contribution à Return YouTube Dislikes diff --git a/CONTRIBUTINGnl.md b/CONTRIBUTINGnl.md new file mode 100644 index 00000000..777ca5df --- /dev/null +++ b/CONTRIBUTINGnl.md @@ -0,0 +1,67 @@ +Lees dit in andere talen: [English](CONTRIBUTINGen.md), [русский](CONTRIBUTINGru.md), [Français](CONTRIBUTINGfr.md), [Türkçe](CONTRIBUTINGtr.md) + +# Welkom bij de YouTube Dislikes bijdragengids + +Bedankt voor het investeren van uw tijd in het bijdragen aan ons project! Al uw wijzigingen worden weergegeven in de volgende versie van de extensie (of de [website](https://www.returnyoutubedislike.com/)). + +## Aan de slag + +Gebruik Prettier met standaardinstellingen voor opmaak. + +#### Vereisten + +U moet node en npm hebben geïnstalleerd om de gebundelde versie van de broncode te maken. + +Versies gebruikt bij het instellen: + +- node: 12.18.4 +- npm: 6.14.6 + +Om de `bundled-content-script.js` te maken die de meeste bedrijfslogica van deze extensie bevat, moet u eerst alle afhankelijkheden installeren. + +1. Ga naar de hoofdmap van de repo en voer het volgende uit: + +``` +npm install +``` + +2. Voer de volgende opdracht uit om `bundled-content-script.js` aan te maken dat wordt gebruikt in `manifest.json` + +``` +npm start // om het (de) buildbestand(en) te maken en een bestandswachter te starten die bij het opslaan opnieuw wordt geladen + +// of + +npm run build // om het (de) buildbestand(en) eenmaal te maken +``` + +Gefeliciteerd, je bent nu klaar om te ontwikkelen! + +Als je nieuw bent in het ontwikkelen van Chrome-extensies of extra hulp nodig hebt, bekijk dan [deze YouTube-tutorial](https://www.youtube.com/watch?v=mdOj6HYE3_0) + +### Problemen + +#### Een nieuw probleem openen + +Als je problemen hebt met de extensie, zoek dan eerst of het probleem nog niet is gemeld. Als dit niet het geval is, open dan een probleem, het gebruik van het probleemformulier wordt sterk aanbevolen, maar is niet verplicht. + +#### Een probleem oplossen + +Als je een probleem hebt gevonden waarvan je denkt dat je het zou kunnen oplossen, wees dan niet verlegen. Open een PR met de oplossing en vermeld het probleem dat u aan het oplossen bent. + +### Functieverzoek: + +#### Een nieuw functieverzoek openen + +Als je een idee hebt voor de extensie, kun je een functieverzoek openen, maar zoek het eerst op om er zeker van te zijn dat de functie niet al is voorgesteld. Het gebruik van het functieformulier wordt sterk aanbevolen, maar is niet verplicht. + +#### Een functieverzoek implementeren + +Als je een functie hebt gevonden waarvan je denkt dat je die zou kunnen implementeren, wees dan niet verlegen. Open een PR met de oplossing en zorg ervoor dat u de functie vermeldt die u implementeert. + +### Welke PR's accepteren we? + +- Probleemoplossingen. +- Implementatie van functies. +- Typefouten of betere en gemakkelijkere woorden om te gebruiken. +- Website bijdragen. diff --git a/CONTRIBUTINGru.md b/CONTRIBUTINGru.md index 82b7bc1b..444edcbc 100644 --- a/CONTRIBUTINGru.md +++ b/CONTRIBUTINGru.md @@ -1,4 +1,5 @@ -Прочитать на других языках: [English](CONTRIBUTING.md) +Прочитать на других языках: [English](CONTRIBUTING.md), [Nederlands](CONTRIBUTINGnl.md), [Français](CONTRIBUTINGfr.md), [Türkçe](CONTRIBUTINGtr.md), [українська](CONTRIBUTINGuk.md) + # Добро пожаловать в руководство по внесению вклада Return YouTube Dislikes diff --git a/CONTRIBUTINGtr.md b/CONTRIBUTINGtr.md new file mode 100644 index 00000000..e41b3c59 --- /dev/null +++ b/CONTRIBUTINGtr.md @@ -0,0 +1,67 @@ +Bunu diğer dillerde okuyun: [English](CONTRIBUTING.md), [русский](CONTRIBUTINGru.md), [Nederlands](CONTRIBUTINGnl.md), [Français](CONTRIBUTINGfr.md), [українська](CONTRIBUTINGuk.md) + +# "YouTube Dislike Sayısını Geri Getir"in katkı kılavuzuna Hoş Geldiniz + +Projemize katkıda bulunmak için zaman ayırdığınız için teşekkür ederiz! Tüm değişiklikleriniz, uzantının bir sonraki sürümüne (veya [internet sitesi](https://www.returnyoutubedislike.com/)ne) yansıtılacaktır. + +## Başlarken + +Lütfen formatlama işlemi için, Prettier'i varsayılan ayarlardayken kullanın. + +#### Ön Şartlar + +Kaynağın paketlenmiş sürümünü oluşturmak için node ve npm'nin kurulu olması gerekir. + +Kurulum sırasında kullanılan sürümler: + +- node: 12.18.4 +- npm: 6.14.6 + +Bu uzantının iş mantığının çoğunu içeren `bundled-content-script.js`yi oluşturmak için, önce tüm bağımlılıkları yüklemeniz gerekir. + +1. Deponun köküne gidin ve şu komutu çalıştırın: + +``` +npm install +``` + +2. `manifest.json` içinde kullanılan `bundled-content-script.js` dosyasını oluşturmak için aşağıdaki komutu çalıştırın. + +``` +npm start // derleme dosyasının/dosyalarının oluşturulması ve kaydedilmesi sırasında çalışırken yeniden yüklenen bir dosya izleyicisini başlatmak için + +// ya da + +npm run build // derleme dosyasını/dosyalarını bir kez oluşturmak için +``` + +Tebrikler, artık geliştirmeye hazırsınız! + +Chrome uzantıları geliştirme konusunda yeniyseniz veya fazladan yardıma ihtiyacınız olursa lütfen [bu YouTube öğreticisi](https://www.youtube.com/watch?v=mdOj6HYE3_0)ne bakın. + +### Issue'lar + +#### Yeni bir issue başlatmak + +Uzantıyla ilgili herhangi bir sorununuz varsa, sorunun önceden bildirilmediğinden emin olmak için lütfen arama yapın. Eğer daha önce bildirilmediyse, bir konu açın. Sorun formunu kullanmanız şiddetle tavsiye edilir ancak zorunlu değildir. + +#### Bir issue'yu çözmek + +Çözebileceğinizi düşündüğünüz bir sorun bulduysanız, çekinmeyin. Düzeltmeyi içeren bir PR açın ve düzelttiğiniz sorunu belirttiğinizden emin olun. + +### Özellik Talebi + +#### Yeni bir özellik talebi açmak + +Uzantı hakkında bir fikriniz varsa, bir özellik isteği açmaktan çekinmeyin, ancak özelliğin daha önce önerilmediğinden emin olmak için lütfen önce arama yapın. Özellik formunun kullanılması şiddetle tavsiye edilir ancak zorunlu değildir. + +#### Bir özellik isteğini uygulamak + +Uygulayabileceğinizi düşündüğünüz bir özellik bulduysanız, çekinmeyin. Düzeltmeyi içeren bir PR açın ve uyguladığınız özelliği belirttiğinizden emin olun. + +### Hangi tür PR'leri kabul ediyoruz? + +- Sorun düzeltmeleri. +- Özellik uygulaması. +- Yazım hataları veya daha anlaşılabilir ve kullanımı daha kolay kelimeler. +- Site katkıları. diff --git a/CONTRIBUTINGuk.md b/CONTRIBUTINGuk.md new file mode 100644 index 00000000..05d2ab4e --- /dev/null +++ b/CONTRIBUTINGuk.md @@ -0,0 +1,67 @@ +Read this in other languages: [English](CONTRIBUTING.md), [русский](CONTRIBUTINGru.md), [Français](CONTRIBUTINGfr.md), [Türkçe](CONTRIBUTINGtr.md) + +# Вітаємо у посібнику внеску в Return YouTube Dislikes + +Дякуємо, що вкладаєте свій час у розвиток нашого проєкту! Усі ваші зміни буде відображено в наступній версії розширення (або ж [вебсайту](https://www.returnyoutubedislike.com/)). + +## Почнімо працювати + +Будь ласка, використовуйте Prettier із налаштуваннями за замовчуванням для форматування коду. + +#### Заздалегідь + +Вам потрібно встановити node і npm, щоб створити bundled версію джерела. + +Версії, що використовувались при налаштуванні: + +- node: 12.18.4 +- npm: 6.14.6 + +Для створення `bundled-content-script.js`, який містить більшу частину бізнес-логіки цього розширення, спочатку потрібно встановити всі залежності. + +1. Перейдіть в корінь репозиторію та виконайте наступне: + +``` +npm install +``` + +2. Виконайте наступну команду, щоб створити `bundled-content-script.js`, який використовується в `manifest.json` + +``` +npm start // для створення файлу(ів) збірки та запуску спостерігача за файлами, який виконує hot-reload при збереженні + +// або ж + +npm run build // для створення файлу(ів) збірки один раз +``` + +Вітаємо, тепер ви готові до розробки! + +Якщо ви новачок у розробці розширення Chrome або вам потрібна додаткова допомога, перегляньте [це керівництво на YouTube](https://www.youtube.com/watch?v=mdOj6HYE3_0) (англ.) + +### Проблеми + +#### Відкриття нової проблеми + +Якщо у вас виникли проблеми з розширенням, здійсніть пошук і переконайтеся, що про цю проблему ще не повідомляли. Якщо ні, створіть Issue, використання форми проблеми наполегливо рекомендується, але не є обов’язковим. + +#### Вирішення проблеми + +Якщо ви знайшли проблему, і гадаєте, що можете її вирішити, не соромтеся. Створіть Pull Request на вилучення з виправленням і обов'язково вкажіть проблему, яку ви усуваєте. + +### Запит функції + +#### Відкриття запиту на нову функцію + +Якщо у вас є ідея щодо розширення, не соромтеся створіть Pull Request, але, будь ласка, здійсніть пошук і переконайтеся, що ця функція ще не запропонована. Використання форми функції наполегливо рекомендується, але не є обов’язковим. + +#### Реалізація запиту функції + +Якщо ви знайшли функцію, і гадаєте, що можете її реалізувати, не соромтеся. Створіть Pull Request із виправленням і обов’язково вкажіть функцію, яку ви впроваджуєте. + +### Які Pull Request ми приймаємо? + +- Виправлення проблем. +- Впровадження нових функцій. +- Виправлення помилок та спрощення тексту. +- Поліпшення сайту. \ No newline at end of file diff --git a/Docs/FAQ.md b/Docs/FAQ.md index d539b4f8..91e49063 100644 --- a/Docs/FAQ.md +++ b/Docs/FAQ.md @@ -1,4 +1,5 @@ -Read this in other languages: [Français](FAQfr.md) +Read this in other languages: [русский](FAQru.md), [Français](FAQfr.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md) + # Frequently Asked Questions @@ -36,11 +37,11 @@ The backend will switch to using a combination of archived dislike stats, estima ### **5. How is the dislike count calculated?** -RYD uses the votes from it's users to extrapolate the dislike count. +RYD uses the votes from its users to extrapolate the dislike count. - If the video was uploaded after the API was shut down: - $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Like Count}}{\textup{RYD Users Dislike Count}} \right) \times \textup{Public Like Count} $$ + $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Dislike Count}}{\textup{RYD Users Like Count}} \right) \times \textup{Public Like Count} $$ - If the RYD database somehow had the actual like and dislike count (provided by the uploader or from the archive), the dislike count will be calculated based on both - the users' votes and the archived value. The archived value will have less influence on the final count as it ages. diff --git a/Docs/FAQfr.md b/Docs/FAQfr.md index 76b481ec..a918f8a0 100644 --- a/Docs/FAQfr.md +++ b/Docs/FAQfr.md @@ -1,4 +1,5 @@ -Lisez ceci dans d'autres langues : [English](FAQ.md) +Lisez ceci dans d'autres langues : [English](FAQ.md), [русский](FAQru.md), [Nederlands](FAQnl.md), [Türkçe](FAQtr.md), [українська](FAQuk.md) + # Foire Aux Questions diff --git a/Docs/FAQnl.md b/Docs/FAQnl.md new file mode 100644 index 00000000..1dcb5d1c --- /dev/null +++ b/Docs/FAQnl.md @@ -0,0 +1,61 @@ +Lees dit in andere talen: [Engels](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Türkçe](FAQtr.md) + +# Veel Gestelde Vragen + +## Raadpleeg deze voordat u een vraag stelt op GitHub of Discord. + +
+ +### **1. Waar haalt deze extensie de gegevens vandaan?** + +Een combinatie van Google API's en geschraapte gegevens. + +We slaan alle beschikbare gegevens op in onze database, zodat deze beschikbaar is nadat Google het aantal dislikes in hun API heeft stopgezet. + +
+ +### **2. Het aantal video-dislikes wordt niet bijgewerkt** + +Op dit moment worden video's die niet leuk zijn in het cachegeheugen opgeslagen en worden niet erg vaak bijgewerkt. Eens in de 2-3 dagen, niet vaker. + +Ja, het is niet ideaal, maar het is wat het is. Werken aan het verbeteren van hoe vaak we ze kunnen bijwerken. + +
+ +### **3. Hoe werkt dit?** + +De extensie verzamelt de video-ID van de video die je aan het bekijken bent, haalt de dislike (en andere velden zoals views, likes etc) op met behulp van onze API. Als dit de eerste keer is dat de video wordt opgehaald door onze API, zal deze de YouTube API gebruiken om de gegevens op te halen, slaat de gegevens vervolgens op in een database voor caching (cache voor ongeveer 2-3 dagen) en archiveringsdoeleinden en stuurt ze naar u terug. De extensie geeft vervolgens de antipathieën aan u weer. + +
+ +### **4. Wat gebeurt er nadat de YouTube API stopt met het teruggeven van het aantal dislikes?** + +De backend zal overschakelen naar het gebruik van een combinatie van afkeer statistieken en afkeer archieven, schattingen geëxtrapoleerd uit gebruikersgegevens van extensies en schattingen op basis van weergave/vind-ik-leuk-verhoudingen voor video's waarvan de afkeuren niet zijn gearchiveerd en voor verouderde afkeer-archieven. + +
+ +### **5. Hoe wordt het aantal dislikes berekend?** + +RYD gebruikt de stemmen van zijn gebruikers om het aantal dislikes te extrapoleren. + +- Als de video is geüpload nadat de API was afgesloten: + + $$ \textup{RYD Dislike Count} = \left( \frac{\textup{RYD Users Like Count}}{\textup{RYD Users Dislike Count}} \right) \times \textup{Public Like Count} $$ + +- Als de RYD-database op de een of andere manier het werkelijke aantal likes en dislikes had (geleverd door de uploader of uit het archief), wordt het aantal dislikes berekend op basis van zowel de stemmen van de gebruikers als de gearchiveerde waarde. De gearchiveerde waarde heeft minder invloed op de uiteindelijke telling naarmate deze ouder wordt. + +
+ +--- + +Dit in videovorm + +[![IReturn YouTube Dislike Uitgelegd (Engels)](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ) + +--- + +
+ +## Ik heb zorgen over de beveiliging/privacy + +Bekijk [deze pagina](SECURITY-FAQnl.md) voor meer informatie. diff --git a/Docs/FAQru.txt b/Docs/FAQru.md similarity index 93% rename from Docs/FAQru.txt rename to Docs/FAQru.md index 5c770df1..826381d9 100644 --- a/Docs/FAQru.txt +++ b/Docs/FAQru.md @@ -1,21 +1,25 @@ -# Часто задаваемые вопросы -## Прежде чем задать вопрос на GitHub или в Discord, пожалуйста, ознакомьтесь с этим. - -### **1. Откуда это расширение получает данные?** -Комбинация API Google и старых данных. - -Мы сохраняем все имеющиеся данные в нашей базе данных, чтобы они были доступны после того, как Google прекратит подсчёт отметок «Не нравится» в своём API. - -### **2. Количество не понравившихся видео не обновляется** -В настоящее время видео с отметками «Не нравится» кэшируются и обновляются не очень часто. Раз в 2-3 дня, не чаще. - -Да, это не идеально, но это то, что есть. Мы работаем над тем, чтобы улучшить частоту их обновления. - -### **3. Как это работает?** -Расширение собирает идентификатор видео, которое вы смотрите, извлекает данные об отметках «Не нравится» (и другие поля, такие как просмотры, отметки «Нравится» и т.д.) с помощью нашего API, если видео было извлечено нашим API впервые, оно использует YouTube API для получения данных, затем сохраняет данные в базе данных для кэширования (кэшируются около 2-3 дней) и архивирования и возвращает их вам. После этого расширение отображает отметки «Не нравится» вам. - -### **4. Что произойдёт после того, как API YouTube перестанет возвращать данные о количестве отметок «Не нравится»?** -Внутренняя часть нашего сервера переключится на использование комбинации архивных статистик отметок «Не нравится», оценок, экстраполированных из данных о пользователях расширения, и оценок, основанных на соотношении просмотров и отметок «Нравится» для видео, чьи отметки «Не нравится» не были заархивированы, и для устаревших архивов с отметками «Не нравится». - -## Я беспокоюсь о безопасности / конфиденциальности -Более подробную информацию смотрите на [этой странице](SECURITY-FAQ.md). \ No newline at end of file +Read this in other languages: [English](FAQ.md), [Nederlands](FAQnl.md), Français](FAQfr.md), [Türkçe](FAQtr.md), [українська](FAQuk.md) + + +# Часто задаваемые вопросы + +## Прежде чем задать вопрос на GitHub или в Discord, пожалуйста, ознакомьтесь с этим. + +### **1. Откуда это расширение получает данные?** +Комбинация API Google и старых данных. + +Мы сохраняем все имеющиеся данные в нашей базе данных, чтобы они были доступны после того, как Google прекратит подсчёт отметок «Не нравится» в своём API. + +### **2. Количество не понравившихся видео не обновляется** +В настоящее время видео с отметками «Не нравится» кэшируются и обновляются не очень часто. Раз в 2-3 дня, не чаще. + +Да, это не идеально, но это то, что есть. Мы работаем над тем, чтобы улучшить частоту их обновления. + +### **3. Как это работает?** +Расширение собирает идентификатор видео, которое вы смотрите, извлекает данные об отметках «Не нравится» (и другие поля, такие как просмотры, отметки «Нравится» и т.д.) с помощью нашего API, если видео было извлечено нашим API впервые, оно использует YouTube API для получения данных, затем сохраняет данные в базе данных для кэширования (кэшируются около 2-3 дней) и архивирования и возвращает их вам. После этого расширение отображает отметки «Не нравится» вам. + +### **4. Что произойдёт после того, как API YouTube перестанет возвращать данные о количестве отметок «Не нравится»?** +Внутренняя часть нашего сервера переключится на использование комбинации архивных статистик отметок «Не нравится», оценок, экстраполированных из данных о пользователях расширения, и оценок, основанных на соотношении просмотров и отметок «Нравится» для видео, чьи отметки «Не нравится» не были заархивированы, и для устаревших архивов с отметками «Не нравится». + +## Я беспокоюсь о безопасности / конфиденциальности +Более подробную информацию смотрите на [этой странице](SECURITY-FAQ.md). diff --git a/Docs/FAQtr.md b/Docs/FAQtr.md new file mode 100644 index 00000000..2b7e7a38 --- /dev/null +++ b/Docs/FAQtr.md @@ -0,0 +1,62 @@ +Bunu diğer dillerde okuyun: [English](FAQ.md), [русский](FAQru.md), ), [Nederlands](FAQnl.md), [Français](FAQfr.md), [українська](FAQuk.md) + + +# Sıkça Sorulan Sorular + +## GitHub'da veya Discord'da bir soru sormadan önce, lütfen buraya göz atın. + +
+ +### **1. Bu uzantı verileri nereden alıyor?** + +Google API'lerinin ve kazınmış verilerin bir kombinasyonu. + +Google, API'lerinde dislike sayılarını kapattıktan sonra kullanılabilir olması için mevcut tüm verileri DB'mize kaydederiz. + +
+ +### **2. Video'nun dislike sayısı güncellenmiyor** + +Şu anda video dislike'ları önbelleğe alınır ve çok sık güncellenmez. Her 2-3 günde bir, daha sık değil. + +Evet, ideal değil, ama olan bu. Bunları nasıl daha sık güncelleyebileceğimizi öğrenmeye çalışıyoruz. + +
+ +### **3. Bu uzantı nasıl çalışıyor?** + +Uzantı, izlediğiniz videonun video kimliğini alır, dislike'larını (ve görüntülemeleri, like'ları vb. diğer alanları) API'mizi kullanarak getirir; video, API'miz tarafından ilk kez getiriliyorsa YouTube API'sini kullanır. Verileri almak için, verileri önbelleğe alma (yaklaşık 2-3 gün önbelleğe alınır) ve arşivleme amacıyla bir veritabanında saklanır ve size geri döndürülür. Uzantı daha sonra size dislike'ları gösterir. + +
+ +### **4. YouTube API'si, dislike sayısını döndürmeyi durdurduğunda ne olacak?** + +Backend, arşivlenmiş dislike istatistikleri, uzantı kullanıcı verilerinden tahmin edilen tahminler ve like'ları arşivlenmemiş videolar ve eski dislike arşivleri için izlenme/like oranlarına dayalı tahminlerin bir kombinasyonunu kullanmaya geçecektir. + +
+ +### **5. Dislike sayısı nasıl hesaplanıyor?** + +YDS, dislike sayısını tahmin etmek için kullanıcılarının oylarını kullanır. + +- Video, API kapatıldıktan sonra yüklendiyse: + + $$ \textup{YDS'nin Dislike Sayısı} = \left( \frac{\textup{YDS Kullanıcılarının Like Sayısı}}{\textup{YDS Kullanıcılarının Dislike Sayısı}} \right) \times \textup{Halka Açık Like Sayısı} $$ + +- YDS veritabanı bir şekilde gerçek like ve dislike sayısına sahipse (yükleyici tarafından veya arşivden sağlanır), dislike sayısı hem kullanıcıların oyları hem de arşivlenen değer temelinde hesaplanacaktır. Arşivlenen değer, eskidikçe son sayım üzerinde daha az etkiye sahip olacaktır. + +
+ +--- + +Bu video şeklinde + +[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ) + +--- + +
+ +## Gizlilik / güvenlik hakkında endişelerim var + +Daha fazla bilgi için [bu sayfa](SECURITY-FAQtr.md)ya göz atın. diff --git a/Docs/FAQuk.md b/Docs/FAQuk.md new file mode 100644 index 00000000..0c4812a6 --- /dev/null +++ b/Docs/FAQuk.md @@ -0,0 +1,61 @@ +Read this in other languages: [English](FAQ.md), [русский](FAQru.md), [Français](FAQfr.md), [Türkçe](FAQtr.md) + +# Часті питання + +## Перш ніж задавати питання на GitHub або у Discord, будь ласка, ознайомтеся з цим. + +
+ +### **1. Звідки це розширення отримує дані?** + +Комбінація Google API та старих даних. + +Ми зберігаємо всі доступні дані в нашій базі, аби вони були доступні після того, як Google вимкне лічильник відміток «Не подобається» у своєму API. + +
+ +### **2. Лічильник «Не подобається» не оновлюється** + +Наразі відео з відмітками «Не подобається» кешуються і оновлюються не надто часто. Не частіше, ніж раз в 2-3 дні. + +Так, це не ідеально, але маємо те, що маємо. Ми працюємо над тим, щоб збільшити частоту їх оновлення. + +
+ +### **3. Як це працює?** + +Розширення отримує ID відео, яке ви переглядаєте, та дізнається кількість відміток «Не подобається» (та інші дані: перегляди, відмітки «Подобається» тощо) за допомогою нашого API, якщо відео було витягнуте нашим API вперше, воно використовує YouTube API для отримання даних, потім зберігає дані в базі даних для кешування (кешуються близько 2-3 днів) та архівування й повертає їх вам. Після цього розширення відображає відмітки «Не подобається» вам. + +
+ +### **4. Що станеться після того, як YouTube API перестане повертати кількість відміток «Не подобається»?** + +Сервер перейде на використання комбінації заархівованих статистичних даних відміток «Не подобається» екстрапольованих із даними . + +
+ +### **5. Як розраховується кількість відміток «Не подобається»?** + +RYD використовує відмітки своїх користувачів, щоб екстраполювати кількість відміток «Не подобається». + +- Якщо відео було завантажено після вимкнення API: + + $$ \textup{К-ть відміток «Не подобається» у RYD} = \left( \frac{\textup{К-ть відміток «Подобається» серед користувачів RYD}}{\textup{К-ть відміток «Не подобається» серед користувачів RYD}} \right) \times \textup{Публічна к-ть відміток «Подобається»} $$ + +- Якщо база даних RYD якимось чином мала фактичну кількість відміток «Подобається» та «Не подобається» (надану завантажувачем або з архіву), кількість відміток «Не подобається» буде розраховано на основі відміток користувачів і архівного значення. Архівне значення матиме менший вплив на остаточний підрахунок у міру актуальності. + +
+ +--- + +Це все, але у відео форматі + +[![IReturn YouTube Dislike Explained](https://yt-embed.herokuapp.com/embed?v=GSmmtv-0yYQ)](https://www.youtube.com/watch?v=GSmmtv-0yYQ) + +--- + +
+ +## Я турбуюся про безпеку/конфіденційність + +Детальніше про це дивіться [тут](SECURITY-FAQuk.md). \ No newline at end of file diff --git a/Docs/Privacy Policy b/Docs/Privacy Policy new file mode 100644 index 00000000..5dfbca3e --- /dev/null +++ b/Docs/Privacy Policy @@ -0,0 +1,7 @@ +The only data collected from users is their likes and dislikes made while the extension is installed. + +No personal info, account name or watch history is collected or saved. + +Users are identified by a random user ID, which is not directly linked to any of their accounts, the only purpose of this user ID is to make voting process possible. + +None of the saved data is shared with any third parties, diff --git a/Docs/SECURITY-FAQ.md b/Docs/SECURITY-FAQ.md index dfbbbca7..915a90ab 100644 --- a/Docs/SECURITY-FAQ.md +++ b/Docs/SECURITY-FAQ.md @@ -1,4 +1,5 @@ -Read this in other languages: [Français](SECURITY-FAQfr.md) +Read this in other languages: [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md) + # Security diff --git a/Docs/SECURITY-FAQfr.md b/Docs/SECURITY-FAQfr.md index 877a95ab..ef09af05 100644 --- a/Docs/SECURITY-FAQfr.md +++ b/Docs/SECURITY-FAQfr.md @@ -1,8 +1,8 @@ -Lisez ceci dans d'autres langues : [English](SECURITY-FAQ.md) +Lisez ceci dans d'autres langues : [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), Nederlands](SECURITY_FAQnl.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md) # Sécurité -### Est-ce que vous traquer l'historique des vidéos que je visionne ? +### Est-ce que vous traquez l'historique des vidéos que je visionne ? Non. Le code de l'extension est public et vous pouvez le voir par vous-même. La seule information envoyée est l'ID de la vidéo, qui est nécessaire pour récupérer le nombre de dislikes des vidéos. Aucun en-tête (headers) supplémentaire n'est envoyé. Sur la [couche de communication](https://fr.wikipedia.org/wiki/Mod%C3%A8le_OSI#Caract%C3%A9risation_r%C3%A9sum%C3%A9e_des_couches), votre adresse IP publique sera exposée au serveur, ainsi que l'heure à laquelle la demande a été faite. Toutefois, aucun de ces éléments ne permet de vous identifier de manière unique. Dans un environnement où vous ne pouvez avoir confiance en personne (zero-trust environment), le mieux que l'on puisse obtenir est une IP dynamique. Qui, aujourd'hui est la vôtre, demain est celle de votre voisin. Si vous êtes vraiment inquiet que votre IP soit tracée, vous utilisez probablement déjà un VPN. diff --git a/Docs/SECURITY-FAQnl.md b/Docs/SECURITY-FAQnl.md new file mode 100644 index 00000000..0604ecd2 --- /dev/null +++ b/Docs/SECURITY-FAQnl.md @@ -0,0 +1,41 @@ +Lees dit in andere talen: [English](SECURITY_FAQ.md), [русский](SECURITY-FAQru.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md) + +# Veiligheid + +### Houd je mijn kijkgeschiedenis bij? + +Nee. De code van de extensie is openbaar en u kunt deze zelf zien. De enige informatie die wordt verzonden, is de video-ID, die +nodig is om het aantal dislikes voor de video's op te halen. Er worden geen extra headers verzonden. Via de communicatielaag +wordt uw openbare IP-adres zichtbaar voor de server, evenals het tijdstip waarop het verzoek is gedaan. Geen van deze +identificeert u echter op enigerlei wijze uniek. Uitgaande van een zero-trust-omgeving, is het beste wat we kunnen krijgen een +dynamisch IP-adres. Wat vandaag van jou is, morgen van je buurman. Als u zich echt zorgen maakt dat uw IP-adres wordt +getraceerd, gebruikt u waarschijnlijk al een VPN. + +### Kun je me uniek identificeren als ik een hekel heb? + +Ja. Als je een video niet leuk vindt, maken we een willekeurig gegenereerde unieke ID voor je die niet is gekoppeld aan je +Google-account. Dit wordt gedaan om botting te voorkomen. Maar er is geen manier om deze willekeurige id aan jou of je +persoonlijke YouTube-account te koppelen. + +### Welke informatie heb je precies? + +Alleen de video-ID. Niet je opmerkingen, niet je gebruikersnaam, niet met wie je de video hebt gedeeld, geen aanvullende +metadata. Niks. Alleen de video-ID. + +### Hoe wordt mijn IP opgeslagen? + +De backend bewaart niet-gehashte IP-adressen alleen in vluchtig geheugen (RAM). Deze adressen worden niet opgeslagen op een +harde schijf en worden daarom niet gelogd. We hashen de IP-adressen en dat wordt in plaats daarvan opgeslagen. Dit wordt gedaan +om databasevandalisme te voorkomen. + +### Ik hoorde wat discussie over OAuth en toegang tot mijn YouTube-account! + +Deze functie zal optioneel zijn, en zeer veel opt-in. Als je een YouTube-creator bent en je wilt je afkeerstatistieken met ons delen, dan kan dat. De weg [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) gestructureerd was, is het eigenlijk heel veilig. U kunt op elk moment de toegang tot uw account intrekken en ons zeer specifieke machtigingen geven. We zullen geen toestemming vragen die niet vereist zijn. We vragen alleen toestemming om je videostatistieken te bekijken. + +### Hoe kan ik deze afkeertelling vertrouwen? + +We hebben maatregelen genomen om botaanvallen te voorkomen en zullen blijven werken aan het verbeteren van de effectiviteit van het botpreventiesysteem: dit zal ons helpen het aantal afkeer als een goede vertegenwoordiger van het werkelijke aantal te houden. Natuurlijk zal het nooit 100% nauwkeurig zijn, dus het is aan jou om te beslissen of je de telling vertrouwt of niet. + +### Waarom deel je de backend-code niet? + +We zullen het op een gegeven moment delen - maar er is echt geen echte reden om het nu te delen. Het geeft een vals gevoel van veiligheid - omdat we in een zero-trust-systeem net zo goed de ene versie kunnen onthullen, maar een andere kunnen implementeren. Er zijn tal van redenen om de code verborgen te houden, met name hoe we spam bestrijden. Het verbergen/verduisteren van de spamverwerkingscode is een vrij standaardpraktijk. \ No newline at end of file diff --git a/Docs/SECURITY-FAQru.md b/Docs/SECURITY-FAQru.md index 34526993..2979627d 100644 --- a/Docs/SECURITY-FAQru.md +++ b/Docs/SECURITY-FAQru.md @@ -1,4 +1,4 @@ -Прочитать на других языках: [English](SECURITY-FAQ.md) +Прочитать на других языках: [English](SECURITY-FAQ.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md), [українська](SECURITY-FAQuk.md) # Безопасность diff --git a/Docs/SECURITY-FAQtr.md b/Docs/SECURITY-FAQtr.md new file mode 100644 index 00000000..645d363a --- /dev/null +++ b/Docs/SECURITY-FAQtr.md @@ -0,0 +1,31 @@ +Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Nederlands](SECURITY_FAQnl.md), [Français](SECURITY-FAQfr.md), [українська](SECURITY-FAQuk.md) + +# Güvenlik + +### İzleme geçmişimi takip ediyor musunuz? + +Hayır. Uzantının kodu herkese açıktır ve kendiniz görebilirsiniz. Gönderilen tek bilgi, videolar için dislike sayısını almak için gereken video kimliğidir. Gönderilen başka bir ek header yoktur. İletişim katmanı üzerinden, genel IP'niz sunucuya ve isteğin yapıldığı zamana maruz kalacaktır. Ancak, bunların hiçbiri sizi hiçbir şekilde benzersiz bir şekilde tanımlamıyor. Sıfır güven ortamını varsayarsak, elde edebileceğimizin en iyisi dinamik bir IP'dir. Ki, bu IP bugün sizin, yarın komşunuzun olabilir. IP'nizin izlenmesinden gerçekten endişeleniyorsanız, muhtemelen zaten bir VPN kullanıyorsunuzdur. + +### Bir videoya dislike atarsam, beni benzersiz bir şekilde tanımlayabilir misiniz? + +Evet. Bir videoya dislike attığınızda, sizin için Google hesabınızla bağlantılı olmayan rastgele oluşturulmuş benzersiz bir kimlik oluştururuz. Bu, bot kullanılmasını önlemek için yapılır. Ancak bu rastgele kimliği, size veya kişisel YouTube hesabınıza bağlamanın bir yolu yoktur. + +### Tam olarak hangi bilgilere sahipsiniz, gerçekten? + +Sadece video ID'si. Yorumlarınızı değil, kullanıcı adınızı değil, videoyu kiminle paylaştığınız değil, ek meta verilerinden hiçbiri değil. Hiç bir şey. Sadece video ID'si. + +### IP adresim nasıl saklanıyor? + +Backend, karma olmayan IP adreslerini yalnızca geçici bellekte (RAM'de) tutar. Bu adresler, bir sabit sürücüde depolanmaz ve bu nedenle günlüğe kaydedilmez. IP adreslerini hash ederiz ve bunun yerine depolanır. Bu, veri tabanı vandalizmini önlemek için yapılır. + +### OAuth üzerinden YouTube hesabıma erişmek konusunda bazı tartışmalar duydum! + +Bu özellik isteğe bağlı olacak ve çok fazla tercih edilecek. Bir YouTube içerik üreticisiyseniz ve dislike istatistiklerinizi bizimle paylaşmak istiyorsanız, bunu yapabilirsiniz. [OAuth](https://en.wikipedia.org/wiki/OAuth#:~:text=but%20without%20giving%20them%20the%20passwords.) yapılandırılma şekli, aslında çok güvenlidir. Hesabınıza erişimi istediğiniz zaman iptal edebilir ve bize çok özel izinler verebilirsiniz. Gerekli olmayan herhangi bir izini istemeyeceğiz. Yalnızca video istatistiklerinizi görüntülemek için izin isteyeceğiz. + +### Bu dislike sayısına nasıl güvenebilirim? + +Bot saldırılarını önlemek için önlemler aldık ve bot önleme sisteminin etkinliğini arttırmak için çalışmaya devam edeceğiz: bu, dislike sayısını gerçek sayının iyi bir temsilcisi olarak tutmamıza yardımcı olacaktır. Tabii ki hiçbir zaman %100 doğru olmayacaktır, bu yüzden sayıma güvenip güvenmemek size kalmıştır. + +### Neden backend kodunu paylaşmıyorsunuz? + +Bir noktada paylaşacağız - ama şu anda paylaşmak için ortada gerçekten gerçek bir sebep yok. Yanlış bir güvenlik hissi verebilir - çünkü sıfır güvenli bir sistemde, bir sürümü ifşa edebilir, ancak bir başkasını devreye alabiliriz. Özellikle spam ile nasıl mücadele ettiğimiz gibi, kodu gizli tutmak için birçok neden vardır. İstenmeyen posta işleme kodunu örtmek/gizlemek oldukça standart bir uygulamadır. diff --git a/Docs/SECURITY-FAQuk.md b/Docs/SECURITY-FAQuk.md new file mode 100644 index 00000000..4d18acc5 --- /dev/null +++ b/Docs/SECURITY-FAQuk.md @@ -0,0 +1,31 @@ +Read this in other languages: [English](SECURITY-FAQ.md), [русский](SECURITY-FAQru.md), [Français](SECURITY-FAQfr.md), [Türkçe](SECURITY-FAQtr.md) + +# Безпека + +### Ви відстежуєте мою історію переглядів? + +Ні. Код розширення знаходиться у відкритому доступі, і ви можете ознайомитись з ним самостійно. Єдина інформація, що передається - це ID відео, який необхідний для отримання даних про кількість відміток. Жодних додаткових заголовків не передається. На комунікаційному рівні серверу буде передано вашу публічну IP-адресу, а також час, коли було зроблено запит. Однак ніщо з цього ніяк не здатно вас ідентифіквати. Припускаючи середовище з нульовою довірою, найцінніше, що ми можемо отримати це динамічний IP. Який сьогодні ваш, а завтра – вашого сусіда. Якщо ви дійсно турбуєтеся про те, що ваш IP може бути відстежений, ви, ймовірно, вже використовуєте якийсь VPN. + +### Чи можете ви однозначно ідентифікувати мене, коли я залишаю відмітку «Не подобається»? + +Так. Коли ви залишаєте відео позначку «Не подобається», ми створюємо для вас випадковий унікальний ID, який не прив'язаний до вашого облікового запису Google. Це робиться для уникнення атаки ботів. Але немає жодного способу зв'язати цей випадковий ID до вас або вашого особистого облікового запису YouTube. + +### Якою саме інформацією ви володієте? + +Лише ID відео. Ні ваших коментарів, ні вашого імені користувача, ні того, з ким ви поділилися відео, ні будь-яких інших додаткових метаданих. Нічого. Лише ID відео. + +### Як зберігається моя IP-адреса? + +Внутрішня частина нашого сервера зберігає нехешовані IP-адреси лише в енергозалежній пам'яті (ОЗП). Ці адреси не зберігаються на жорсткому диску і тому ніде не записані. Ми хешуємо IP-адреси, і вони зберігаються замість інших. Це зроблено для запобігання вандалізму у базі даних. + +### Я чув дискусію щодо OAuth і доступу до мого облікового запису YouTube! + +Ця функція буде необов'язковою та дуже необхідною. Якщо ви творець YouTube і хочете поділитися з нами кількістю ваших відміток «Не подобається», ви зможете це зробити. За структурою [OAuth](https://uk.wikipedia.org/wiki/OAuth#:~:text=%D0%B1%D0%B5%D0%B7%20%D0%BD%D0%B5%D0%BE%D0%B1%D1%85%D1%96%D0%B4%D0%BD%D0%BE%D1%81%D1%82%D1%96%20%D0%B2%D0%B2%D0%BE%D0%B4%D1%83%20%D1%96%D0%BC%D0%B5%D0%BD%D1%96%20%D0%BA%D0%BE%D1%80%D0%B8%D1%81%D1%82%D1%83%D0%B2%D0%B0%D1%87%D0%B0%20%D1%82%D0%B0%20%D0%BF%D0%B0%D1%80%D0%BE%D0%BB%D1%8E) надбезпечний. Ви зможете відкликати доступ до свого облікового запису в будь-яку мить, і зможете дати нам обмежені дозволи. Ми не будемо вимагати жодних дозволів, крім необжідних. Ми будемо вимагати лише дозволи перегляду статистики ваших відео. + +### Наскільки достовірна ця кількость відміток «Не подобається»? + +Ми вжили заходів щодо запобігання атакам ботів і збираємося продовжувати працювати над підвищенням ефективності цієї сисеми надалі: це допоможе нам зберегти підрахунок відміток «Не подобається» як хороше представлення фактичної кількості. Звичайно, він ніколи не буде точним на всі 100%, тож ви самі вирішуєте, довіряти йому чи ні. + +### Чому б вам не поділитися внутрішнім кодом вашого сервера? + +Ми поділимося ним у якийсь момент – але зараз немає жодних причин це робити. Це дасть хибне почуття безпеки - адже в системі з нульовою довірою ми можемо з таким самим успіхом поділитися однією версією, але розгорнути іншу. Є багато причин тримати код у таємниці, зокрема, як ми боремося зі спамом. Приховування та затьмарення коду обробки спаму є доволі стандартною практикою. \ No newline at end of file diff --git a/Docs/readme.md b/Docs/readme.md index b6949e05..e014fe8f 100644 --- a/Docs/readme.md +++ b/Docs/readme.md @@ -1,4 +1,4 @@ -Read this in other languages: [Français](readmefr.md) +Read this in other languages: [Nederlands](readmenl.md), [Français](readmefr.md), [Türkçe](readmetr.md) **Contents** @@ -22,8 +22,8 @@ Read this in other languages: [Français](readmefr.md) ## FAQs -- [General](https://github.com/Anarios/return-youtube-dislike/blob/main/Guides/FAQ.md) -- [Security](https://github.com/Anarios/return-youtube-dislike/blob/main/Guides/SECURITY-FAQ.md) +- [General](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) +- [Security](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/SECURITY-FAQ.md) + +
+ +## Gidsen + +- [Downloaden, installeren en gebruiken](https://github.com/Anarios/return-youtube-dislike/wiki/Downloading,-Installing-&-Using) +- [Probleemoplossen](https://github.com/Anarios/return-youtube-dislike/wiki/Troubleshooting-Guide) + + + +
+ +## FAQs + +- [Algemeen](https://github.com/Anarios/return-youtube-dislike/blob/main/Guides/FAQ.md) +- [Beveiliging](https://github.com/Anarios/return-youtube-dislike/blob/main/Guides/SECURITY-FAQ.md) + + diff --git a/Docs/readmetr.md b/Docs/readmetr.md new file mode 100644 index 00000000..49145023 --- /dev/null +++ b/Docs/readmetr.md @@ -0,0 +1,39 @@ +Read this in other languages: [English](readme.md), [Nederlands](readmenl.md), [Français](readmefr.md) + +**İçerikler** + +- [Rehberler](#rehberler) +- [SSS'ler](#sss'ler) + + +
+ +## Rehberler + +- [İndirme, Yükleme ve Kullanma](https://github.com/Anarios/return-youtube-dislike/wiki/Downloading,-Installing-&-Using) +- [Sorun Giderme](https://github.com/Anarios/return-youtube-dislike/wiki/Troubleshooting-Guide) + + + +
+ +## SSS'ler + +- [Genel](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQtr.md) +- [Güvenlik](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/SECURITY-FAQtr.md) + + diff --git a/Extensions/UserScript/Return Youtube Dislike.user.js b/Extensions/UserScript/Return Youtube Dislike.user.js index 253344c7..fa53dcea 100644 --- a/Extensions/UserScript/Return Youtube Dislike.user.js +++ b/Extensions/UserScript/Return Youtube Dislike.user.js @@ -2,7 +2,7 @@ // @name Return YouTube Dislike // @namespace https://www.returnyoutubedislike.com/ // @homepage https://www.returnyoutubedislike.com/ -// @version 3.0.1 +// @version 3.1.2 // @encoding utf-8 // @description Return of the YouTube Dislike, Based off https://www.returnyoutubedislike.com/ // @icon https://github.com/Anarios/return-youtube-dislike/raw/main/Icons/Return%20Youtube%20Dislike%20-%20Transparent.png @@ -58,6 +58,9 @@ function isInViewport(element) { const height = innerHeight || document.documentElement.clientHeight; const width = innerWidth || document.documentElement.clientWidth; return ( + // When short (channel) is ignored, the element (like/dislike AND short itself) is + // hidden with a 0 DOMRect. In this case, consider it outside of Viewport + !(rect.top == 0 && rect.left == 0 && rect.bottom == 0 && rect.right == 0) && rect.top >= 0 && rect.left >= 0 && rect.bottom <= height && @@ -79,10 +82,19 @@ function getButtons() { } } if (isMobile) { - return document.querySelector(".slim-video-action-bar-actions"); + return ( + document.querySelector( + ".slim-video-action-bar-actions .segmented-buttons" + ) ?? document.querySelector(".slim-video-action-bar-actions") + ); } if (document.getElementById("menu-container")?.offsetParent === null) { - return document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div"); + return ( + document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div") ?? + document.querySelector( + "ytd-menu-renderer.ytd-video-primary-info-renderer > div" + ) + ); } else { return document .getElementById("menu-container") @@ -90,12 +102,46 @@ function getButtons() { } } +function getDislikeButton() { + return getButtons().children[0].tagName === + "YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER" + ? getButtons().children[0].children[1] === undefined + ? document.querySelector("#segmented-dislike-button") + : getButtons().children[0].children[1] + : getButtons().children[1]; +} + function getLikeButton() { - return getButtons().children[0]; + return getButtons().children[0].tagName === + "YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER" + ? document.querySelector("#segmented-like-button") !== null + ? document.querySelector("#segmented-like-button") + : getButtons().children[0].children[0] + : getButtons().children[0]; } -function getDislikeButton() { - return getButtons().children[1]; +function getLikeTextContainer() { + return ( + getLikeButton().querySelector("#text") ?? + getLikeButton().getElementsByTagName("yt-formatted-string")[0] ?? + getLikeButton().querySelector("span[role='text']") + ); +} + +function getDislikeTextContainer() { + let result = + getDislikeButton().querySelector("#text") ?? + getDislikeButton().getElementsByTagName("yt-formatted-string")[0] ?? + getDislikeButton().querySelector("span[role='text']"); + if (result === null) { + let textSpan = document.createElement("span"); + textSpan.id = "text"; + textSpan.style.marginLeft = "6px"; + getDislikeButton().querySelector("button").appendChild(textSpan); + getDislikeButton().querySelector("button").style.width = "auto"; + result = getDislikeButton().querySelector("#text"); + } + return result; } let mutationObserver = new Object(); @@ -197,7 +243,7 @@ function setLikes(likesCount) { likesCount; return; } - getButtons().children[0].querySelector("#text").innerText = likesCount; + getLikeTextContainer().innerText = likesCount; } function setDislikes(dislikesCount) { @@ -205,20 +251,26 @@ function setDislikes(dislikesCount) { mobileDislikes = dislikesCount; return; } - getButtons().children[1].querySelector("#text").innerText = dislikesCount; + getDislikeTextContainer()?.removeAttribute("is-empty"); + getDislikeTextContainer().innerText = dislikesCount; } function getLikeCountFromButton() { - if (isShorts()) { - //Youtube Shorts don't work with this query. It's not nessecary; we can skip it and still see the results. - //It should be possible to fix this function, but it's not critical to showing the dislike count. + try { + if (isShorts()) { + //Youtube Shorts don't work with this query. It's not necessary; we can skip it and still see the results. + //It should be possible to fix this function, but it's not critical to showing the dislike count. + return false; + } + let likeButton = + getLikeButton().querySelector("yt-formatted-string#text") ?? + getLikeButton().querySelector("button"); + + let likesStr = likeButton.getAttribute("aria-label").replace(/\D/g, ""); + return likesStr.length > 0 ? parseInt(likesStr) : false; + } catch { return false; } - let likesStr = getLikeButton() - .querySelector("yt-formatted-string#text") - .getAttribute("aria-label") - .replace(/\D/g, ""); - return likesStr.length > 0 ? parseInt(likesStr) : false; } (typeof GM_addStyle != "undefined" @@ -580,17 +632,17 @@ function setEventListeners(evt) { let jsInitChecktimer; function checkForJS_Finish() { - console.log(); + //console.log(); if (isShorts() || (getButtons()?.offsetParent && isVideoLoaded())) { const buttons = getButtons(); if (!window.returnDislikeButtonlistenersSet) { cLog("Registering button listeners..."); try { - buttons.children[0].addEventListener("click", likeClicked); - buttons.children[1].addEventListener("click", dislikeClicked); - buttons.children[0].addEventListener("touchstart", likeClicked); - buttons.children[1].addEventListener("touchstart", dislikeClicked); + getLikeButton().addEventListener("click", likeClicked); + getDislikeButton().addEventListener("click", dislikeClicked); + getLikeButton().addEventListener("touchstart", likeClicked); + getDislikeButton().addEventListener("touchstart", dislikeClicked); } catch { return; } //Don't spam errors into the console @@ -618,7 +670,11 @@ if (isMobile) { return originalPush.apply(history, args); }; setInterval(() => { - getDislikeButton().querySelector(".button-renderer-text").innerText = - mobileDislikes; + if (getDislikeButton().querySelector(".button-renderer-text") === null) { + getDislikeTextContainer().innerText = mobileDislikes; + } else { + getDislikeButton().querySelector(".button-renderer-text").innerText = + mobileDislikes; + } }, 1000); } diff --git a/Extensions/combined/_locales/cs/messages.json b/Extensions/combined/_locales/cs/messages.json index f80e3aca..d49fac7c 100644 --- a/Extensions/combined/_locales/cs/messages.json +++ b/Extensions/combined/_locales/cs/messages.json @@ -42,7 +42,7 @@ "message": "aktualizovat na" }, "version30installed": { - "message": "Verze 3.0.0.1 nainstalována" + "message": "Verze 3.0.0.11 nainstalována" }, "whatsnew": { "message": "Co je nového" diff --git a/Extensions/combined/_locales/de/messages.json b/Extensions/combined/_locales/de/messages.json index 9b0a7ba2..0ca86683 100644 --- a/Extensions/combined/_locales/de/messages.json +++ b/Extensions/combined/_locales/de/messages.json @@ -36,7 +36,7 @@ "message": "aktualisieren auf" }, "version30installed": { - "message": "Version 3.0.0.1 installiert" + "message": "Version 3.0.0.11 installiert" }, "whatsnew": { "message": "Was ist neu" diff --git a/Extensions/combined/_locales/el/messages.json b/Extensions/combined/_locales/el/messages.json new file mode 100644 index 00000000..bd112d7a --- /dev/null +++ b/Extensions/combined/_locales/el/messages.json @@ -0,0 +1,134 @@ +{ + "extensionName": { + "message": "Επιστροφή του YouTube Dislike" + }, + "extensionNameBeta": { + "message": "Return YouTube Dislike Beta" + }, + "extensionDesc": { + "message": "Επιστρέφει τα dislikes" + }, + "textDeveloper": { + "message": "από τον Dmitry Selivanov & την κοινότητα" + }, + "linkWebsite": { + "message": "Ιστοσελίδα" + }, + "linkFAQ": { + "message": "Συχνές ερωτήσεις" + }, + "linkDonate": { + "message": "Στηρίξτε" + }, + "linkHelp": { + "message": "Βοήθεια" + }, + "linkChangelog": { + "message": "Αρχείο αλλαγών" + }, + "legendSettings": { + "message": "Ρυθμίσεις" + }, + "textSettings": { + "message": "Διακοπή υποβολής like/dislike" + }, + "textLikesDisabled": { + "message": "Απενεργοποιήθηκε από τον κάτοχο" + }, + "textSettingsHover": { + "message": "Σταματάει να μετράει τα likes & dislikes που κάνεις." + }, + "textRoundingNumbers": { + "message": "Στρογγυλοποιήστε την τιμή μέτρησης (προεπιλεγμένη επιλογή του YouTube)." + }, + "textRoundingNumbersHover": { + "message": "Εμφάνιση στρογγυλεμένων αριθμών." + }, + "textConsistentFormat": { + "message": "Κάνει σταθερή την μορφοποίηση των likes & dislikes." + }, + "textConsistentFormatHover": { + "message": "Μορφοποίηση του αριθμού των likes." + }, + "textNumberFormat": { + "message": "Μορφή αριθμών:" + }, + "textColorizeRatioBar": { + "message": "Χρωματισμός μπάρας αναλογιών." + }, + "textColorizeRatioBarHover": { + "message": "Προσαρμοζόμενο χρώμα για την μπάρα αναλογιών." + }, + "textColorizeThumbs": { + "message": "Χρωματισμός των thumbs" + }, + "textColorizeThumbsHover": { + "message": "Προσαρμοζόμενο χρώμα για τα thumb icons." + }, + "textColorTheme": { + "message": "Θέματα χρωμάτων:" + }, + "textColorTheme1": { + "message": "Classic" + }, + "textColorTheme2": { + "message": "Accessible" + }, + "textColorTheme3": { + "message": "Neon" + }, + "textTempUnavailable": { + "message": "Προσωρινά μη διαθέσιμο" + }, + "textUpdate": { + "message": "Ενημέρωση σε" + }, + "version30installed": { + "message": "Εκδοση 3.0.0.11 εγκαταστάθηκε" + }, + "whatsnew": { + "message": "Τί νέο υπάρχει" + }, + "shortsSupport": { + "message": "Υποστήριξη για YouTube Shorts" + }, + "customColors": { + "message": "Προσαρμοζόμενα χρώματα για τα κουμπιά και την μπάρα dislike" + }, + "customNumberFormats": { + "message": "Προσαρμοζόμενη μορφή αριθμών" + }, + "considerDonating": { + "message": "Το μόνο πράγμα που διατηρεί την επέκταση σε λειτουργία είναι οι δωρεές σας, σκεφτείτε να υποστηρίξετε το έργο." + }, + "roundNumbers": { + "message": "Εμφάνιση στρογγυλεμένων αριθμών" + }, + "roundNumbersHover": { + "message": "Στρογγυλοποιήστε την τιμή μέτρησης (προεπιλεγμένη επιλογή του YouTube)." + }, + "reformatLikes": { + "message": "Μορφοποίηση του αριθμού των likes" + }, + "reformatLikesHover": { + "message": "Σταθερή μορφοποίηση των likes & dislikes." + }, + "numberFormat": { + "message": "Μορφή αριθμών:" + }, + "colorizeRatio": { + "message": "Χρωματισμός μπάρας σχέσης" + }, + "colorizeRatioHover": { + "message": "Προσαρμοζόμενο χρώμα για την μπάρα αναλογιών." + }, + "colorizeThumbs": { + "message": "Χρωματισμός των thumbs" + }, + "colorizeThumbsHover": { + "message": "Προσαρμοζόμενο χρώμα για τα thumb icons." + }, + "colorTheme": { + "message": "Χρωματικό θέμα:" + } +} diff --git a/Extensions/combined/_locales/en/messages.json b/Extensions/combined/_locales/en/messages.json index a5ba9c0d..9d8823c8 100644 --- a/Extensions/combined/_locales/en/messages.json +++ b/Extensions/combined/_locales/en/messages.json @@ -84,7 +84,7 @@ "message": "Update to" }, "version30installed": { - "message": "Version 3.0.0.1 installed" + "message": "Version 3.0.0.11 installed" }, "whatsnew": { "message": "What's new" diff --git a/Extensions/combined/_locales/es/messages.json b/Extensions/combined/_locales/es/messages.json index 3d1ffc41..10f24d7e 100644 --- a/Extensions/combined/_locales/es/messages.json +++ b/Extensions/combined/_locales/es/messages.json @@ -84,7 +84,7 @@ "message": "actualizar a" }, "version30installed": { - "message": "Versión 3.0.0.1 instalada" + "message": "Versión 3.0.0.11 instalada" }, "whatsnew": { "message": "Novedades" diff --git a/Extensions/combined/_locales/fr/messages.json b/Extensions/combined/_locales/fr/messages.json index 95d61936..1ad8a46a 100644 --- a/Extensions/combined/_locales/fr/messages.json +++ b/Extensions/combined/_locales/fr/messages.json @@ -6,7 +6,7 @@ "message": "Return YouTube Dislike Beta" }, "extensionDesc": { - "message": "Ré-affiche les pouces rouges/dislikes des vidées" + "message": "Ré-affiche les pouces rouges/dislikes des vidéos" }, "textDeveloper": { "message": "par Dmitry Selivanov & Communauté" @@ -42,7 +42,7 @@ "message": "mettre à jour vers" }, "version30installed": { - "message": "Version 3.0.0.1 installée" + "message": "Version 3.0.0.11 installée" }, "whatsnew": { "message": "Quoi de neuf" diff --git a/Extensions/combined/_locales/gr/messages.json b/Extensions/combined/_locales/gr/messages.json deleted file mode 100644 index 269504cd..00000000 --- a/Extensions/combined/_locales/gr/messages.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "extensionName": { - "message": "Επιστροφή του YouTube Dislike" - }, - "extensionNameBeta": { - "message": "Return YouTube Dislike Beta" - }, - "extensionDesc": { - "message": "Επιστρέφει τα dislikes" - }, - "textDeveloper": { - "message": "από τον Dmitry Selivanov & την κοινότητα" - }, - "linkWebsite": { - "message": "Ιστοσελίδα" - }, - "linkFAQ": { - "message": "Γρήγορες Ερωτήσεις & Απαντήσεις" - }, - "linkDonate": { - "message": "Στηρίξτε" - }, - "linkHelp": { - "message": "Βοήθεια" - }, - "legendSettings": { - "message": "Ρυθμίσεις" - }, - "textSettings": { - "message": "Διακοπή υποβολής like/dislike" - }, - "textSettingsHover": { - "message": "Σταματάει να μετράει τα likes & dislikes που κάνεις." - }, - "textUpdate": { - "message": "ενημέρωση σε" - }, - "version30installed": { - "message": "Εκδοση 3.0.0.1 εγκαταστάθηκε" - }, - "whatsnew": { - "message": "Τι είναι νέο;" - }, - "shortsSupport": { - "message": "Υποστήριξη για YouTube Shorts" - }, - "customColors": { - "message": "Προσαρμοζόμενα χρώματα για τα κουμπιά και την μπάρα dislike" - }, - "customNumberFormats": { - "message": "Προσαρμοζόμενη μορφή αριθμών." - }, - "considerDonating": { - "message": "Το μόνο πράγμα που διατηρεί την επέκταση σε λειτουργία είναι οι δωρεές σας, σκεφτείτε να υποστηρίξετε το έργο." - }, - "roundNumbers": { - "message": "Εμφάνιση στρογγυλεμένων αριθμών" - }, - "roundNumbersHover": { - "message": "Στρογγυλοποιήστε την τιμή μέτρησης (αυτή είναι η προεπιλεγμένη επιλογή του YouTube)." - }, - "reformatLikes": { - "message": "Μορφοποίηση του αριθμού των likes" - }, - "reformatLikesHover": { - "message": "Κάνει την αξία των στατιστικών πιο συνεπή." - }, - "numberFormat": { - "message": "Αριθμητική μορφή" - }, - "colorizeRatio": { - "message": "Χρωματίστε τη γραμμή dislikes" - }, - "colorizeRatioHover": { - "message": "Χρωματίστε τη γραμμή dislikes με προσαρμοσμένα χρώματα." - }, - "colorizeThumbs": { - "message": "Χρωματίστε τα κουμπιά" - }, - "colorizeThumbsHover": { - "message": "Χρωματίστε τα κουμπιά likes και dislikes με προσαρμοσμένα χρώματα." - }, - "colorTheme": { - "message": "Χρωματικός συνδυασμός:" - } -} diff --git a/Extensions/combined/_locales/it/messages.json b/Extensions/combined/_locales/it/messages.json index adf6dcbe..c1d03984 100644 --- a/Extensions/combined/_locales/it/messages.json +++ b/Extensions/combined/_locales/it/messages.json @@ -36,7 +36,7 @@ "message": "aggiorna a" }, "version30installed": { - "message": "Versione 3.0.0.1 installata" + "message": "Versione 3.0.0.11 installata" }, "whatsnew": { "message": "Quali sono le novità" diff --git a/Extensions/combined/_locales/ja/messages.json b/Extensions/combined/_locales/ja/messages.json index 6a587cc3..be6d0433 100644 --- a/Extensions/combined/_locales/ja/messages.json +++ b/Extensions/combined/_locales/ja/messages.json @@ -42,7 +42,7 @@ "message": "アップデート:" }, "version30installed": { - "message": "バージョン 3.0.0.1 がインストールされました。" + "message": "バージョン 3.0.0.11 がインストールされました。" }, "whatsnew": { "message": "新機能" diff --git a/Extensions/combined/_locales/ko/messages.json b/Extensions/combined/_locales/ko/messages.json new file mode 100644 index 00000000..7e0fa89a --- /dev/null +++ b/Extensions/combined/_locales/ko/messages.json @@ -0,0 +1,134 @@ +{ + "extensionName": { + "message": "Return YouTube Dislike" + }, + "extensionNameBeta": { + "message": "Return YouTube Dislike 베타" + }, + "extensionDesc": { + "message": "대략적인 싫어요 갯수를 볼 수 있게 합니다" + }, + "textDeveloper": { + "message": "Dmitry Selivanov와 커뮤니티 제작" + }, + "linkWebsite": { + "message": "웹사이트" + }, + "linkFAQ": { + "message": "FAQ" + }, + "linkDonate": { + "message": "기부" + }, + "linkHelp": { + "message": "도움말" + }, + "linkChangelog": { + "message": "변경사항" + }, + "legendSettings": { + "message": "설정" + }, + "textSettings": { + "message": "좋아요/싫어요 제출 비활성화" + }, + "textLikesDisabled": { + "message": "업로더가 비활성화함" + }, + "textSettingsHover": { + "message": "당신의 좋아요와 싫어요 갯수 계산을 중지합니다." + }, + "textRoundingNumbers": { + "message": "좋아요/싫어요 통계 비활성화(기본 YouTube 동작)" + }, + "textRoundingNumbersHover": { + "message": "반올림된 통계 보이기" + }, + "textConsistentFormat": { + "message": "좋아요와 싫어요 형식을 일관되게 만듭니다" + }, + "textConsistentFormatHover": { + "message": "좋아요 갯수 표시 형식 재정의" + }, + "textNumberFormat": { + "message": "숫자 표시 형식:" + }, + "textColorizeRatioBar": { + "message": "비율 막대 컬러화" + }, + "textColorizeRatioBarHover": { + "message": "비율 막대에 커스텀 색상을 사용합니다." + }, + "textColorizeThumbs": { + "message": "엄지 컬러화" + }, + "textColorizeThumbsHover": { + "message": "엄지 아이콘에 커스텀 색상을 사용합니다." + }, + "textColorTheme": { + "message": "컬러 테마:" + }, + "textColorTheme1": { + "message": "클래식" + }, + "textColorTheme2": { + "message": "Accessible" + }, + "textColorTheme3": { + "message": "네온" + }, + "textTempUnavailable": { + "message": "일시적으로 사용할 수 없음" + }, + "textUpdate": { + "message": "업데이트" + }, + "version30installed": { + "message": "3.0.0.11 버전이 설치됨" + }, + "whatsnew": { + "message": "새로운 점" + }, + "shortsSupport": { + "message": "유튜브 쇼츠 지원" + }, + "customColors": { + "message": "싫어요 바와 버튼의 색을 커스텀" + }, + "customNumberFormats": { + "message": "숫자 표시 형식 커스텀" + }, + "considerDonating": { + "message": "확장 프로그램을 계속 돌아가게 할 수 있는 유일한 방법은 당신의 기부이며, 프로젝트에 지원하는 것을 고려해 주세요." + }, + "roundNumbers": { + "message": "반올림된 숫자 표시" + }, + "roundNumbersHover": { + "message": "반올림된 숫자(기본 유튜브 동작)." + }, + "reformatLikes": { + "message": "좋아요 갯수 표시 형식 재정의" + }, + "reformatLikesHover": { + "message": "좋아요와 싫어요 형식을 일관되게 만듭니다." + }, + "numberFormat": { + "message": "숫자 표시 형식:" + }, + "colorizeRatio": { + "message": "비율 막대 컬러화" + }, + "colorizeRatioHover": { + "message": "비율 막대에 커스텀 색상을 사용합니다." + }, + "colorizeThumbs": { + "message": "엄지 컬러화" + }, + "colorizeThumbsHover": { + "message": "엄지 아이콘에 커스텀 색상을 사용합니다." + }, + "colorTheme": { + "message": "컬러 테마:" + } +} diff --git a/Extensions/combined/_locales/nl/messages.json b/Extensions/combined/_locales/nl/messages.json new file mode 100644 index 00000000..4ee2e36f --- /dev/null +++ b/Extensions/combined/_locales/nl/messages.json @@ -0,0 +1,134 @@ +{ + "extensionName": { + "message": "Return YouTube Dislike" + }, + "extensionNameBeta": { + "message": "Return YouTube Dislike Beta" + }, + "extensionDesc": { + "message": "Retourneert het vermogen om dislikes te zien" + }, + "textDeveloper": { + "message": "door Dmitry Selivanov & Gemeenschap" + }, + "linkWebsite": { + "message": "Website" + }, + "linkFAQ": { + "message": "FAQ" + }, + "linkDonate": { + "message": "Doneer" + }, + "linkHelp": { + "message": "Help" + }, + "linkChangelog": { + "message": "Wijzig-log" + }, + "legendSettings": { + "message": "Instellingen" + }, + "textSettings": { + "message": "Inzending voor leuk/niet leuk uitschakelen" + }, + "textLikesDisabled": { + "message": "Uitgeschakeld door eigenaar" + }, + "textSettingsHover": { + "message": "Stopt met het tellen van je leuks en niet leuks" + }, + "textRoundingNumbers": { + "message": "Statistieken voor leuk/niet leuk naar beneden afronden (standaard YouTube-gedrag)" + }, + "textRoundingNumbersHover": { + "message": "Afgeronde statistieken weergeven." + }, + "textConsistentFormat": { + "message": "Maak het formaat voor likes en dislikes consistent" + }, + "textConsistentFormatHover": { + "message": "Herformatteer als getallen." + }, + "textNumberFormat": { + "message": "Nummer formaat:" + }, + "textColorizeRatioBar": { + "message": "Verhoudingsbalk inkleuren" + }, + "textColorizeRatioBarHover": { + "message": "Gebruik aangepaste kleuren voor de verhoudingsbalk." + }, + "textColorizeThumbs": { + "message": "Duimen inkleuren" + }, + "textColorizeThumbsHover": { + "message": "Gebruik aangepaste kleuren voor duimpictogrammen." + }, + "textColorTheme": { + "message": "Kleuren thema:" + }, + "textColorTheme1": { + "message": "Klassiek" + }, + "textColorTheme2": { + "message": "Beschikbaar" + }, + "textColorTheme3": { + "message": "Neon" + }, + "textTempUnavailable": { + "message": "Tijdelijk niet beschikbaar" + }, + "textUpdate": { + "message": "Update naar" + }, + "version30installed": { + "message": "Versie 3.0.0.11 geïnstalleerd" + }, + "whatsnew": { + "message": "Wat is er nieuw" + }, + "shortsSupport": { + "message": "YouTube Shorts Ondersteuning" + }, + "customColors": { + "message": "Aangepaste kleuren voor afkeerbalk en knoppen" + }, + "customNumberFormats": { + "message": "Aangepaste getalnotaties" + }, + "considerDonating": { + "message": "Het enige dat de extensie draaiende houdt, zijn uw donaties, overweeg alstublieft om het project te steunen." + }, + "roundNumbers": { + "message": "Afgeronde getallen weergeven" + }, + "roundNumbersHover": { + "message": "Rond getallen naar beneden af (standaard YouTube-gedrag)." + }, + "reformatLikes": { + "message": "Opnieuw formatteren zoals getallen" + }, + "reformatLikesHover": { + "message": "Maak het formaat voor leuk en niet leuk consistent." + }, + "numberFormat": { + "message": "Nummer formaat:" + }, + "colorizeRatio": { + "message": "Verhoudingsbalk inkleuren" + }, + "colorizeRatioHover": { + "message": "Gebruik aangepaste kleuren voor de verhoudingsbalk." + }, + "colorizeThumbs": { + "message": "Duimen inkleuren" + }, + "colorizeThumbsHover": { + "message": "Gebruik aangepaste kleuren voor de duimpictogrammen." + }, + "colorTheme": { + "message": "Kleuren thema:" + } + } diff --git a/Extensions/combined/_locales/pt_BR/messages.json b/Extensions/combined/_locales/pt_BR/messages.json index fac12a21..ed3f6aae 100644 --- a/Extensions/combined/_locales/pt_BR/messages.json +++ b/Extensions/combined/_locales/pt_BR/messages.json @@ -42,7 +42,7 @@ "message": "Atualizar para" }, "version30installed": { - "message": "Versão 3.0.0.1 instalada" + "message": "Versão 3.0.0.11 instalada" }, "whatsnew": { "message": "O que há de novo?" diff --git a/Extensions/combined/_locales/ru/messages.json b/Extensions/combined/_locales/ru/messages.json index c275bf97..f71752cc 100644 --- a/Extensions/combined/_locales/ru/messages.json +++ b/Extensions/combined/_locales/ru/messages.json @@ -36,7 +36,7 @@ "message": "обновление до" }, "version30installed": { - "message": "Версия 3.0.0.1 установлена" + "message": "Версия 3.0.0.11 установлена" }, "whatsnew": { "message": "Что нового" diff --git a/Extensions/combined/_locales/sv_SE/messages.json b/Extensions/combined/_locales/sv_SE/messages.json new file mode 100644 index 00000000..2011c83e --- /dev/null +++ b/Extensions/combined/_locales/sv_SE/messages.json @@ -0,0 +1,134 @@ +{ + "extensionName": { + "message": "Return YouTube Dislike" + }, + "extensionNameBeta": { + "message": "Return YouTube Dislike Beta" + }, + "extensionDesc": { + "message": "Återställer förmågan att se ogilla" + }, + "textDeveloper": { + "message": "av Dmitry Selivanov & Community" + }, + "linkWebsite": { + "message": "Hemsida" + }, + "linkFAQ": { + "message": "FAQ" + }, + "linkDonate": { + "message": "Donera" + }, + "linkHelp": { + "message": "Hjälp" + }, + "linkChangelog": { + "message": "Ändringslogg" + }, + "legendSettings": { + "message": "Inställningar" + }, + "textSettings": { + "message": "Inaktivera gilla-/ogilla-inskickningar" + }, + "textLikesDisabled": { + "message": "Inaktiverad av ägaren" + }, + "textSettingsHover": { + "message": "Slutar räkna dina gilla och ogilla." + }, + "textRoundingNumbers": { + "message": "Avrunda statistiken neråt för gilla/ogilla (standard YouTube-beteende)" + }, + "textRoundingNumbersHover": { + "message": "Visa avrundad statistik." + }, + "textConsistentFormat": { + "message": "Gör formatet på gilla och ogilla konsekvent" + }, + "textConsistentFormatHover": { + "message": "Omformatera som siffror." + }, + "textNumberFormat": { + "message": "Sifforformat:" + }, + "textColorizeRatioBar": { + "message": "Färgsätt förhållandefältet" + }, + "textColorizeRatioBarHover": { + "message": "Använd anpassade färger för förhållandefältet." + }, + "textColorizeThumbs": { + "message": "Färglägg tummarna" + }, + "textColorizeThumbsHover": { + "message": "Använd anpassade färger för tumikoner." + }, + "textColorTheme": { + "message": "Färgtema:" + }, + "textColorTheme1": { + "message": "Klassisk" + }, + "textColorTheme2": { + "message": "Tillgänglig" + }, + "textColorTheme3": { + "message": "Neon" + }, + "textTempUnavailable": { + "message": "Tillfälligt otillgänglig" + }, + "textUpdate": { + "message": "Uppdatera till" + }, + "version30installed": { + "message": "Version 3.0.0.11 installerad" + }, + "whatsnew": { + "message": "Vad är nytt" + }, + "shortsSupport": { + "message": "YouTube Shorts Support" + }, + "customColors": { + "message": "Anpassade färger för knappar och fältet ogilla" + }, + "customNumberFormats": { + "message": "Anpassade sifforformat" + }, + "considerDonating": { + "message": "Det enda som håller tillägget i gång är dina donationer, överväg att stöda projektet." + }, + "roundNumbers": { + "message": "Visa avrundade siffror" + }, + "roundNumbersHover": { + "message": "Avrunda siffrorna neråt (standard YouTube-beteende)." + }, + "reformatLikes": { + "message": "Omformatera som siffror" + }, + "reformatLikesHover": { + "message": "Gör formatet på gilla och ogilla konsekvent." + }, + "numberFormat": { + "message": "Sifforformat:" + }, + "colorizeRatio": { + "message": "Färgsätt förhållandefältet" + }, + "colorizeRatioHover": { + "message": "Använd anpassade färger för förhållandefältet." + }, + "colorizeThumbs": { + "message": "Färglägg tummarna" + }, + "colorizeThumbsHover": { + "message": "Använd anpassade färger för tumikoner." + }, + "colorTheme": { + "message": "Färgtema:" + } +} diff --git a/Extensions/combined/_locales/tr/messages.json b/Extensions/combined/_locales/tr/messages.json index d2b2f899..17e9cd5c 100644 --- a/Extensions/combined/_locales/tr/messages.json +++ b/Extensions/combined/_locales/tr/messages.json @@ -23,6 +23,9 @@ "linkHelp": { "message": "Yardım" }, + "linkChangelog": { + "message": "Değişim Günlüğü" + }, "legendSettings": { "message": "Ayarlar" }, @@ -30,19 +33,58 @@ "message": "Like/dislike gönderimini devre dışı bırak" }, "textLikesDisabled": { - "message": "sahibi tarafından devre dışı bırakıldı" + "message": "Sahibi tarafından devre dışı bırakıldı" }, "textSettingsHover": { - "message": "Like'larınızı ve dislike'larınızı saymayı bırakır." + "message": "Like ve dislike'larınızı saymayı bırakır." + }, + "textRoundingNumbers": { + "message": "Like/dislike istatisliklerini aşağıya yuvarlar (varsayılan YouTube davranışı)" + }, + "textRoundingNumbersHover": { + "message": "Yuvarlatılmış istatistikleri göster." + }, + "textConsistentFormat": { + "message": "Like ve dislike tarzını tutarlı hâle getirir" + }, + "textConsistentFormatHover": { + "message": "Like sayılarının tarzını yenileştir." + }, + "textNumberFormat": { + "message": "Sayı tarzı:" + }, + "textColorizeRatioBar": { + "message": "Beğeni oranı çubuğunu renklendir" + }, + "textColorizeRatioBarHover": { + "message": "Oran çubuğu için özel renkler kullanın." + }, + "textColorizeThumbs": { + "message": "Butonları renklendir" + }, + "textColorizeThumbsHover": { + "message": "Buton simgeleri için özel renkler kullanın." + }, + "textColorTheme": { + "message": "Renk teması:" + }, + "textColorTheme1": { + "message": "Klasik" + }, + "textColorTheme2": { + "message": "Anlaşılır" + }, + "textColorTheme3": { + "message": "Neon" }, "textTempUnavailable": { - "message": "geçici olarak kullanım dışı" + "message": "Geçici Olarak Kullanım Dışı" }, "textUpdate": { - "message": "şu sürüme güncelle" + "message": "Şu sürüme güncelle" }, "version30installed": { - "message": "Sürüm 3.0.0.1 yüklendi" + "message": "Sürüm 3.0.0.11 yüklendi" }, "whatsnew": { "message": "Yeni Ne Var" @@ -58,5 +100,35 @@ }, "considerDonating": { "message": "Uzantının var olmasını sağlayan tek şey bağışlarınızdır, lütfen projeyi desteklemeyi düşünün." + }, + "roundNumbers": { + "message": "Aşağı yuvarlanmış sayıları gösterir" + }, + "roundNumbersHover": { + "message": "Sayıları aşağıya yuvarla (varsayılan YouTube davranışı)." + }, + "reformatLikes": { + "message": "Like sayılarının tarzını yenileştir" + }, + "reformatLikesHover": { + "message": "Like ve dislike tarzını tutarlı hâle getirir." + }, + "numberFormat": { + "message": "Sayı tarzı:" + }, + "colorizeRatio": { + "message": "Beğeni oranı çubuğunu renklendir" + }, + "colorizeRatioHover": { + "message": "Beğeni oranı çubuğu için özel renkler kullanın." + }, + "colorizeThumbs": { + "message": "Butonları renklendir" + }, + "colorizeThumbsHover": { + "message": "Buton simgeleri için özel renkler kullan." + }, + "colorTheme": { + "message": "Renk teması:" } } diff --git a/Extensions/combined/_locales/uk/messages.json b/Extensions/combined/_locales/uk/messages.json new file mode 100644 index 00000000..bbe38903 --- /dev/null +++ b/Extensions/combined/_locales/uk/messages.json @@ -0,0 +1,134 @@ +{ + "extensionName": { + "message": "Return YouTube Dislike" + }, + "extensionNameBeta": { + "message": "Return YouTube Dislike Beta" + }, + "extensionDesc": { + "message": "Повертає здатність бачити відмітки «Не подобається»" + }, + "textDeveloper": { + "message": "від Дмитра Селіванова та спільноти" + }, + "linkWebsite": { + "message": "Вебсайт" + }, + "linkFAQ": { + "message": "ЧаПи" + }, + "linkDonate": { + "message": "Підтримати" + }, + "linkHelp": { + "message": "Допомога" + }, + "linkChangelog": { + "message": "Журнал змін" + }, + "legendSettings": { + "message": "Налаштування" + }, + "textSettings": { + "message": "Вимкнути надсилання відміток" + }, + "textLikesDisabled": { + "message": "Вимкнуто власником" + }, + "textSettingsHover": { + "message": "Вимикає надсилання відміток «Подобається» та «Не подобається»." + }, + "textRoundingNumbers": { + "message": "Округлює значення відміток (стандартний параметр YouTube)" + }, + "textRoundingNumbersHover": { + "message": "Показувати заокруглені значення." + }, + "textConsistentFormat": { + "message": "Зробить формат «Подобається» та «Не подобається» однаковим" + }, + "textConsistentFormatHover": { + "message": "Форматувати як числа." + }, + "textNumberFormat": { + "message": "Формат значень:" + }, + "textColorizeRatioBar": { + "message": "Обрати кольори стрічки співвідношення" + }, + "textColorizeRatioBarHover": { + "message": "Змінює кольори стрічки співвідношення на обрані вами." + }, + "textColorizeThumbs": { + "message": "Обрати кольори відміток" + }, + "textColorizeThumbsHover": { + "message": "Змінює кольори піктограм відміток на обрані вами." + }, + "textColorTheme": { + "message": "Кольорова схема:" + }, + "textColorTheme1": { + "message": "Класика" + }, + "textColorTheme2": { + "message": "Доступність" + }, + "textColorTheme3": { + "message": "Неон" + }, + "textTempUnavailable": { + "message": "Тимчасово недоступно" + }, + "textUpdate": { + "message": "Оновлення до" + }, + "version30installed": { + "message": "Версію 3.0.0.11 встановлено" + }, + "whatsnew": { + "message": "Що нового" + }, + "shortsSupport": { + "message": "Підтримка YouTube Shorts" + }, + "customColors": { + "message": "Користувальницькі кольори стрічки співвідношення та кнопок" + }, + "customNumberFormats": { + "message": "Користувацькі формати значень" + }, + "considerDonating": { + "message": "Розширення досі існує лише за допомогою ваших пожертв, будь ласка, підтримайте проєкт." + }, + "roundNumbers": { + "message": "Показувати заокруглені значення" + }, + "roundNumbersHover": { + "message": "Округлює значення відміток (стандартний параметр YouTube)" + }, + "reformatLikes": { + "message": "Форматувати як числа" + }, + "reformatLikesHover": { + "message": "Зробить формат «Подобається» та «Не подобається» однаковим" + }, + "numberFormat": { + "message": "Формат значень:" + }, + "colorizeRatio": { + "message": "Обрати кольори стрічки співвідношення" + }, + "colorizeRatioHover": { + "message": "Змінює кольори стрічки співвідношення на обрані вами." + }, + "colorizeThumbs": { + "message": "Обрати кольори відміток" + }, + "colorizeThumbsHover": { + "message": "Змінює кольори піктограм відміток на обрані вами." + }, + "colorTheme": { + "message": "Кольорова схема:" + } +} diff --git a/Extensions/combined/changelog/changelog.js b/Extensions/combined/changelog/changelog.js index 8c9e332a..fbef6c94 100644 --- a/Extensions/combined/changelog/changelog.js +++ b/Extensions/combined/changelog/changelog.js @@ -6,7 +6,6 @@ const config = { coloredBar: false, colorTheme: "classic", numberDisplayFormat: "compactShort", - numberDisplayRoundDown: true, showAdvancedMessage: '', hideAdvancedMessage: diff --git a/Extensions/combined/changelog/images/colorize_example.jpg b/Extensions/combined/changelog/images/colorize_example.jpg index add351dd..ce2cb742 100644 Binary files a/Extensions/combined/changelog/images/colorize_example.jpg and b/Extensions/combined/changelog/images/colorize_example.jpg differ diff --git a/Extensions/combined/changelog/images/number_format.jpg b/Extensions/combined/changelog/images/number_format.jpg index 43a17cc6..e5e89002 100644 Binary files a/Extensions/combined/changelog/images/number_format.jpg and b/Extensions/combined/changelog/images/number_format.jpg differ diff --git a/Extensions/combined/content-style.css b/Extensions/combined/content-style.css index d8da7db1..8444b583 100644 --- a/Extensions/combined/content-style.css +++ b/Extensions/combined/content-style.css @@ -30,12 +30,20 @@ } .ryd-tooltip { - position: relative; display: block; height: 2px; +} + +.ryd-tooltip-old-design { + position: relative; top: 9px; } +.ryd-tooltip-new-design { + position: absolute; + bottom: -10px; +} + .ryd-tooltip-bar-container { width: 100%; height: 2px; @@ -44,3 +52,12 @@ padding-bottom: 12px; top: -6px; } + +/* required to make the ratio bar visible in the new design */ +ytd-menu-renderer.ytd-watch-metadata { + overflow-y: visible !important; +} + +#top-level-buttons-computed { + position: relative !important; +} diff --git a/Extensions/combined/icons/server.svg b/Extensions/combined/icons/server.svg index 869a391e..4e6c50fd 100644 --- a/Extensions/combined/icons/server.svg +++ b/Extensions/combined/icons/server.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/Extensions/combined/manifest-chrome.json b/Extensions/combined/manifest-chrome.json index d881a756..de118dc9 100644 --- a/Extensions/combined/manifest-chrome.json +++ b/Extensions/combined/manifest-chrome.json @@ -2,7 +2,7 @@ "name": "__MSG_extensionName__", "description": "__MSG_extensionDesc__", "default_locale": "en", - "version": "3.0.0.1", + "version": "3.0.0.10", "manifest_version": 3, "background": { "service_worker": "ryd.background.js" @@ -36,5 +36,9 @@ "resources": ["ryd.script.js"], "matches": ["*://*.youtube.com/*"] } - ] + ], + "options_ui": { + "page": "popup.html", + "open_in_tab": false + } } diff --git a/Extensions/combined/manifest-firefox.json b/Extensions/combined/manifest-firefox.json index 82fd897a..e35a599d 100644 --- a/Extensions/combined/manifest-firefox.json +++ b/Extensions/combined/manifest-firefox.json @@ -2,7 +2,7 @@ "name": "__MSG_extensionName__", "description": "__MSG_extensionDesc__", "default_locale": "en", - "version": "3.0.0.0", + "version": "3.0.0.10", "manifest_version": 2, "background": { "scripts": ["ryd.background.js"] @@ -28,8 +28,12 @@ "css": ["content-style.css"], "js": ["ryd.content-script.js"] } - ] - // , + ], + "options_ui": { + "page": "popup.html", + "open_in_tab": false + } + // uncomment this section for local storage to work in firefox locally // "browser_specific_settings": { // "gecko": { // "id": "addon@example.com", diff --git a/Extensions/combined/manifest-safari.json b/Extensions/combined/manifest-safari.json new file mode 100644 index 00000000..4a38cb3c --- /dev/null +++ b/Extensions/combined/manifest-safari.json @@ -0,0 +1,36 @@ +{ + "name": "__MSG_extensionName__", + "description": "__MSG_extensionDesc__", + "default_locale": "en", + "version": "3.0.0.8", + "manifest_version": 2, + "background": { + "scripts": ["ryd.background.js"], + "persistent": false + }, + "icons": { + "48": "icons/icon48.png", + "128": "icons/icon128.png" + }, + "permissions": [ + "activeTab", + "*://*.youtube.com/*", + "storage", + "*://returnyoutubedislikeapi.com/*" + ], + "browser_action": { + "default_popup": "popup.html" + }, + "content_scripts": [ + { + "matches": ["*://*.youtube.com/*"], + "exclude_matches": ["*://*.music.youtube.com/*"], + "run_at": "document_idle", + "css": ["content-style.css"], + "js": ["ryd.content-script.js"] + } + ], + "options_ui": { + "page": "popup.html" + } +} diff --git a/Extensions/combined/popup.html b/Extensions/combined/popup.html index aa2e5085..9bf53cd6 100644 --- a/Extensions/combined/popup.html +++ b/Extensions/combined/popup.html @@ -104,21 +104,15 @@


- -

@@ -134,13 +128,13 @@


@@ -148,13 +142,13 @@

data-hover="Display percentage in like/dislike bar tooltip." > - + Percentage in like/dislike bar tooltip.
diff --git a/Extensions/combined/popup.js b/Extensions/combined/popup.ts similarity index 53% rename from Extensions/combined/popup.js rename to Extensions/combined/popup.ts index cf72829d..30d67337 100644 --- a/Extensions/combined/popup.js +++ b/Extensions/combined/popup.ts @@ -1,4 +1,9 @@ -import { cLog } from "./src/utils"; +import storage from "./src/storage"; +import { + ColorTheme, + NumberDisplayFormat, + TooltipPercentageMode, +} from "./src/types"; /* Config */ const config = { @@ -8,7 +13,6 @@ const config = { coloredBar: false, colorTheme: "classic", numberDisplayFormat: "compactShort", - numberDisplayRoundDown: true, showTooltipPercentage: false, tooltipPercentageMode: "dash_like", numberDisplayReformatLikes: false, @@ -29,18 +33,27 @@ const config = { }; /* Change language */ -function localizeHtmlPage() { - //Localize by replacing __MSG_***__ meta tags - var objects = document.getElementsByTagName("html"); - for (var j = 0; j < objects.length; j++) { - var obj = objects[j]; - - var valStrH = obj.innerHTML.toString(); - var valNewH = valStrH.replace(/__MSG_(\w+)__/g, function (match, v1) { +function localizeHtmlPage(): void { + // Localize by replacing __MSG_***__ meta tags + const objects: HTMLCollectionOf = + document.getElementsByTagName("html"); + + for (let j = 0; j < objects.length; j++) { + const obj = objects[j]; + + const valStrH = obj?.innerHTML; + const valNewH = valStrH?.replace(/__MSG_(\w+)__/g, (_, v1) => { return v1 ? chrome.i18n.getMessage(v1) : ""; }); - if (valNewH != valStrH) { + if (!valNewH) { + continue; + } + + if (valNewH === valStrH) { + continue; + } + if (obj?.innerHTML) { obj.innerHTML = valNewH; } } @@ -57,67 +70,66 @@ createLink(config.links.donate, "link_donate"); createLink(config.links.help, "link_help"); createLink(config.links.changelog, "link_changelog"); -function createLink(url, id) { - document.getElementById(id).addEventListener("click", () => { +function createLink(url: any, id: any) { + document.getElementById(id)?.addEventListener("click", () => { chrome.tabs.create({ url: url }); }); } document .getElementById("disable_vote_submission") - .addEventListener("click", (ev) => { - chrome.storage.sync.set({ disableVoteSubmission: ev.target.checked }); + ?.addEventListener("click", (ev: any) => { + storage.set({ disableVoteSubmission: ev.target.checked }); }); -document.getElementById("colored_thumbs").addEventListener("click", (ev) => { - chrome.storage.sync.set({ coloredThumbs: ev.target.checked }); -}); - -document.getElementById("colored_bar").addEventListener("click", (ev) => { - chrome.storage.sync.set({ coloredBar: ev.target.checked }); -}); +document + .getElementById("colored_thumbs") + ?.addEventListener("click", (ev: any) => { + storage.set({ coloredThumbs: ev.target.checked }); + }); -document.getElementById("color_theme").addEventListener("click", (ev) => { - chrome.storage.sync.set({ colorTheme: ev.target.value }); +document.getElementById("colored_bar")?.addEventListener("click", (ev: any) => { + storage.set({ coloredBar: ev.target.checked }); }); -document.getElementById("number_round_down").addEventListener("click", (ev) => { - chrome.storage.sync.set({ numberDisplayRoundDown: ev.target.checked }); - updateNumberDisplayFormatContent(ev.target.checked); +document.getElementById("color_theme")?.addEventListener("click", (ev: any) => { + storage.set({ colorTheme: ev.target.value }); }); -document.getElementById("number_format").addEventListener("change", (ev) => { - chrome.storage.sync.set({ numberDisplayFormat: ev.target.value }); -}); +document + .getElementById("number_format") + ?.addEventListener("change", (ev: any) => { + storage.set({ numberDisplayFormat: ev.target.value }); + }); document .getElementById("show_tooltip_percentage") - .addEventListener("click", (ev) => { - chrome.storage.sync.set({ showTooltipPercentage: ev.target.checked }); + ?.addEventListener("click", (ev: any) => { + storage.set({ showTooltipPercentage: ev.target.checked }); }); document .getElementById("tooltip_percentage_mode") - .addEventListener("change", (ev) => { - chrome.storage.sync.set({ tooltipPercentageMode: ev.target.value }); + ?.addEventListener("change", (ev: any) => { + storage.set({ tooltipPercentageMode: ev.target.value }); }); document .getElementById("number_reformat_likes") - .addEventListener("click", (ev) => { - chrome.storage.sync.set({ numberDisplayReformatLikes: ev.target.checked }); + ?.addEventListener("click", (ev: any) => { + storage.set({ numberDisplayReformatLikes: ev.target.checked }); }); /* Advanced Toggle */ const advancedToggle = document.getElementById("advancedToggle"); -advancedToggle.addEventListener("click", () => { +advancedToggle?.addEventListener("click", () => { const adv = document.getElementById("advancedSettings"); - if (config.advanced) { + if (config.advanced && adv) { adv.style.transform = "scale(1.1)"; adv.style.pointerEvents = "none"; adv.style.opacity = "0"; advancedToggle.innerHTML = config.showAdvancedMessage; - } else { + } else if (adv) { adv.style.transform = "scale(1)"; adv.style.pointerEvents = "auto"; adv.style.opacity = "1"; @@ -128,14 +140,13 @@ advancedToggle.addEventListener("click", () => { initConfig(); -function initConfig() { +async function initConfig() { initializeDisableVoteSubmission(); initializeVersionNumber(); initializeColoredThumbs(); initializeColoredBar(); initializeColorTheme(); initializeNumberDisplayFormat(); - initializeNumberDisplayRoundDown(); initializeTooltipPercentage(); initializeTooltipPercentageMode(); initializeNumberDisplayReformatLikes(); @@ -143,7 +154,10 @@ function initConfig() { function initializeVersionNumber() { const version = chrome.runtime.getManifest().version; - document.getElementById("ext-version").innerHTML = "v" + version; + const updateLink = document.getElementById("ext-update"); + if (updateLink) { + updateLink.innerHTML = "v" + version; + } fetch( "https://raw.githubusercontent.com/Anarios/return-youtube-dislike/main/Extensions/combined/manifest-chrome.json" @@ -151,23 +165,26 @@ function initializeVersionNumber() { .then((response) => response.json()) .then((json) => { if (compareVersions(json.version, version)) { - document.getElementById("ext-update").innerHTML = - chrome.i18n.getMessage("textUpdate") + " v" + json.version; - document.getElementById("ext-update").style.padding = ".25rem .5rem"; + const updateLink = document.getElementById("ext-update"); + if (updateLink) { + updateLink.innerHTML = + chrome.i18n.getMessage("textUpdate") + " v" + json.version; + updateLink.style.padding = ".25rem .5rem"; + } } }); // .catch(console.error); } // returns whether current < latest -function compareVersions(latestStr, currentStr) { +function compareVersions(latestStr: string, currentStr: string) { let latestarr = latestStr.split("."); let currentarr = currentStr.split("."); let outdated = false; // goes through version numbers from left to right from greatest to least significant for (let i = 0; i < Math.max(latestarr.length, currentarr.length); i++) { - let latest = i < latestarr.length ? parseInt(latestarr[i]) : 0; - let current = i < currentarr.length ? parseInt(currentarr[i]) : 0; + let latest = i < latestarr.length ? parseInt(latestarr[i] as string) : 0; + let current = i < currentarr.length ? parseInt(currentarr[i] as string) : 0; if (latest > current) { outdated = true; break; @@ -179,79 +196,76 @@ function compareVersions(latestStr, currentStr) { return outdated; } +function initializeTooltipPercentage() { + storage.get(["showTooltipPercentage"], (res: any) => { + handleShowTooltipPercentageChangeEvent(res); + }); +} + function initializeDisableVoteSubmission() { - chrome.storage.sync.get(["disableVoteSubmission"], (res) => { + storage.get(["disableVoteSubmission"], (res) => { handleDisableVoteSubmissionChangeEvent(res.disableVoteSubmission); }); } function initializeColoredThumbs() { - chrome.storage.sync.get(["coloredThumbs"], (res) => { + storage.get(["coloredThumbs"], (res) => { handleColoredThumbsChangeEvent(res.coloredThumbs); }); } function initializeColoredBar() { - chrome.storage.sync.get(["coloredBar"], (res) => { + storage.get(["coloredBar"], (res) => { handleColoredBarChangeEvent(res.coloredBar); }); } function initializeColorTheme() { - chrome.storage.sync.get(["colorTheme"], (res) => { + storage.get(["colorTheme"], (res) => { handleColorThemeChangeEvent(res.colorTheme); }); } -function initializeNumberDisplayRoundDown() { - chrome.storage.sync.get(["numberDisplayRoundDown"], (res) => { - handleNumberDisplayRoundDownChangeEvent(res.numberDisplayRoundDown); - }); -} - -function initializeTooltipPercentage() { - chrome.storage.sync.get(["showTooltipPercentage"], (res) => { - handleShowTooltipPercentageChangeEvent(res.showTooltipPercentage); - }); -} - function initializeTooltipPercentageMode() { - chrome.storage.sync.get(["tooltipPercentageMode"], (res) => { + storage.get(["tooltipPercentageMode"], (res) => { handleTooltipPercentageModeChangeEvent(res.tooltipPercentageMode); }); } function initializeNumberDisplayFormat() { - chrome.storage.sync.get(["numberDisplayFormat"], (res) => { + storage.get(["numberDisplayFormat"], (res) => { handleNumberDisplayFormatChangeEvent(res.numberDisplayFormat); }); updateNumberDisplayFormatContent(); } -function updateNumberDisplayFormatContent(roundDown) { - let testValue; - if (roundDown) { - testValue = 123000; - } else { - testValue = 123456; +function updateNumberDisplayFormatContent() { + let testValue = 123456; + const short = document.getElementById("number_format_compactShort"); + const long = document.getElementById("number_format_compactLong"); + const standard = document.getElementById("number_format_standard"); + if (short) { + short.innerHTML = getNumberFormatter("compactShort").format(testValue); + } + if (long) { + long.innerHTML = getNumberFormatter("compactLong").format(testValue); + } + if (standard) { + standard.innerHTML = getNumberFormatter("standard").format(testValue); } - document.getElementById("number_format_compactShort").innerHTML = - getNumberFormatter("compactShort").format(testValue); - document.getElementById("number_format_compactLong").innerHTML = - getNumberFormatter("compactLong").format(testValue); - document.getElementById("number_format_standard").innerHTML = - getNumberFormatter("standard").format(testValue); } function initializeNumberDisplayReformatLikes() { - chrome.storage.sync.get(["numberDisplayReformatLikes"], (res) => { + storage.get(["numberDisplayReformatLikes"], (res) => { handleNumberDisplayReformatLikesChangeEvent(res.numberDisplayReformatLikes); }); } -chrome.storage.onChanged.addListener(storageChangeHandler); +storage.onChanged.addListener(storageChangeHandler); -function storageChangeHandler(changes, area) { +function storageChangeHandler(changes: { + [key: string]: chrome.storage.StorageChange; +}) { if (changes.disableVoteSubmission !== undefined) { handleDisableVoteSubmissionChangeEvent( changes.disableVoteSubmission.newValue @@ -266,11 +280,6 @@ function storageChangeHandler(changes, area) { if (changes.colorTheme !== undefined) { handleColorThemeChangeEvent(changes.colorTheme.newValue); } - if (changes.numberDisplayRoundDown !== undefined) { - handleNumberDisplayRoundDownChangeEvent( - changes.numberDisplayRoundDown.newValue - ); - } if (changes.numberDisplayFormat !== undefined) { handleNumberDisplayFormatChangeEvent(changes.numberDisplayFormat.newValue); } @@ -286,85 +295,137 @@ function storageChangeHandler(changes, area) { } } -function handleDisableVoteSubmissionChangeEvent(value) { +function handleDisableVoteSubmissionChangeEvent(value: boolean) { config.disableVoteSubmission = value; - document.getElementById("disable_vote_submission").checked = value; + const disableVoteSubmission = document.getElementById( + "disable_vote_submission" + ); + if (disableVoteSubmission) { + (disableVoteSubmission as any).checked = value; + } } -function handleColoredThumbsChangeEvent(value) { +function handleColoredThumbsChangeEvent(value: boolean) { config.coloredThumbs = value; - document.getElementById("colored_thumbs").checked = value; + const coloredThumbs = document.getElementById("colored_thumbs"); + if (coloredThumbs) { + (coloredThumbs as any).checked = value; + } } -function handleColoredBarChangeEvent(value) { +function handleColoredBarChangeEvent(value: boolean) { config.coloredBar = value; - document.getElementById("colored_bar").checked = value; + const coloredBar = document.getElementById("colored_bar"); + if (coloredBar) { + (coloredBar as any).checked = value; + } } -function handleColorThemeChangeEvent(value) { +function handleColorThemeChangeEvent(value: "classic" | "neon" | "accessible") { if (!value) { value = "classic"; } config.colorTheme = value; - document - .getElementById("color_theme") - .querySelector('option[value="' + value + '"]').selected = true; + const colorTheme = document.getElementById("color_theme"); + const themeOption = colorTheme?.querySelector( + 'option[value="' + value + '"]' + ); + if (themeOption) { + (themeOption as any).selected = true; + } updateColorThemePreviewContent(value); } -function updateColorThemePreviewContent(themeName) { - document.getElementById("color_theme_example_like").style.backgroundColor = - getColorFromTheme(themeName, true); - document.getElementById("color_theme_example_dislike").style.backgroundColor = - getColorFromTheme(themeName, false); -} - -function handleNumberDisplayRoundDownChangeEvent(value) { - config.numberDisplayRoundDown = value; - document.getElementById("number_round_down").checked = value; +function updateColorThemePreviewContent(colorTheme: ColorTheme) { + const colorThemeExampleLike = document.getElementById( + "color_theme_example_like" + ); + if (colorThemeExampleLike) { + colorThemeExampleLike.style.backgroundColor = getColorFromTheme( + colorTheme, + true + ); + } + const colorThemeExampleDislike = document.getElementById( + "color_theme_example_dislike" + ); + if (colorThemeExampleDislike) { + colorThemeExampleDislike.style.backgroundColor = getColorFromTheme( + colorTheme, + false + ); + } } -function handleNumberDisplayFormatChangeEvent(value) { +function handleNumberDisplayFormatChangeEvent(value: NumberDisplayFormat) { config.numberDisplayFormat = value; - document - .getElementById("number_format") - .querySelector('option[value="' + value + '"]').selected = true; + const numberFormat = document.getElementById("number_format"); + const formatOption = numberFormat?.querySelector( + 'option[value="' + value + '"]' + ); + if (formatOption) { + (formatOption as any).selected = true; + } } -function handleShowTooltipPercentageChangeEvent(value) { +function handleShowTooltipPercentageChangeEvent(value: boolean) { config.showTooltipPercentage = value; - document.getElementById("show_tooltip_percentage").checked = value; + const showTooltipPercentage = document.getElementById( + "show_tooltip_percentage" + ) as HTMLInputElement; + if (showTooltipPercentage) { + showTooltipPercentage.checked = value; + } } -function handleTooltipPercentageModeChangeEvent(value) { +function handleTooltipPercentageModeChangeEvent(value: TooltipPercentageMode) { if (!value) { value = "dash_like"; } config.tooltipPercentageMode = value; - - document - .getElementById("tooltip_percentage_mode") - .querySelector('option[value="' + value + '"]').selected = true; + const tooltipPercentageMode = document.getElementById( + "tooltip_percentage_mode" + ); + const modeOption = tooltipPercentageMode?.querySelector( + 'option[value="' + value + '"]' + ); + if (modeOption) { + (modeOption as any).selected = true; + } } -function handleNumberDisplayReformatLikesChangeEvent(value) { +function handleNumberDisplayReformatLikesChangeEvent(value: boolean) { config.numberDisplayReformatLikes = value; - document.getElementById("number_reformat_likes").checked = value; + const numberReformatLikes = document.getElementById("number_reformat_likes"); + if (numberReformatLikes) { + (numberReformatLikes as any).checked = value; + } } -function getNumberFormatter(optionSelect) { - let formatterNotation; - let formatterCompactDisplay; +function getNumberFormatter( + numberDisplayFormat: "compactShort" | "compactLong" | "standard" +) { + let formatterNotation: Intl.NumberFormatOptions["notation"]; + let formatterCompactDisplay: Intl.NumberFormatOptions["compactDisplay"]; let userLocales; try { - userLocales = new URL( - Array.from(document.querySelectorAll("head > link[rel='search']")) - ?.find((n) => n?.getAttribute("href")?.includes("?locale=")) - ?.getAttribute("href") - )?.searchParams?.get("locale"); + const searchLinks = document.querySelectorAll("head > link[rel='search']"); + const searchLink = Array.from(searchLinks).find((n) => { + return n?.getAttribute("href")?.includes("?locale="); + }); + const href = searchLink?.getAttribute("href"); + if (!href) { + throw new Error("No href found"); + } + const url = new URL(href); + const searchParams = url.searchParams; + if (!searchParams) { + throw new Error("No searchParams found"); + } + userLocales = searchParams.get("locale"); } catch {} - switch (optionSelect) { + switch (numberDisplayFormat) { case "compactLong": formatterNotation = "compact"; formatterCompactDisplay = "long"; @@ -396,19 +457,30 @@ function getNumberFormatter(optionSelect) { ); let result = await resp.status; if (result === 200) { - status.innerText = "Online"; - status.style.color = "green"; - serverStatus.style.filter = - "invert(58%) sepia(81%) saturate(2618%) hue-rotate(81deg) brightness(119%) contrast(129%)"; + if (status) { + status.innerText = "Online"; + status.style.color = "green"; + } + if (serverStatus) { + serverStatus.style.filter = + "invert(58%) sepia(81%) saturate(2618%) hue-rotate(81deg) brightness(119%) contrast(129%)"; + } } else { - status.innerText = "Offline"; - status.style.color = "red"; - serverStatus.style.filter = - "invert(11%) sepia(100%) saturate(6449%) hue-rotate(3deg) brightness(116%) contrast(115%)"; + if (status) { + status.innerText = "Offline"; + status.style.color = "red"; + } + if (serverStatus) { + serverStatus.style.filter = + "invert(11%) sepia(100%) saturate(6449%) hue-rotate(3deg) brightness(116%) contrast(115%)"; + } } })(); -function getColorFromTheme(colorTheme, voteIsLike) { +function getColorFromTheme( + colorTheme: "accessible" | "neon" | "classic", + voteIsLike: boolean +) { let colorString; switch (colorTheme) { case "accessible": @@ -435,15 +507,3 @@ function getColorFromTheme(colorTheme, voteIsLike) { } return colorString; } - -/* popup-script.js -document.querySelector('#login') -.addEventListener('click', function () { - chrome.runtime.sendMessage({ message: 'get_auth_token' }); -}); - - -document.querySelector("#log_off").addEventListener("click", function () { - chrome.runtime.sendMessage({ message: "log_off" }); -}); -*/ diff --git a/Extensions/combined/readme.md b/Extensions/combined/readme.md index 0818eb31..faee2306 100644 --- a/Extensions/combined/readme.md +++ b/Extensions/combined/readme.md @@ -6,7 +6,7 @@
  1. Go to the root directory of the project
  2. -
  3. Run npm i to install all project dependancies (if not done so already)
  4. +
  5. Run npm i to install all project dependencies (if not done so already)
  6. run npm run dev to compile the extension to the ~/Extensions/combined/dist/ folder.
diff --git a/Extensions/combined/ryd.background.js b/Extensions/combined/ryd.background.ts similarity index 55% rename from Extensions/combined/ryd.background.js rename to Extensions/combined/ryd.background.ts index c416da94..458fba19 100644 --- a/Extensions/combined/ryd.background.js +++ b/Extensions/combined/ryd.background.ts @@ -1,106 +1,109 @@ +import { ColorTheme, ExtConfig, NumberDisplayFormat } from "./src/types"; +import { getBrowser } from "./src/utils"; + const apiUrl = "https://returnyoutubedislikeapi.com"; const voteDisabledIconName = "icon_hold128.png"; const defaultIconName = "icon128.png"; -let api; +let api = getBrowser(); /** stores extension's global config */ -let extConfig = { +let extConfig: ExtConfig = { disableVoteSubmission: false, coloredThumbs: false, coloredBar: false, colorTheme: "classic", // classic, accessible, neon numberDisplayFormat: "compactShort", // compactShort, compactLong, standard - numberDisplayRoundDown: true, // locale 'de' shows exact numbers by default numberDisplayReformatLikes: false, // use existing (native) likes number + showTooltipPercentage: undefined, + tooltipPercentageMode: undefined, }; -if (isChrome()) api = chrome; -else if (isFirefox()) api = browser; - initExtConfig(); -api.runtime.onMessage.addListener((request, sender, sendResponse) => { - if (request.message === "get_auth_token") { - chrome.identity.getAuthToken({ interactive: true }, function (token) { - console.log(token); - chrome.identity.getProfileUserInfo(function (userInfo) { - console.log(JSON.stringify(userInfo)); - }); - }); - } else if (request.message === "log_off") { - // chrome.identity.clearAllCachedAuthTokens(() => console.log("logged off")); - } else if (request.message == "set_state") { - // chrome.identity.getAuthToken({ interactive: true }, function (token) { - let token = ""; - fetch( - `${apiUrl}/votes?videoId=${request.videoId}&likeCount=${ - request.likeCount || "" - }`, - { - method: "GET", - headers: { - Accept: "application/json", - }, - } - ) - .then((response) => response.json()) - .then((response) => { - sendResponse(response); - }) - .catch(); - return true; - } else if (request.message == "send_links") { - toSend = toSend.concat(request.videoIds.filter((x) => !sentIds.has(x))); - if (toSend.length >= 20) { - fetch(`${apiUrl}/votes`, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(toSend), +api.runtime.onMessage.addListener( + ( + request: any, + _: chrome.runtime.MessageSender, + sendResponse: (response?: any) => void + ) => { + if (request.message === "get_auth_token") { + chrome.identity.getAuthToken({ interactive: true }, function (token) { + console.log(token); + chrome.identity.getProfileUserInfo(function (userInfo) { + console.log(JSON.stringify(userInfo)); + }); }); - for (const toSendUrl of toSend) { - sentIds.add(toSendUrl); + } else if (request.message === "log_off") { + // chrome.identity.clearAllCachedAuthTokens(() => console.log("logged off")); + } else if (request.message == "set_state") { + // chrome.identity.getAuthToken({ interactive: true }, function (token) { + fetch( + `${apiUrl}/votes?videoId=${request.videoId}&likeCount=${ + request.likeCount || "" + }`, + { + method: "GET", + headers: { + Accept: "application/json", + }, + } + ) + .then((response) => response.json()) + .then((response) => { + sendResponse(response); + }) + .catch(); + return true; + } else if (request.message == "send_links") { + toSend = toSend.concat( + request.videoIds.filter((x: string) => !sentIds.has(x)) + ); + if (toSend.length >= 20) { + fetch(`${apiUrl}/votes`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(toSend), + }); + for (const toSendUrl of toSend) { + sentIds.add(toSendUrl); + } + toSend = []; } - toSend = []; + } else if (request.message == "register") { + register(); + return true; + } else if (request.message == "send_vote") { + sendVote(request.videoId, request.vote); + return true; } - } else if (request.message == "register") { - register(); - return true; - } else if (request.message == "send_vote") { - sendVote(request.videoId, request.vote); - return true; + console.warn("Unknown message received", request); + return; } -}); +); -api.runtime.onInstalled.addListener((details) => { +api.runtime.onInstalled.addListener((details: any) => { + const reason: chrome.runtime.InstalledDetails["reason"] | "browser_update" = + details.reason; if ( // No need to show changelog if its was a browser update (and not extension update) - details.reason === "browser_update" || + reason === "browser_update" || // Chromium (e.g., Google Chrome Cannary) uses this name instead of the one above for some reason - details.reason === "chrome_update" || + reason === "chrome_update" || // No need to show changelog if developer just reloaded the extension - details.reason === "update" - ) + reason === "update" + ) { return; - api.tabs.create({ - url: api.runtime.getURL("/changelog/3/changelog_3.0.html"), - }); + } else if (details.reason == "install") { + api.tabs.create({ + url: api.runtime.getURL("/changelog/3/changelog_3.0.html"), + }); + } }); -// api.storage.sync.get(['lastShowChangelogVersion'], (details) => { -// if (extConfig.showUpdatePopup === true && -// details.lastShowChangelogVersion !== chrome.runtime.getManifest().version -// ) { -// // keep it inside get to avoid race condition -// api.storage.sync.set({'lastShowChangelogVersion ': chrome.runtime.getManifest().version}); -// // wait until async get runs & don't steal tab focus -// api.tabs.create({url: api.runtime.getURL("/changelog/3/changelog_3.0.html"), active: false}); -// } -// }); - -async function sendVote(videoId, vote) { - api.storage.sync.get(null, async (storageResult) => { +async function sendVote(videoId: string, vote: 0 | 1 | -1) { + api.storage.sync.get(null, async (storageResult: { [key: string]: any }) => { if (!storageResult.userId || !storageResult.registrationConfirmed) { await register(); } @@ -171,19 +174,20 @@ async function register() { } } -api.storage.sync.get(null, async (res) => { +api.storage.sync.get(null, async (res: any) => { if (!res || !res.userId || !res.registrationConfirmed) { await register(); } }); const sentIds = new Set(); -let toSend = []; +let toSend: any[] = []; -function countLeadingZeroes(uInt8View, limit) { +function countLeadingZeroes(uInt8View: Uint8Array, limit?: number) { let zeroes = 0; let value = 0; for (let i = 0; i < uInt8View.length; i++) { + // @ts-ignore value = uInt8View[i]; if (value === 0) { zeroes += 8; @@ -200,14 +204,14 @@ function countLeadingZeroes(uInt8View, limit) { zeroes += count - (value >>> 7); break; } - if (zeroes >= limit) { + if (limit && zeroes >= limit) { break; } } return zeroes; } -async function solvePuzzle(puzzle) { +async function solvePuzzle(puzzle: { challenge: string; difficulty: number }) { let challenge = Uint8Array.from(atob(puzzle.challenge), (c) => c.charCodeAt(0) ); @@ -216,6 +220,7 @@ async function solvePuzzle(puzzle) { let uInt32View = new Uint32Array(buffer); let maxCount = Math.pow(2, puzzle.difficulty) * 3; for (let i = 4; i < 20; i++) { + //@ts-ignore uInt8View[i] = challenge[i - 4]; } @@ -240,7 +245,10 @@ function generateUserID(length = 36) { const values = new Uint32Array(length); crypto.getRandomValues(values); for (let i = 0; i < length; i++) { - result += charset[values[i] % charset.length]; + const value = values[i]!; + const idx = value % charset.length; + const char = charset[idx]; + result += char; } return result; } else { @@ -251,7 +259,9 @@ function generateUserID(length = 36) { } } -function storageChangeHandler(changes, area) { +function storageChangeHandler(changes: { + [key: string]: chrome.storage.StorageChange; +}) { if (changes.disableVoteSubmission !== undefined) { handleDisableVoteSubmissionChangeEvent( changes.disableVoteSubmission.newValue @@ -266,11 +276,6 @@ function storageChangeHandler(changes, area) { if (changes.colorTheme !== undefined) { handleColorThemeChangeEvent(changes.colorTheme.newValue); } - if (changes.numberDisplayRoundDown !== undefined) { - handleNumberDisplayRoundDownChangeEvent( - changes.numberDisplayRoundDown.newValue - ); - } if (changes.numberDisplayFormat !== undefined) { handleNumberDisplayFormatChangeEvent(changes.numberDisplayFormat.newValue); } @@ -291,7 +296,7 @@ function storageChangeHandler(changes, area) { } } -function handleDisableVoteSubmissionChangeEvent(value) { +function handleDisableVoteSubmissionChangeEvent(value: boolean) { extConfig.disableVoteSubmission = value; if (value === true) { changeIcon(voteDisabledIconName); @@ -300,26 +305,15 @@ function handleDisableVoteSubmissionChangeEvent(value) { } } -function handleNumberDisplayFormatChangeEvent(value) { +function handleNumberDisplayFormatChangeEvent(value: NumberDisplayFormat) { extConfig.numberDisplayFormat = value; } -function handleShowTooltipPercentageChangeEvent(value) { +function handleShowTooltipPercentageChangeEvent(value: boolean | undefined) { extConfig.showTooltipPercentage = value; } -function handleTooltipPercentageModeChangeEvent(value) { - if (!value) { - value = "dash_like"; - } - extConfig.tooltipPercentageMode = value; -} - -function handleNumberDisplayRoundDownChangeEvent(value) { - extConfig.numberDisplayRoundDown = value; -} - -function changeIcon(iconName) { +function changeIcon(iconName: string) { if (api.action !== undefined) api.action.setIcon({ path: "/icons/" + iconName }); else if (api.browserAction !== undefined) @@ -327,22 +321,22 @@ function changeIcon(iconName) { else console.log("changing icon is not supported"); } -function handleColoredThumbsChangeEvent(value) { +function handleColoredThumbsChangeEvent(value: boolean) { extConfig.coloredThumbs = value; } -function handleColoredBarChangeEvent(value) { +function handleColoredBarChangeEvent(value: boolean) { extConfig.coloredBar = value; } -function handleColorThemeChangeEvent(value) { +function handleColorThemeChangeEvent(value: ColorTheme) { if (!value) { value = "classic"; } extConfig.colorTheme = value; } -function handleNumberDisplayReformatLikesChangeEvent(value) { +function handleNumberDisplayReformatLikesChangeEvent(value: boolean) { extConfig.numberDisplayReformatLikes = value; } @@ -354,25 +348,27 @@ function initExtConfig() { initializeColoredBar(); initializeColorTheme(); initializeNumberDisplayFormat(); - initializeNumberDisplayRoundDown(); initializeNumberDisplayReformatLikes(); initializeTooltipPercentage(); initializeTooltipPercentageMode(); } function initializeDisableVoteSubmission() { - api.storage.sync.get(["disableVoteSubmission"], (res) => { - if (res.disableVoteSubmission === undefined) { - api.storage.sync.set({ disableVoteSubmission: false }); - } else { - extConfig.disableVoteSubmission = res.disableVoteSubmission; - if (res.disableVoteSubmission) changeIcon(voteDisabledIconName); + api.storage.sync.get( + ["disableVoteSubmission"], + (res: { [key: string]: any }) => { + if (res.disableVoteSubmission === undefined) { + api.storage.sync.set({ disableVoteSubmission: false }); + } else { + extConfig.disableVoteSubmission = res.disableVoteSubmission; + if (res.disableVoteSubmission) changeIcon(voteDisabledIconName); + } } - }); + ); } function initializeColoredThumbs() { - api.storage.sync.get(["coloredThumbs"], (res) => { + api.storage.sync.get(["coloredThumbs"], (res: { [key: string]: any }) => { if (res.coloredThumbs === undefined) { api.storage.sync.set({ coloredThumbs: false }); } else { @@ -381,18 +377,8 @@ function initializeColoredThumbs() { }); } -function initializeNumberDisplayRoundDown() { - api.storage.sync.get(["numberDisplayRoundDown"], (res) => { - if (res.numberDisplayRoundDown === undefined) { - api.storage.sync.set({ numberDisplayRoundDown: true }); - } else { - extConfig.numberDisplayRoundDown = res.numberDisplayRoundDown; - } - }); -} - function initializeColoredBar() { - api.storage.sync.get(["coloredBar"], (res) => { + api.storage.sync.get(["coloredBar"], (res: { [key: string]: any }) => { if (res.coloredBar === undefined) { api.storage.sync.set({ coloredBar: false }); } else { @@ -402,7 +388,7 @@ function initializeColoredBar() { } function initializeColorTheme() { - api.storage.sync.get(["colorTheme"], (res) => { + api.storage.sync.get(["colorTheme"], (res: { [key: string]: any }) => { if (res.colorTheme === undefined) { api.storage.sync.set({ colorTheme: false }); } else { @@ -412,51 +398,53 @@ function initializeColorTheme() { } function initializeNumberDisplayFormat() { - api.storage.sync.get(["numberDisplayFormat"], (res) => { - if (res.numberDisplayFormat === undefined) { - api.storage.sync.set({ numberDisplayFormat: "compactShort" }); - } else { - extConfig.numberDisplayFormat = res.numberDisplayFormat; + api.storage.sync.get( + ["numberDisplayFormat"], + (res: { [key: string]: any }) => { + if (res.numberDisplayFormat === undefined) { + api.storage.sync.set({ numberDisplayFormat: "compactShort" }); + } else { + extConfig.numberDisplayFormat = res.numberDisplayFormat; + } } - }); + ); } function initializeTooltipPercentage() { - api.storage.sync.get(["showTooltipPercentage"], (res) => { - if (res.showTooltipPercentage === undefined) { - api.storage.sync.set({ showTooltipPercentage: false }); - } else { - extConfig.showTooltipPercentage = res.showTooltipPercentage; + api.storage.sync.get( + ["showTooltipPercentage"], + (res: { [key: string]: any }) => { + if (res.showTooltipPercentage === undefined) { + api.storage.sync.set({ showTooltipPercentage: false }); + } else { + extConfig.showTooltipPercentage = res.showTooltipPercentage; + } } - }); + ); } function initializeTooltipPercentageMode() { - api.storage.sync.get(["tooltipPercentageMode"], (res) => { - if (res.tooltipPercentageMode === undefined) { - api.storage.sync.set({ tooltipPercentageMode: "dash_like" }); - } else { - extConfig.tooltipPercentageMode = res.tooltipPercentageMode; + api.storage.sync.get( + ["tooltipPercentageMode"], + (res: { [key: string]: any }) => { + if (res.tooltipPercentageMode === undefined) { + api.storage.sync.set({ tooltipPercentageMode: "dash_like" }); + } else { + extConfig.tooltipPercentageMode = res.tooltipPercentageMode; + } } - }); + ); } function initializeNumberDisplayReformatLikes() { - api.storage.sync.get(["numberDisplayReformatLikes"], (res) => { - if (res.numberDisplayReformatLikes === undefined) { - api.storage.sync.set({ numberDisplayReformatLikes: false }); - } else { - extConfig.numberDisplayReformatLikes = res.numberDisplayReformatLikes; + api.storage.sync.get( + ["numberDisplayReformatLikes"], + (res: { [key: string]: any }) => { + if (res.numberDisplayReformatLikes === undefined) { + api.storage.sync.set({ numberDisplayReformatLikes: false }); + } else { + extConfig.numberDisplayReformatLikes = res.numberDisplayReformatLikes; + } } - }); -} - -function isChrome() { - return typeof chrome !== "undefined" && typeof chrome.runtime !== "undefined"; -} - -function isFirefox() { - return ( - typeof browser !== "undefined" && typeof browser.runtime !== "undefined" ); } diff --git a/Extensions/combined/ryd.content-script.js b/Extensions/combined/ryd.content-script.js deleted file mode 100644 index a07dd994..00000000 --- a/Extensions/combined/ryd.content-script.js +++ /dev/null @@ -1,68 +0,0 @@ -//--- Import Button Functions ---// -import { - getButtons, - getLikeButton, - getDislikeButton, - checkForSignInButton, -} from "./src/buttons"; - -//--- Import State Functions ---// -import { - isMobile, - isShorts, - isVideoDisliked, - isVideoLiked, - getState, - setState, - setInitialState, - setLikes, - setDislikes, - getLikeCountFromButton, - LIKED_STATE, - DISLIKED_STATE, - NEUTRAL_STATE, - initExtConfig, -} from "./src/state"; - -//--- Import Video & Browser Functions ---// -import { - numberFormat, - getBrowser, - getVideoId, - isVideoLoaded, - cLog, -} from "./src/utils"; -import { createRateBar } from "./src/bar"; -import { - sendVote, - likeClicked, - dislikeClicked, - addLikeDislikeEventListener, - storageChangeHandler, -} from "./src/events"; - -initExtConfig(); - -let jsInitChecktimer = null; - -function setEventListeners(evt) { - function checkForJS_Finish() { - if (isShorts() || (getButtons()?.offsetParent && isVideoLoaded())) { - addLikeDislikeEventListener(); - setInitialState(); - getBrowser().storage.onChanged.addListener(storageChangeHandler); - clearInterval(jsInitChecktimer); - jsInitChecktimer = null; - } - } - - jsInitChecktimer = setInterval(checkForJS_Finish, 111); -} - -setEventListeners(); - -document.addEventListener("yt-navigate-finish", function (event) { - if (jsInitChecktimer !== null) clearInterval(jsInitChecktimer); - window.returnDislikeButtonlistenersSet = false; - setEventListeners(); -}); diff --git a/Extensions/combined/ryd.content-script.ts b/Extensions/combined/ryd.content-script.ts new file mode 100644 index 00000000..81091f63 --- /dev/null +++ b/Extensions/combined/ryd.content-script.ts @@ -0,0 +1,51 @@ +//--- Import Button Functions ---// +import { getButtons } from "./src/buttons"; + +//--- Import State Functions ---// +import { initExtConfig, isShorts, setInitialState } from "./src/state"; + +//--- Import Video & Browser Functions ---// +import { + addLikeDislikeEventListener, + storageChangeHandler, +} from "./src/events"; +import { getBrowser, isVideoLoaded } from "./src/utils"; + +initExtConfig(); + +let jsInitChecktimer: any; +let isSetInitialStateDone: boolean = false; + +function setEventListeners(): void { + function checkForJS_Finish(): void { + try { + if ( + isShorts() || + ((getButtons() as HTMLElement)?.offsetParent && isVideoLoaded()) + ) { + addLikeDislikeEventListener(); + setInitialState(); + isSetInitialStateDone = true; + getBrowser().storage.onChanged.addListener(storageChangeHandler); + if (jsInitChecktimer !== null) { + clearInterval(jsInitChecktimer); + jsInitChecktimer = null; + } + } + } catch (exception: unknown) { + if (!isSetInitialStateDone) { + setInitialState(); + } + } + } + + jsInitChecktimer = setInterval(checkForJS_Finish, 111); +} + +setEventListeners(); + +document.addEventListener("yt-navigate-finish", function () { + if (jsInitChecktimer !== null) clearInterval(jsInitChecktimer); + window.returnDislikeButtonlistenersSet = false; // Consider adding a type for `window.returnDislikeButtonlistenersSet` + setEventListeners(); +}); diff --git a/Extensions/combined/src/bar.js b/Extensions/combined/src/bar.js deleted file mode 100644 index 55f21ed7..00000000 --- a/Extensions/combined/src/bar.js +++ /dev/null @@ -1,116 +0,0 @@ -import { getButtons } from "./buttons"; -import { - extConfig, - isMobile, - isLikesDisabled, - isNewDesign, - isShorts, -} from "./state"; -import { cLog, getColorFromTheme } from "./utils"; - -function createRateBar(likes, dislikes) { - if (!isLikesDisabled()) { - let rateBar = document.getElementById("ryd-bar-container"); - - const widthPx = - getButtons().children[0].clientWidth + - getButtons().children[1].clientWidth + - 8; - - const widthPercent = - likes + dislikes > 0 ? (likes / (likes + dislikes)) * 100 : 50; - - var likePercentage = parseFloat(widthPercent.toFixed(1)); - const dislikePercentage = (100 - likePercentage).toLocaleString(); - likePercentage = likePercentage.toLocaleString(); - - if (extConfig.showTooltipPercentage) { - var tooltipInnerHTML; - switch (extConfig.tooltipPercentageMode) { - case "dash_dislike": - tooltipInnerHTML = `${likes.toLocaleString()} / ${dislikes.toLocaleString()}  -  ${dislikePercentage}%`; - break; - case "both": - tooltipInnerHTML = `${likePercentage}% / ${dislikePercentage}%`; - break; - case "only_like": - tooltipInnerHTML = `${likePercentage}%`; - break; - case "only_dislike": - tooltipInnerHTML = `${dislikePercentage}%`; - break; - default: // dash_like - tooltipInnerHTML = `${likes.toLocaleString()} / ${dislikes.toLocaleString()}  -  ${likePercentage}%`; - } - } else { - tooltipInnerHTML = `${likes.toLocaleString()} / ${dislikes.toLocaleString()}`; - } - - if (!isShorts()) { - if (!rateBar && !isMobile()) { - let colorLikeStyle = ""; - let colorDislikeStyle = ""; - if (extConfig.coloredBar) { - colorLikeStyle = "; background-color: " + getColorFromTheme(true); - colorDislikeStyle = "; background-color: " + getColorFromTheme(false); - } - - ( - document.getElementById( - isNewDesign() ? "actions-inner" : "menu-container" - ) || document.querySelector("ytm-slim-video-action-bar-renderer") - ).insertAdjacentHTML( - "beforeend", - ` -
-
-
-
-
-
- - ${tooltipInnerHTML} - -
- ` - ); - - // Add border between info and comments - if (isNewDesign()) { - let descriptionAndActionsElement = document.getElementById("top-row"); - descriptionAndActionsElement.style.borderBottom = - "1px solid var(--yt-spec-10-percent-layer)"; - descriptionAndActionsElement.style.paddingBottom = "10px"; - } - } else { - document.getElementById("ryd-bar-container").style.width = - widthPx + "px"; - document.getElementById("ryd-bar").style.width = widthPercent + "%"; - document.querySelector("#ryd-dislike-tooltip > #tooltip").innerHTML = - tooltipInnerHTML; - if (extConfig.coloredBar) { - document.getElementById("ryd-bar-container").style.backgroundColor = - getColorFromTheme(false); - document.getElementById("ryd-bar").style.backgroundColor = - getColorFromTheme(true); - } - } - } - } else { - cLog("removing bar"); - let ratebar = document.getElementById("ryd-bar-container"); - if (ratebar) { - ratebar.parentNode.removeChild(ratebar); - } - } -} - -export { createRateBar }; diff --git a/Extensions/combined/src/bar.ts b/Extensions/combined/src/bar.ts new file mode 100644 index 00000000..b8484a8a --- /dev/null +++ b/Extensions/combined/src/bar.ts @@ -0,0 +1,164 @@ +import { getButtons, getDislikeButton, getLikeButton } from "./buttons"; +import { + extConfig, + isLikesDisabled, + isMobile, + isNewDesign, + isRoundedDesign, + isShorts, +} from "./state"; +import { cLog, getColorFromTheme, isInViewport } from "./utils"; + +function createRateBar(likes: number, dislikes: number) { + let rateBar = document.getElementById("ryd-bar-container"); + if (!isLikesDisabled()) { + // sometimes rate bar is hidden + if (rateBar && !isInViewport(rateBar)) { + rateBar.remove(); + rateBar = null; + } + + const likeButtonWidth = getLikeButton()?.clientWidth; + const dislikeButtonWidth = getDislikeButton()?.clientWidth; + + if (!likeButtonWidth || !dislikeButtonWidth) { + console.error("like or dislike button width is 0"); + return; + } + + const widthPx = + likeButtonWidth + dislikeButtonWidth + (isRoundedDesign() ? 0 : 8); + + const widthPercent = + likes + dislikes > 0 ? (likes / (likes + dislikes)) * 100 : 50; + + var likePercentage: number | string = parseFloat(widthPercent.toFixed(1)); + const dislikePercentage = (100 - likePercentage).toLocaleString(); + likePercentage = likePercentage.toLocaleString(); + + if (extConfig.showTooltipPercentage) { + var tooltipInnerHTML; + switch (extConfig.tooltipPercentageMode) { + case "dash_dislike": + tooltipInnerHTML = `${likes.toLocaleString()} / ${dislikes.toLocaleString()}  -  ${dislikePercentage}%`; + break; + case "both": + tooltipInnerHTML = `${likePercentage}% / ${dislikePercentage}%`; + break; + case "only_like": + tooltipInnerHTML = `${likePercentage}%`; + break; + case "only_dislike": + tooltipInnerHTML = `${dislikePercentage}%`; + break; + default: // dash_like + tooltipInnerHTML = `${likes.toLocaleString()} / ${dislikes.toLocaleString()}  -  ${likePercentage}%`; + } + } else { + tooltipInnerHTML = `${likes.toLocaleString()} / ${dislikes.toLocaleString()}`; + } + + if (!isShorts()) { + if (!rateBar && !isMobile()) { + let colorLikeStyle = ""; + let colorDislikeStyle = ""; + if (extConfig.coloredBar) { + colorLikeStyle = "; background-color: " + getColorFromTheme(true); + colorDislikeStyle = "; background-color: " + getColorFromTheme(false); + } + let actions = + isNewDesign() && getButtons()?.id === "top-level-buttons-computed" + ? getButtons() + : document.getElementById("menu-container"); + ( + actions || + document.querySelector("ytm-slim-video-action-bar-renderer") + )?.insertAdjacentHTML( + "beforeend", + ` +
+
+
+
+
+
+ + ${tooltipInnerHTML} + +
+ ` + ); + + if (isNewDesign()) { + // Add border between info and comments + let descriptionAndActionsElement = document.getElementById("top-row"); + if (!descriptionAndActionsElement) { + console.error("descriptionAndActionsElement not found"); + return; + } + descriptionAndActionsElement.style.borderBottom = + "1px solid var(--yt-spec-10-percent-layer)"; + descriptionAndActionsElement.style.paddingBottom = "10px"; + + // Fix like/dislike ratio bar offset in new UI + const actionsInner = document.getElementById("actions-inner"); + if (!actionsInner) { + console.error("actionsInner not found"); + return; + } + actionsInner.style.width = "revert"; + if (isRoundedDesign()) { + const actions = document.getElementById("actions"); + if (!actions) { + console.error("actions not found"); + return; + } + actions.style.flexDirection = "row-reverse"; + } + } + } else { + const barContainer = document.getElementById("ryd-bar-container"); + if (!barContainer) { + console.error("barContainer not found"); + return; + } + barContainer.style.width = widthPx + "px"; + + const bar = document.getElementById("ryd-bar"); + if (!bar) { + console.error("bar not found"); + return; + } + bar.style.width = widthPercent + "%"; + + const tooltip = document.getElementById( + "#ryd-dislike-tooltip > #tooltip" + ); + if (!tooltip) { + console.error("tooltip not found"); + return; + } + tooltip.innerHTML = tooltipInnerHTML; + if (extConfig.coloredBar) { + barContainer.style.backgroundColor = getColorFromTheme(false); + bar.style.backgroundColor = getColorFromTheme(true); + } + } + } + } else { + cLog("removing bar"); + if (rateBar && rateBar.parentNode) { + rateBar.parentNode.removeChild(rateBar); + } + } +} + +export { createRateBar }; diff --git a/Extensions/combined/src/buttons.js b/Extensions/combined/src/buttons.js deleted file mode 100644 index 95ba1c63..00000000 --- a/Extensions/combined/src/buttons.js +++ /dev/null @@ -1,55 +0,0 @@ -import { isMobile, isShorts } from "./state"; -import { isInViewport } from "./utils"; - -function getButtons() { - //--- If Watching Youtube Shorts: ---// - if (isShorts()) { - let elements = document.querySelectorAll( - isMobile() - ? "ytm-like-button-renderer" - : "#like-button > ytd-like-button-renderer" - ); - for (let element of elements) { - //Youtube Shorts can have multiple like/dislike buttons when scrolling through videos - //However, only one of them should be visible (no matter how you zoom) - if (isInViewport(element)) { - return element; - } - } - } - //--- If Watching On Mobile: ---// - if (isMobile()) { - return document.querySelector(".slim-video-action-bar-actions"); - } - //--- If Menu Element Is Displayed: ---// - if (document.getElementById("menu-container")?.offsetParent === null) { - return document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div"); - //--- If Menu Element Isnt Displayed: ---// - } else { - return document - .getElementById("menu-container") - ?.querySelector("#top-level-buttons-computed"); - } -} - -function getLikeButton() { - return getButtons().children[0]; -} - -function getDislikeButton() { - return getButtons().children[1]; -} - -function checkForSignInButton() { - if ( - document.querySelector( - "a[href^='https://accounts.google.com/ServiceLogin']" - ) - ) { - return true; - } else { - return false; - } -} - -export { getButtons, getLikeButton, getDislikeButton, checkForSignInButton }; diff --git a/Extensions/combined/src/buttons.ts b/Extensions/combined/src/buttons.ts new file mode 100644 index 00000000..e53c771b --- /dev/null +++ b/Extensions/combined/src/buttons.ts @@ -0,0 +1,172 @@ +import { isMobile, isShorts } from "./state"; +import { isInViewport } from "./utils"; + +function getButtons() { + //--- If Watching Youtube Shorts: ---// + if (isShorts()) { + let elements: NodeListOf; + if (isMobile()) { + elements = document.querySelectorAll("ytm-like-button-renderer"); + } else { + elements = document.querySelectorAll( + "#like-button > ytd-like-button-renderer" + ); + } + for (let element of Array.from(elements)) { + //Youtube Shorts can have multiple like/dislike buttons when scrolling through videos + //However, only one of them should be visible (no matter how you zoom) + if (isInViewport(element)) { + return element; + } + } + } + //--- If Watching On Mobile: ---// + if (isMobile()) { + return document.querySelector(".slim-video-action-bar-actions"); + } + //--- If Menu Element Is Displayed: ---// + if (document.getElementById("menu-container")?.offsetParent === null) { + return document.querySelector("ytd-menu-renderer.ytd-watch-metadata > div"); + //--- If Menu Element Isn't Displayed: ---// + } else { + return document + .getElementById("menu-container") + ?.querySelector("#top-level-buttons-computed"); + } +} + +function getLikeButton(): HTMLElement | undefined { + const buttons = getButtons(); + if (!buttons) { + console.error("buttons not found"); + return; + } + + const children = buttons.children; + if (children.length === 0) { + console.error("like button not found"); + return; + } + + const firstChild = children[0] as HTMLElement; + if (firstChild.tagName === "YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER") { + const segmentedLikeButton = document.getElementById( + "segmented-like-button" + ); + if (segmentedLikeButton) { + return segmentedLikeButton; + } + + const grandChildren = firstChild.children; + if (grandChildren.length > 0) { + return grandChildren[0] as HTMLElement; + } + } else { + return firstChild; + } + console.error("like button not found"); + return; +} + +function getLikeTextContainer() { + return ( + getLikeButton()?.querySelector("#text") ?? + getLikeButton()?.getElementsByTagName("yt-formatted-string")[0] ?? + getLikeButton()?.querySelector("span[role='text']") + ); +} + +function getDislikeButton() { + const buttons = getButtons(); + if (!buttons) { + console.error("buttons not found"); + return; + } + + const children = buttons.children; + if (children.length === 0) { + console.error("dislike button not found"); + return; + } + + const firstChild = children[0] as HTMLElement; + if (firstChild.tagName === "YTD-SEGMENTED-LIKE-DISLIKE-BUTTON-RENDERER") { + const segmentedDislikeButton = document.getElementById( + "segmented-dislike-button" + ); + if (segmentedDislikeButton) { + return segmentedDislikeButton; + } + + const grandChildren = firstChild.children; + if (grandChildren.length > 0) { + return grandChildren[1] as HTMLElement; + } + } else { + return children[1] as HTMLElement; + } + console.error("dislike button not found"); + return; +} + +function createDislikeTextContainer() { + const textNodeClone = ( + getLikeButton() || getLikeButton()?.parentNode + )?.cloneNode(true); + const insertPreChild = getDislikeButton()?.querySelector( + "yt-touch-feedback-shape" + ); + if (textNodeClone && insertPreChild) { + getDislikeButton() + ?.querySelector("button") + ?.insertBefore(textNodeClone, insertPreChild); + } + getDislikeButton() + ?.querySelector("button") + ?.classList.remove("yt-spec-button-shape-next--icon-button"); + getDislikeButton() + ?.querySelector("button") + ?.classList.add("yt-spec-button-shape-next--icon-leading"); + if ((textNodeClone as any).querySelector("span[role='text']") === null) { + const span = document.createElement("span"); + span.setAttribute("role", "text"); + while (textNodeClone?.firstChild) { + textNodeClone.removeChild(textNodeClone.firstChild); + } + textNodeClone?.appendChild(span); + } + (textNodeClone as any).querySelector("span[role='text']").innerText = ""; + return (textNodeClone as any).querySelector("span[role='text']"); +} + +function getDislikeTextContainer() { + let result = + getDislikeButton()?.querySelector("#text") ?? + getDislikeButton()?.getElementsByTagName("yt-formatted-string")[0] ?? + getDislikeButton()?.querySelector("span[role='text']"); + if (result == null) { + result = createDislikeTextContainer(); + } + return result; +} + +function checkForSignInButton() { + if ( + document.querySelector( + "a[href^='https://accounts.google.com/ServiceLogin']" + ) + ) { + return true; + } else { + return false; + } +} + +export { + getButtons, + getLikeButton, + getDislikeButton, + getLikeTextContainer, + getDislikeTextContainer, + checkForSignInButton, +}; diff --git a/Extensions/combined/src/events.js b/Extensions/combined/src/events.ts similarity index 78% rename from Extensions/combined/src/events.js rename to Extensions/combined/src/events.ts index 9b0e78ae..c363afbe 100644 --- a/Extensions/combined/src/events.js +++ b/Extensions/combined/src/events.ts @@ -1,18 +1,23 @@ -import { getBrowser, getVideoId, numberFormat, cLog } from "./utils"; -import { checkForSignInButton, getButtons } from "./buttons"; +import { createRateBar } from "./bar"; +import { + checkForSignInButton, + getDislikeButton, + getLikeButton, +} from "./buttons"; import { - NEUTRAL_STATE, - LIKED_STATE, DISLIKED_STATE, - setDislikes, + LIKED_STATE, + NEUTRAL_STATE, extConfig, - storedData, - setLikes, getLikeCountFromButton, + setDislikes, + setLikes, + storedData, } from "./state"; -import { createRateBar } from "./bar"; +import { ColorTheme, NumberDisplayFormat } from "./types"; +import { getBrowser, getVideoId, numberFormat } from "./utils"; -function sendVote(vote) { +function sendVote(vote: 0 | 1 | -1) { if (extConfig.disableVoteSubmission !== true) { getBrowser().runtime.sendMessage({ message: "send_vote", @@ -83,17 +88,20 @@ function dislikeClicked() { } function addLikeDislikeEventListener() { - const buttons = getButtons(); if (!window.returnDislikeButtonlistenersSet) { - buttons.children[0].addEventListener("click", likeClicked); - buttons.children[1].addEventListener("click", dislikeClicked); - buttons.children[0].addEventListener("touchstart", likeClicked); - buttons.children[1].addEventListener("touchstart", dislikeClicked); + getLikeButton()?.addEventListener("click", likeClicked); + getLikeButton()?.addEventListener("touchstart", likeClicked); + if (getDislikeButton()) { + getDislikeButton()?.addEventListener("click", dislikeClicked); + getDislikeButton()?.addEventListener("touchstart", dislikeClicked); + } window.returnDislikeButtonlistenersSet = true; } } -function storageChangeHandler(changes, area) { +function storageChangeHandler(changes: { + [key: string]: chrome.storage.StorageChange; +}) { if (changes.disableVoteSubmission !== undefined) { handleDisableVoteSubmissionChangeEvent( changes.disableVoteSubmission.newValue @@ -108,12 +116,6 @@ function storageChangeHandler(changes, area) { if (changes.colorTheme !== undefined) { handleColorThemeChangeEvent(changes.colorTheme.newValue); } - - if (changes.numberDisplayRoundDown !== undefined) { - handleNumberDisplayRoundDownChangeEvent( - changes.numberDisplayRoundDown.newValue - ); - } if (changes.numberDisplayFormat !== undefined) { handleNumberDisplayFormatChangeEvent(changes.numberDisplayFormat.newValue); } @@ -124,39 +126,35 @@ function storageChangeHandler(changes, area) { } } -function handleDisableVoteSubmissionChangeEvent(value) { +function handleDisableVoteSubmissionChangeEvent(value: boolean) { extConfig.disableVoteSubmission = value; } -function handleColoredThumbsChangeEvent(value) { +function handleColoredThumbsChangeEvent(value: boolean) { extConfig.coloredThumbs = value; } -function handleColoredBarChangeEvent(value) { +function handleColoredBarChangeEvent(value: boolean) { extConfig.coloredBar = value; } -function handleColorThemeChangeEvent(value) { +function handleColorThemeChangeEvent(value: ColorTheme) { if (!value) value = "classic"; extConfig.colorTheme = value; } -function handleNumberDisplayFormatChangeEvent(value) { +function handleNumberDisplayFormatChangeEvent(value: NumberDisplayFormat) { extConfig.numberDisplayFormat = value; } -function handleNumberDisplayRoundDownChangeEvent(value) { - extConfig.numberDisplayRoundDown = value; -} - -function handleNumberDisplayReformatLikesChangeEvent(value) { +function handleNumberDisplayReformatLikesChangeEvent(value: boolean) { extConfig.numberDisplayReformatLikes = value; } export { - sendVote, - likeClicked, - dislikeClicked, addLikeDislikeEventListener, + dislikeClicked, + likeClicked, + sendVote, storageChangeHandler, }; diff --git a/Extensions/combined/src/starRating.js b/Extensions/combined/src/starRating.ts similarity index 94% rename from Extensions/combined/src/starRating.js rename to Extensions/combined/src/starRating.ts index 65cf18b1..37a336d8 100644 --- a/Extensions/combined/src/starRating.js +++ b/Extensions/combined/src/starRating.ts @@ -1,6 +1,6 @@ import { cLog } from "./utils"; -function createStarRating(rating, isMobile) { +function createStarRating(rating: number, isMobile: boolean) { let starRating = document.createElement("label"); let starSlider = document.createElement("input"); @@ -20,18 +20,18 @@ function createStarRating(rating, isMobile) { if (isMobile) { YTLikeButton = document.querySelector( "#app > div.page-container > ytm-watch > ytm-single-column-watch-next-results-renderer > ytm-slim-video-metadata-section-renderer > ytm-slim-video-action-bar-renderer > div > ytm-slim-metadata-toggle-button-renderer:nth-child(1)" - ); + ) as HTMLElement; } else { YTLikeButton = document.querySelector( "#top-level-buttons-computed > ytd-toggle-button-renderer:nth-child(1)" - ); + ) as HTMLElement; } YTLikeButton.insertAdjacentElement("afterend", starRating); try { let YTBar = document.querySelector("#ryd-bar-container"); - YTBar.setAttribute("style", "width: 190%; height: 2px;"); + YTBar?.setAttribute("style", "width: 190%; height: 2px;"); } catch (err) { cLog("RateBar Not Present"); } diff --git a/Extensions/combined/src/state.js b/Extensions/combined/src/state.ts similarity index 50% rename from Extensions/combined/src/state.js rename to Extensions/combined/src/state.ts index ec2125a5..0ff48377 100644 --- a/Extensions/combined/src/state.js +++ b/Extensions/combined/src/state.ts @@ -1,14 +1,20 @@ -import { getLikeButton, getDislikeButton, getButtons } from "./buttons"; import { createRateBar } from "./bar"; import { + getButtons, + getDislikeButton, + getDislikeTextContainer, + getLikeButton, + getLikeTextContainer, +} from "./buttons"; +import { ExtConfig, StoredData } from "./types"; +import { + cLog, getBrowser, + getColorFromTheme, getVideoId, - cLog, + localize, numberFormat, - getColorFromTheme, } from "./utils"; -import { localize } from "./utils"; -import { createStarRating } from "./starRating"; //TODO: Do not duplicate here and in ryd.background.js const apiUrl = "https://returnyoutubedislikeapi.com"; @@ -16,19 +22,18 @@ const LIKED_STATE = "LIKED_STATE"; const DISLIKED_STATE = "DISLIKED_STATE"; const NEUTRAL_STATE = "NEUTRAL_STATE"; -let extConfig = { +let extConfig: ExtConfig = { disableVoteSubmission: false, coloredThumbs: false, coloredBar: false, colorTheme: "classic", numberDisplayFormat: "compactShort", - numberDisplayRoundDown: true, showTooltipPercentage: false, tooltipPercentageMode: "dash_like", numberDisplayReformatLikes: false, }; -let storedData = { +let storedData: StoredData = { likes: 0, dislikes: 0, previousState: NEUTRAL_STATE, @@ -46,7 +51,17 @@ function isNewDesign() { return document.getElementById("comment-teaser") !== null; } -let mutationObserver = new Object(); +function isRoundedDesign() { + return document.getElementById("segmented-like-button") !== null; +} + +class MutationObserverWrapper extends Object { + options: MutationObserverInit; + exists: boolean; + observer: MutationObserver; +} + +let mutationObserver = new MutationObserverWrapper(); if (isShorts() && mutationObserver.exists !== true) { cLog("initializing mutation observer"); @@ -56,24 +71,25 @@ if (isShorts() && mutationObserver.exists !== true) { subtree: false, }; mutationObserver.exists = true; - mutationObserver.observer = new MutationObserver(function ( - mutationList, - observer - ) { + mutationObserver.observer = new MutationObserver(function (mutationList) { mutationList.forEach((mutation) => { if ( mutation.type === "attributes" && mutation.target.nodeName === "TP-YT-PAPER-BUTTON" && - mutation.target.id === "button" + (mutation.target as HTMLElement).id === "button" ) { // cLog('Short thumb button status changed'); - if (mutation.target.getAttribute("aria-pressed") === "true") { - mutation.target.style.color = - mutation.target.parentElement.parentElement.id === "like-button" + if ( + (mutation.target as HTMLElement).getAttribute("aria-pressed") === + "true" + ) { + (mutation.target as HTMLElement).style.color = + (mutation.target as HTMLElement)?.parentElement?.parentElement + ?.id === "like-button" ? getColorFromTheme(true) : getColorFromTheme(false); } else { - mutation.target.style.color = "unset"; + (mutation.target as HTMLElement).style.color = "unset"; } return; } @@ -88,35 +104,51 @@ function isLikesDisabled() { // return true if the like button's text doesn't contain any number if (isMobile()) { return /^\D*$/.test( - getButtons().children[0].querySelector(".button-renderer-text").innerText + ( + getButtons()?.children[0]?.querySelector( + ".button-renderer-text" + ) as HTMLElement + )?.innerText ); } - return /^\D*$/.test( - getButtons().children[0].querySelector("#text").innerText - ); + return /^\D*$/.test((getButtons()?.children[0] as HTMLElement)?.innerText); } function isVideoLiked() { if (isMobile()) { return ( - getLikeButton().querySelector("button").getAttribute("aria-label") == + getLikeButton()?.querySelector("button")?.getAttribute("aria-label") === "true" ); } - return getLikeButton().classList.contains("style-default-active"); + return ( + getLikeButton()?.classList.contains("style-default-active") || + getLikeButton()?.querySelector("button")?.getAttribute("aria-pressed") === + "true" + ); } function isVideoDisliked() { if (isMobile()) { return ( - getDislikeButton().querySelector("button").getAttribute("aria-label") == - "true" + getDislikeButton() + ?.querySelector("button") + ?.getAttribute("aria-label") === "true" ); } - return getDislikeButton().classList.contains("style-default-active"); + return ( + getDislikeButton()?.classList.contains("style-default-active") || + getDislikeButton() + ?.querySelector("button") + ?.getAttribute("aria-pressed") === "true" + ); } -function getState(storedData) { +function getState(storedData: { + likes: number; + dislikes: number; + previousState: string; +}) { if (isVideoLiked()) { return { current: LIKED_STATE, previous: storedData.previousState }; } @@ -127,46 +159,130 @@ function getState(storedData) { } //--- Sets The Likes And Dislikes Values ---// -function setLikes(likesCount) { - getButtons().children[0].querySelector("#text").innerText = likesCount; +function setLikes(likesCount: string) { + cLog(`SET likes ${likesCount}`); + const likeTextContainer = getLikeTextContainer() as HTMLElement; + if (!likeTextContainer) { + console.error("likeTextContainer not found"); + return; + } + likeTextContainer.innerText = likesCount; } -function setDislikes(dislikesCount) { +function setDislikes(dislikesCount: string) { + cLog(`SET dislikes ${dislikesCount}`); + getDislikeTextContainer()?.removeAttribute("is-empty"); + getDislikeTextContainer()?.removeAttribute("is-empty"); if (!isLikesDisabled()) { if (isMobile()) { - getButtons().children[1].querySelector( + const buttons = getButtons(); + if (!buttons) { + console.error("buttons not found"); + return; + } + + const children = buttons.children; + if (children.length === 0) { + console.error("buttons children not found"); + return; + } + + const secondChild = children[1] as HTMLElement; + if (!secondChild) { + console.error("secondChild not found"); + return; + } + + const buttonRendererText = secondChild.querySelector( ".button-renderer-text" - ).innerText = dislikesCount; + ) as HTMLElement; + if (!buttonRendererText) { + console.error("buttonRendererText not found"); + return; + } + + buttonRendererText.innerText = dislikesCount; return; } - getButtons().children[1].querySelector("#text").innerText = dislikesCount; + const dislikeTextContainer = getDislikeTextContainer() as HTMLElement; + if (!dislikeTextContainer) { + console.error("dislikeTextContainer not found"); + return; + } + + dislikeTextContainer.innerText = dislikesCount; } else { cLog("likes count disabled by creator"); if (isMobile()) { - getButtons().children[1].querySelector( + const buttons = getButtons(); + if (!buttons) { + console.error("buttons not found"); + return; + } + + const children = buttons.children; + if (children.length === 0) { + console.error("buttons children not found"); + return; + } + + const secondChild = children[1] as HTMLElement; + if (!secondChild) { + console.error("secondChild not found"); + return; + } + + const buttonRendererText = secondChild.querySelector( ".button-renderer-text" - ).innerText = localize("TextLikesDisabled"); + ) as HTMLElement; + if (!buttonRendererText) { + console.error("buttonRendererText not found"); + return; + } + + buttonRendererText.innerText = localize("TextLikesDisabled"); return; } - getButtons().children[1].querySelector("#text").innerText = - localize("TextLikesDisabled"); + const dislikeTextContainer = getDislikeTextContainer() as HTMLElement; + if (!dislikeTextContainer) { + console.error("dislikeTextContainer not found"); + return; + } + dislikeTextContainer.innerText = localize("TextLikesDisabled"); } } function getLikeCountFromButton() { - if (isShorts()) { - //Youtube Shorts don't work with this query. It's not nessecary; we can skip it and still see the results. - //It should be possible to fix this function, but it's not critical to showing the dislike count. + try { + if (isShorts()) { + //Youtube Shorts don't work with this query. It's not necessary; we can skip it and still see the results. + //It should be possible to fix this function, but it's not critical to showing the dislike count. + return false; + } + + let likeButton = + getLikeButton()?.querySelector("yt-formatted-string#text") ?? + getLikeButton()?.querySelector("button"); + + let likesStr = likeButton?.getAttribute("aria-label")?.replace(/\D/g, ""); + if (!likesStr) { + console.error("likesStr not found"); + return false; + } + + const likeStrLength = likesStr?.length; + if (!likeStrLength) { + console.error("likeStrLength not found"); + return false; + } + + return likeStrLength > 0 ? parseInt(likesStr) : false; + } catch { return false; } - let likesStr = getLikeButton() - .querySelector("yt-formatted-string#text") - .getAttribute("aria-label") - .replace(/\D/g, ""); - return likesStr.length > 0 ? parseInt(likesStr) : false; } -function processResponse(response, storedData) { +function processResponse(response: any, storedData: StoredData) { const formattedDislike = numberFormat(response.dislikes); setDislikes(formattedDislike); if (extConfig.numberDisplayReformatLikes === true) { @@ -180,19 +296,30 @@ function processResponse(response, storedData) { createRateBar(storedData.likes, storedData.dislikes); if (extConfig.coloredThumbs === true) { if (isShorts()) { - // for shorts, leave deactived buttons in default color - let shortLikeButton = getLikeButton().querySelector( + // for shorts, leave deactivated buttons in default color + const shortLikeButton = getLikeButton()?.querySelector( "tp-yt-paper-button#button" - ); - let shortDislikeButton = getDislikeButton().querySelector( + ) as HTMLElement; + if (!shortLikeButton) { + console.error("shortLikeButton not found"); + return; + } + + const shortDislikeButton = getDislikeButton()?.querySelector( "tp-yt-paper-button#button" - ); - if (shortLikeButton.getAttribute("aria-pressed") === "true") { + ) as HTMLElement; + if (!shortDislikeButton) { + console.error("shortDislikeButton not found"); + return; + } + + if (shortLikeButton?.getAttribute("aria-pressed") === "true") { shortLikeButton.style.color = getColorFromTheme(true); } - if (shortDislikeButton.getAttribute("aria-pressed") === "true") { + if (shortDislikeButton?.getAttribute("aria-pressed") === "true") { shortDislikeButton.style.color = getColorFromTheme(false); } + mutationObserver.observer.observe( shortLikeButton, mutationObserver.options @@ -202,8 +329,20 @@ function processResponse(response, storedData) { mutationObserver.options ); } else { - getLikeButton().style.color = getColorFromTheme(true); - getDislikeButton().style.color = getColorFromTheme(false); + const likeButton = getLikeButton(); + if (!likeButton) { + console.error("likeButton not found"); + return; + } + + const dislikeButton = getDislikeButton(); + if (!dislikeButton) { + console.error("dislikeButton not found"); + return; + } + + likeButton.style.color = getColorFromTheme(true); + dislikeButton.style.color = getColorFromTheme(false); } } //Temporary disabling this - it breaks all places where getButtons()[1] is used @@ -211,13 +350,16 @@ function processResponse(response, storedData) { } // Tells the user if the API is down -function displayError(error) { - getButtons().children[1].querySelector("#text").innerText = localize( - "textTempUnavailable" - ); +function displayError() { + const dislikeTextContainer = getDislikeTextContainer() as HTMLElement; + if (!dislikeTextContainer) { + console.error("dislikeTextContainer not found"); + return; + } + dislikeTextContainer.innerText = localize("textTempUnavailable"); } -async function setState(storedData) { +async function setState(storedData: StoredData) { storedData.previousState = isVideoDisliked() ? DISLIKED_STATE : isVideoLiked() @@ -238,7 +380,7 @@ async function setState(storedData) { } ) .then((response) => { - if (!response.ok) displayError(response.error); + if (!response.ok) displayError(); return response; }) .then((response) => response.json()) @@ -260,14 +402,13 @@ function initExtConfig() { initializeColoredBar(); initializeColorTheme(); initializeNumberDisplayFormat(); - initializeNumberDisplayRoundDown(); initializeTooltipPercentage(); initializeTooltipPercentageMode(); initializeNumberDisplayReformatLikes(); } function initializeDisableVoteSubmission() { - getBrowser().storage.sync.get(["disableVoteSubmission"], (res) => { + getBrowser().storage.sync.get(["disableVoteSubmission"], (res: any) => { if (res.disableVoteSubmission === undefined) { getBrowser().storage.sync.set({ disableVoteSubmission: false }); } else { @@ -277,7 +418,7 @@ function initializeDisableVoteSubmission() { } function initializeColoredThumbs() { - getBrowser().storage.sync.get(["coloredThumbs"], (res) => { + getBrowser().storage.sync.get(["coloredThumbs"], (res: any) => { if (res.coloredThumbs === undefined) { getBrowser().storage.sync.set({ coloredThumbs: false }); } else { @@ -287,7 +428,7 @@ function initializeColoredThumbs() { } function initializeColoredBar() { - getBrowser().storage.sync.get(["coloredBar"], (res) => { + getBrowser().storage.sync.get(["coloredBar"], (res: any) => { if (res.coloredBar === undefined) { getBrowser().storage.sync.set({ coloredBar: false }); } else { @@ -296,18 +437,8 @@ function initializeColoredBar() { }); } -function initializeNumberDisplayRoundDown() { - getBrowser().storage.sync.get(["numberDisplayRoundDown"], (res) => { - if (res.numberDisplayRoundDown === undefined) { - getBrowser().storage.sync.set({ numberDisplayRoundDown: true }); - } else { - extConfig.numberDisplayRoundDown = res.numberDisplayRoundDown; - } - }); -} - function initializeColorTheme() { - getBrowser().storage.sync.get(["colorTheme"], (res) => { + getBrowser().storage.sync.get(["colorTheme"], (res: any) => { if (res.colorTheme === undefined) { getBrowser().storage.sync.set({ colorTheme: false }); } else { @@ -317,7 +448,7 @@ function initializeColorTheme() { } function initializeNumberDisplayFormat() { - getBrowser().storage.sync.get(["numberDisplayFormat"], (res) => { + getBrowser().storage.sync.get(["numberDisplayFormat"], (res: any) => { if (res.numberDisplayFormat === undefined) { getBrowser().storage.sync.set({ numberDisplayFormat: "compactShort" }); } else { @@ -327,7 +458,7 @@ function initializeNumberDisplayFormat() { } function initializeTooltipPercentage() { - getBrowser().storage.sync.get(["showTooltipPercentage"], (res) => { + getBrowser().storage.sync.get(["showTooltipPercentage"], (res: any) => { if (res.showTooltipPercentage === undefined) { getBrowser().storage.sync.set({ showTooltipPercentage: false }); } else { @@ -337,7 +468,7 @@ function initializeTooltipPercentage() { } function initializeTooltipPercentageMode() { - getBrowser().storage.sync.get(["tooltipPercentageMode"], (res) => { + getBrowser().storage.sync.get(["tooltipPercentageMode"], (res: any) => { if (res.tooltipPercentageMode === undefined) { getBrowser().storage.sync.set({ tooltipPercentageMode: "dash_like" }); } else { @@ -347,7 +478,7 @@ function initializeTooltipPercentageMode() { } function initializeNumberDisplayReformatLikes() { - getBrowser().storage.sync.get(["numberDisplayReformatLikes"], (res) => { + getBrowser().storage.sync.get(["numberDisplayReformatLikes"], (res: any) => { if (res.numberDisplayReformatLikes === undefined) { getBrowser().storage.sync.set({ numberDisplayReformatLikes: false }); } else { @@ -357,22 +488,23 @@ function initializeNumberDisplayReformatLikes() { } export { + DISLIKED_STATE, + LIKED_STATE, + NEUTRAL_STATE, + extConfig, + getLikeCountFromButton, + getState, + initExtConfig, + isLikesDisabled, isMobile, + isNewDesign, + isRoundedDesign, isShorts, isVideoDisliked, isVideoLiked, - isNewDesign, - getState, - setState, + setDislikes, setInitialState, setLikes, - setDislikes, - getLikeCountFromButton, - LIKED_STATE, - DISLIKED_STATE, - NEUTRAL_STATE, - extConfig, - initExtConfig, + setState, storedData, - isLikesDisabled, }; diff --git a/Extensions/combined/src/storage.ts b/Extensions/combined/src/storage.ts new file mode 100644 index 00000000..ef9337e5 --- /dev/null +++ b/Extensions/combined/src/storage.ts @@ -0,0 +1,2 @@ +const storage = chrome.storage.sync || chrome.storage.local; +export default storage; diff --git a/Extensions/combined/src/types/data.ts b/Extensions/combined/src/types/data.ts new file mode 100644 index 00000000..6ac8adac --- /dev/null +++ b/Extensions/combined/src/types/data.ts @@ -0,0 +1,7 @@ +export type StoredData = { + likes: number; + dislikes: number; + previousState: DataState; +}; + +export type DataState = "LIKED_STATE" | "DISLIKED_STATE" | "NEUTRAL_STATE"; diff --git a/Extensions/combined/src/types/ext-config.ts b/Extensions/combined/src/types/ext-config.ts new file mode 100644 index 00000000..a7a48f3a --- /dev/null +++ b/Extensions/combined/src/types/ext-config.ts @@ -0,0 +1,20 @@ +export type ColorTheme = "classic" | "accessible" | "neon"; +export type NumberDisplayFormat = "compactShort" | "compactLong" | "standard"; +export type TooltipPercentageMode = + | "dash_like" + | "dash_dislike" + | "both" + | "only_like" + | "only_dislike" + | undefined; + +export type ExtConfig = { + disableVoteSubmission: boolean; + coloredThumbs: boolean; + coloredBar: boolean; + colorTheme: ColorTheme; + numberDisplayFormat: NumberDisplayFormat; + numberDisplayReformatLikes: boolean; + showTooltipPercentage: boolean | undefined; + tooltipPercentageMode: TooltipPercentageMode; +}; diff --git a/Extensions/combined/src/types/index.ts b/Extensions/combined/src/types/index.ts new file mode 100644 index 00000000..ae4a0d1c --- /dev/null +++ b/Extensions/combined/src/types/index.ts @@ -0,0 +1,2 @@ +export * from "./ext-config"; +export * from "./data"; diff --git a/Extensions/combined/src/utils.js b/Extensions/combined/src/utils.ts similarity index 60% rename from Extensions/combined/src/utils.js rename to Extensions/combined/src/utils.ts index 05dafbf0..5dbae1d2 100644 --- a/Extensions/combined/src/utils.js +++ b/Extensions/combined/src/utils.ts @@ -1,38 +1,45 @@ import { extConfig } from "./state"; +import { NumberDisplayFormat } from "./types"; -function roundDown(num) { - if (num < 1000) return num; - const int = Math.floor(Math.log10(num) - 2); - const decimal = int + (int % 3 ? 1 : 0); - const value = Math.floor(num / 10 ** decimal); - return value * 10 ** decimal; -} +declare const browser: any; -function numberFormat(numberState) { - let numberDisplay; - if (extConfig.numberDisplayRoundDown === false) { - numberDisplay = numberState; - } else { - numberDisplay = roundDown(numberState); - } - return getNumberFormatter(extConfig.numberDisplayFormat).format( - numberDisplay - ); +function numberFormat(numberState: number) { + return getNumberFormatter(extConfig.numberDisplayFormat).format(numberState); } -function getNumberFormatter(optionSelect) { - let userLocales; +function getNumberFormatter(numberDisplayFormat: NumberDisplayFormat) { + let userLocales: string; if (document.documentElement.lang) { userLocales = document.documentElement.lang; } else if (navigator.language) { userLocales = navigator.language; } else { try { - userLocales = new URL( - Array.from(document.querySelectorAll("head > link[rel='search']")) - ?.find((n) => n?.getAttribute("href")?.includes("?locale=")) - ?.getAttribute("href") - )?.searchParams?.get("locale"); + const headLinks = document.querySelectorAll("head > link[rel='search']"); + if (!headLinks || headLinks.length === 0) { + throw new Error("No head links found"); + } + + const localeLink = Array.from(headLinks).find((n) => + n?.getAttribute("href")?.includes("?locale=") + ); + if (!localeLink) { + throw new Error("No locale link found"); + } + + const localeLinkHref = localeLink.getAttribute("href"); + if (!localeLinkHref) { + throw new Error("No locale link href found"); + } + + const url = new URL(localeLinkHref); + const searchParams = url.searchParams; + const locale = searchParams.get("locale"); + if (!searchParams || typeof locale !== "string") { + throw new Error("No locale found"); + } + + userLocales = locale; } catch { cLog( "Cannot find browser locale. Use en as default for number formatting." @@ -41,9 +48,9 @@ function getNumberFormatter(optionSelect) { } } - let formatterNotation; - let formatterCompactDisplay; - switch (optionSelect) { + let formatterNotation: Intl.NumberFormatOptions["notation"]; + let formatterCompactDisplay: Intl.NumberFormatOptions["compactDisplay"]; + switch (numberDisplayFormat) { case "compactLong": formatterNotation = "compact"; formatterCompactDisplay = "long"; @@ -65,11 +72,11 @@ function getNumberFormatter(optionSelect) { return formatter; } -function localize(localeString) { +function localize(localeString: string) { return chrome.i18n.getMessage(localeString); } -function getBrowser() { +function getBrowser(): typeof chrome | typeof browser | false { if (typeof chrome !== "undefined" && typeof chrome.runtime !== "undefined") { return chrome; } else if ( @@ -83,11 +90,13 @@ function getBrowser() { } } -function getVideoId(url) { +function getVideoId(url: string) { const urlObject = new URL(url); const pathname = urlObject.pathname; if (pathname.startsWith("/clip")) { - return document.querySelector("meta[itemprop='videoId']").content; + return ( + document?.querySelector("meta[itemprop='videoId']") as HTMLMetaElement + )?.content; } else { if (pathname.startsWith("/shorts")) { return pathname.slice(8); @@ -96,11 +105,14 @@ function getVideoId(url) { } } -function isInViewport(element) { +function isInViewport(element: HTMLElement) { const rect = element.getBoundingClientRect(); const height = innerHeight || document.documentElement.clientHeight; const width = innerWidth || document.documentElement.clientWidth; return ( + // When short (channel) is ignored, the element (like/dislike AND short itself) is + // hidden with a 0 DOMRect. In this case, consider it outside of Viewport + !(rect.top == 0 && rect.left == 0 && rect.bottom == 0 && rect.right == 0) && rect.top >= 0 && rect.left >= 0 && rect.bottom <= height && @@ -117,16 +129,12 @@ function isVideoLoaded() { ); } -function cLog(message, writer) { +function cLog(message: string) { message = `[return youtube dislike]: ${message}`; - if (writer) { - writer(message); - } else { - console.log(message); - } + console.log(message); } -function getColorFromTheme(voteIsLike) { +function getColorFromTheme(voteIsLike: boolean) { let colorString; switch (extConfig.colorTheme) { case "accessible": diff --git a/Icons/128x128_transparent.jpg b/Icons/128x128_transparent.jpg index 0a2dba14..ad35fce5 100644 Binary files a/Icons/128x128_transparent.jpg and b/Icons/128x128_transparent.jpg differ diff --git a/Icons/Discord.gif b/Icons/Discord.gif index b368ae38..49e277cc 100644 Binary files a/Icons/Discord.gif and b/Icons/Discord.gif differ diff --git a/Icons/Return Youtube Dislike - Dark.jpg b/Icons/Return Youtube Dislike - Dark.jpg index 22293216..8713c597 100644 Binary files a/Icons/Return Youtube Dislike - Dark.jpg and b/Icons/Return Youtube Dislike - Dark.jpg differ diff --git a/Icons/Return Youtube Dislike - Dark.png b/Icons/Return Youtube Dislike - Dark.png index 23c30eb9..6dd57d19 100644 Binary files a/Icons/Return Youtube Dislike - Dark.png and b/Icons/Return Youtube Dislike - Dark.png differ diff --git a/README.md b/README.md index b31aa56b..8b590660 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ [![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) [![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) -Read this in other languages: [Español](READMEes.md), [русский](READMEru.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md) + +Read this in other languages: [русский](READMEru.md), [Español](READMEes.md), [Nederlands](READMEnl.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md, [中文](READMEcn.md) + # Return YouTube Dislike @@ -39,7 +41,7 @@ You can learn more at our website at: [returnyoutubedislike.com](https://www.ret Third-party use of this open API is allowed with the following restrictions: - **Attribution**: This project should be clearly attributed with a link to [returnyoutubedislike.com](https://returnyoutubedislike.com/). -- **Rate Limiting**: There are per client rate limits in place of 100 per minute and 10'000 per day. This will return a _429_ status code indicating that your application should back off. +- **Rate Limiting**: There are per client rate limits in place of 100 per minute and 10,000 per day. This will return a _429_ status code indicating that your application should back off. The API is accessible over the following base URL: https://returnyoutubedislikeapi.com diff --git a/READMEcn.md b/READMEcn.md new file mode 100644 index 00000000..11d4d987 --- /dev/null +++ b/READMEcn.md @@ -0,0 +1,86 @@ +[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Rating&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Chrome Web Store Users](https://img.shields.io/chrome-web-store/users/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Users&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Mozilla rating](https://img.shields.io/amo/stars/return-youtube-dislikes?label=Firefox%20Rating&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Mozilla downloads](https://img.shields.io/amo/users/return-youtube-dislikes?label=Firefox%20Users&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Commit rate](https://img.shields.io/github/commit-activity/m/Anarios/return-youtube-dislike?label=Commits&style=flat)](https://github.com/Anarios/return-youtube-dislike/commits/main) +[![Issues](https://img.shields.io/github/issues/Anarios/return-youtube-dislike?style=flat&label=Issues)](https://github.com/Anarios/return-youtube-dislike/issues) +[![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) +[![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) + +阅读其他语言版本:[English](README.md), [русский](READMEru.md), [Español](READMEes.md), [Nederlands](READMEnl.md), [Français](READMEfr.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md) + +# Return YouTube Dislike + +

+ Return YouTube Dislike是一个开源的扩展,可以显示 YouTube 的不喜欢数量。
+ 适用于 Chrome 和 Firefox 作为 Web 扩展。
+ 也可以作为 JS Userscript 在其他浏览器上使用。

+ +

+ +## 故事 + +在2021年11月10日,Google [宣布](https://blog.youtube/news-and-events/update-to-youtube/) 将移除 YouTube 的不喜欢数量。 + +此外,YouTube API 中的 `dislike` 字段于2021年12月13日 [被移除](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts),移除了在观看之前评估内容质量的能力。 + +## 它是如何工作的 + +随着 YouTube API 中不喜欢统计信息的移除,我们的后端切换到使用从扩展用户数据中抓取的不喜欢统计信息和估算数据的组合。 + +[常见问题解答](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) + +## 为什么重要 + +您可以在我们的网站上了解更多信息:[returnyoutubedislike.com](https://www.returnyoutubedislike.com/) + +## API 文档 + +允许第三方使用此开放 API,但有以下限制: + +- **归因**: 该项目应清楚地归因于 [returnyoutubedislike.com](https://returnyoutubedislike.com/) 的链接。 +- **速率限制**: 客户端的速率限制为每分钟100次和每天10,000次。这将返回 _429_ 状态代码,表示您的应用程序应该减速。 + +API 可以通过以下基本 URL 访问: +https://returnyoutubedislikeapi.com + +可用端点列表在这里: +https://returnyoutubedislikeapi.com/swagger/index.html + +### 获取投票 + +示例获取给定 YouTube 视频 ID 的投票: +`/votes?videoId=kxOuG8jMIgI` + +```json +{ + "id": "kxOuG8jMIgI", + "dateCreated": "2021-12-20T12:25:54.418014Z", + "likes": 27326, + "dislikes": 498153, + "rating": 1.212014408444885, + "viewCount": 3149885, + "deleted": false +} +``` + +不存在的 YouTube ID 将返回状态码 _404_ "未找到"。 +格式错误的 YouTube ID 将返回 _400_ "请求无效"。 + +## 贡献 + +请阅读[贡献指南](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTING.md)。 + +## 支持这个项目! + +您可以通过以下链接向我们捐赠来支持这个项目: + +[捐赠](https://returnyoutubedislike.com/donate) + +## 赞助商 + +[Piepacker](https://piepacker.com) + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[PocketTube](https://yousub.info/?utm_source=return diff --git a/READMEde.md b/READMEde.md new file mode 100644 index 00000000..95fd8828 --- /dev/null +++ b/READMEde.md @@ -0,0 +1,96 @@ +[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Rating&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Chrome Web Store Users](https://img.shields.io/chrome-web-store/users/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Users&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Mozilla rating](https://img.shields.io/amo/stars/return-youtube-dislikes?label=Firefox%20Rating&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Mozilla downloads](https://img.shields.io/amo/users/return-youtube-dislikes?label=Firefox%20Users&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Commit rate](https://img.shields.io/github/commit-activity/m/Anarios/return-youtube-dislike?label=Commits&style=flat)](https://github.com/Anarios/return-youtube-dislike/commits/main) +[![Issues](https://img.shields.io/github/issues/Anarios/return-youtube-dislike?style=flat&label=Issues)](https://github.com/Anarios/return-youtube-dislike/issues) +[![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) +[![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) + + +Lesen sie dies in anderen Sprachen: [English](README.md), [Español](READMEes.md), [русский](READMEru.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md) + + +# Return YouTube Dislike + +

+ Return YouTube Dislike (Bring die YouTube Dislikes zurück) ist eine open-source Erweiterung die den Dislike-Zähler zurückbringt.
+ Für Chromium Browser und Firefox als Browser Erweiterung verfügbar.
+ Für andere Browsers auch als JS Userscript verfügbar.

+ +

+ +## Die Geschichte + +Am 10. November 2021, [kündigte Google an](https://blog.youtube/news-and-events/update-to-youtube/) das der YouTube Dislike-Zähler von der Platform entfernt werden sollte. + +Zusätzlich, wurde das `dislike` Feld in der YouTube API am 13. Dezember 2021 [entfernt](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts), und damit auch jegliche Möglichkeit die Qualität der Inhalte zu bewerten bevor man das Video sah. + +## Was die Erweiterung macht + +Mit der entfernung der Statistiken der YouTube API, wechselte unser Backend zu einer Kombination von archivierten Dislike Statistiken sowie den extrapolierten Schätzungen durch die Nutzerdaten dieser Erweiterung anfallen, um die Dislike-Zahlen zu berechnen. + +[FAQ](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) + +## Warum dies wichtig ist + +Mehr erfahren Sie auf unserer Website unter: [returnyoutubedislike.com](https://www.returnyoutubedislike.com/) + +## API Dokumentierung + +Dritte dürfen diese öffentliche API mit folgenden Restriktionen benützen: + +- **Namensnennung**: Dieses Projekt sollte klar und mit folgendem Link [returnyoutubedislike.com](https://returnyoutubedislike.com/) versehen zugeordnet werden. +- **Raten Limitierung**: Es bestehen pro Nutzer limitierungen von 100 pro Minute sowie 10'000 pro Tag. Dies wird eine Statusmeldung von _429_ ausgeben, die darauf hinweist, dass sich Ihre Anwendung zurückziehen sollte. + +Die API ist unter der folgenden basis URL verfügbar: +https://returnyoutubedislikeapi.com + +Eine Liste aller verfügbaren Endpunkten finden Sie hier: +https://returnyoutubedislikeapi.com/swagger/index.html + +### Votum erhalten + +Beispiel um die Abstimmungen einer gegebenen YouTube ID zu erhalten: +`/votes?videoId=kxOuG8jMIgI` + +```json +{ + "id": "kxOuG8jMIgI", + "dateCreated": "2021-12-20T12:25:54.418014Z", + "likes": 27326, + "dislikes": 498153, + "rating": 1.212014408444885, + "viewCount": 3149885, + "deleted": false +} +``` + +Nicht existierende YouTube IDs werden den Statuscode _404_ "Not Found" zurückgeben. +Falsch geformte YouTube IDs werden den Statuscode _400_ "Bad Request" zurückgeben. + + + +## Beitragen + +Bitte lesen Sie das [Beitrags-Handbuch](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTING.md). + +## Unterstütze dieses Projekt! + +Sie können das Projekt unterstützen indem Sie unter den folgenden Link spenden: + +[Spenden](https://returnyoutubedislike.com/donate) + +## Sponsoren + +[Piepacker](https://piepacker.com) + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[PocketTube](https://yousub.info/?utm_source=returnyoutubedislike) + +[Werde unser Sponsor](https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601) diff --git a/READMEes.md b/READMEes.md index 63704b04..6c3aad41 100644 --- a/READMEes.md +++ b/READMEes.md @@ -7,7 +7,9 @@ [![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) [![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) -Leer en otros idiomas: [English](README.md), [русский](READMEru.md), [Français](READMEfr.md) [日本語](READMEja.md), [Türkçe](READMEtr.md) + +Leer en otros idiomas: [English](README.md), [русский](READMEru.md), [Nederlands](READMEnl.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md) + # Return YouTube Dislike diff --git a/READMEfr.md b/READMEfr.md index 6915d88c..9d26f4f3 100644 --- a/READMEfr.md +++ b/READMEfr.md @@ -7,9 +7,11 @@ [![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) [![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](LICENSE) -# Return YouTube Dislike -Lisez ceci dans d'autres langues : [English](README.md), [Español](READMEes.md), [русский](READMEru.md), [Türkçe](READMEtr.md) +Lisez ceci dans d'autres langues : [English](README.md), [русский](READMEru.md), [Español](READMEes.md), [Nederlands](READMEnl.md),[日本語](READMEja.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md) + + +# Return YouTube Dislike

Return YouTube Dislike est une extension open-source qui ré-affiche les dislikes (pouces rouges) sur YouTube.
@@ -64,8 +66,8 @@ Exemple pour obtenir les likes d'une vidéo YouTube avec un ID donné: } ``` -Si aucunne vidéo YouTube à cet ID, il sera retourner le code d'erreur _404_ "Not Found". -Un ID YouTube invilide renverra _400_ "Bad Request". +Si aucune vidéo YouTube n'a cet ID, le code d'erreur _404_ "Not Found" sera retourné. +Un ID YouTube invalide renverra le code d'erreur _400_ "Bad Request". + +## Συνεισφορά + +Παρακαλώ διαβάστε τον [οδηγό συνεισφοράς](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTING.md). + +## Υποστηρίξτε αυτό το project! + +Μπορείτε να υποστηρίξετε αυτό το έργο κάνοντας δωρεά προς εμάς στον παρακάτω σύνδεσμο: + +[Δωρεά](https://returnyoutubedislike.com/donate) + +## Χορηγοί + +[Piepacker](https://piepacker.com) + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[PocketTube](https://yousub.info/?utm_source=returnyoutubedislike) + +[Γίνεται χορηγός μας](https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601) diff --git a/READMEja.md b/READMEja.md index 2aba04b7..8a628d09 100644 --- a/READMEja.md +++ b/READMEja.md @@ -7,7 +7,9 @@ [![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) [![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) -別の言語: [English](README.md), [Español](READMEes.md), [русский](READMEru.md), [Türkçe](READMEtr.md) + +別の言語: [English](README.md), [русский](READMEru.md), [Español](READMEes.md), [Nederlands](READMEnl.md), [Français](READMEfr.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md) + # Return YouTube Dislike diff --git a/READMEnl.md b/READMEnl.md new file mode 100644 index 00000000..98c7b795 --- /dev/null +++ b/READMEnl.md @@ -0,0 +1,96 @@ +[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Rating&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Chrome Web Store Users](https://img.shields.io/chrome-web-store/users/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Users&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Mozilla rating](https://img.shields.io/amo/stars/return-youtube-dislikes?label=Firefox%20Rating&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Mozilla downloads](https://img.shields.io/amo/users/return-youtube-dislikes?label=Firefox%20Users&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Commit rate](https://img.shields.io/github/commit-activity/m/Anarios/return-youtube-dislike?label=Commits&style=flat)](https://github.com/Anarios/return-youtube-dislike/commits/main) +[![Issues](https://img.shields.io/github/issues/Anarios/return-youtube-dislike?style=flat&label=Issues)](https://github.com/Anarios/return-youtube-dislike/issues) +[![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) +[![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) + + +Lees dit in andere talen: [English](README.md), [Español](READMEes.md), [русский](READMEru.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md) + + +# Return YouTube Dislike + +

+ Return YouTube Dislike is een open-source extensie die het aantal dislikes van YouTube retourneert.
+ Beschikbaar voor Chrome en Firefox als webextensie.
+ Ook beschikbaar voor andere browsers als JS Userscript.

+ +

+ +## Het Verhaal + +Op 10 november 2021 [kondigde](https://blog.youtube/news-and-events/update-to-youtube/) that the YouTube dislike count would be removed. + +Additionally, the `dislike` field in the YouTube API was [removed](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) Google aan dat het aantal dislikes op YouTube zou worden verwijderd. + +## Wat het doet + +Met de verwijdering van afkeerstatistieken uit de YouTube API, schakelde onze backend over op het gebruik van een combinatie van geschraapte afkeerstatistieken, schattingen geëxtrapoleerd uit gebruikersgegevens van extensies. + +[FAQ](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) + +## Waarom het uitmaakt + +U kunt meer informatie vinden op onze website op: [returnyoutubedislike.com](https://www.returnyoutubedislike.com/) + +## API-documentatie + +Gebruik door derden van deze open API is toegestaan ​​met de volgende beperkingen: + +- **Naamsvermelding**: dit project moet duidelijk worden toegeschreven met een link naar [returnyoutubedislike.com](https://returnyoutubedislike.com/). +- **Snelheidsbeperking**: Er zijn tarieflimieten per klant in plaats van 100 per minuut en 10.000 per dag. Hiermee wordt een statuscode _429_ geretourneerd die aangeeft dat uw toepassing moet worden uitgeschakeld. + +De API is toegankelijk via de volgende basis-URL: +https://returnyoutubedislikeapi.com + +Lijst met beschikbare eindpunten is hier beschikbaar: +https://returnyoutubedislikeapi.com/swagger/index.html + +### Stemmen krijgen + +Voorbeeld om stemmen te krijgen voor een bepaalde YouTube-video-ID: +`/votes?videoId=kxOuG8jMIgI` + +```json +{ + "id": "kxOuG8jMIgI", + "dateCreated": "2021-12-20T12:25:54.418014Z", + "likes": 27326, + "dislikes": 498153, + "rating": 1.212014408444885, + "viewCount": 3149885, + "deleted": false +} +``` + +Geen bestaande YouTube-ID retourneert statuscode _404_ "Niet gevonden". +Verkeerd gevormde YouTube-ID retourneert _400_ "Slecht verzoek". + + + +## Bijdragen + +Lees de [bijdragengids](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTING.md). + +## Steun dit project! + +U kunt dit project steunen door aan ons te doneren via onderstaande link: + +[Doneer](https://returnyoutubedislike.com/donate) + +## Sponsoren + +[Piepacker](https://piepacker.com) + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[PocketTube](https://yousub.info/?utm_source=returnyoutubedislike) + +[Wordt een sponsor](https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601) diff --git a/READMEru.md b/READMEru.md index 1609f37d..a918f52c 100644 --- a/READMEru.md +++ b/READMEru.md @@ -7,14 +7,16 @@ [![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) [![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) -Прочитать на других языках: [English](README.md), [Español](READMEes.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md) + +Прочитать на других языках: [English](README.md), [Español](READMEes.md), [Nederlands](READMEnl.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md) + # Return YouTube Dislike

- Return YouTube Dislike - это расширение с открытым исходным кодом, которое возвращает счётчик отметок «Не нравится» на YouTube.
+ Return YouTube Dislike — это расширение с открытым исходным кодом, которое возвращает счётчик отметок «Не нравится» на YouTube.
Доступно для Chrome и Firefox в качестве веб-расширения.
- Также доступен для других браузеров в виде пользовательского скрипта JS.

+ Также доступен для других браузеров в виде пользовательского скрипта.

@@ -22,13 +24,13 @@ 10 ноября 2021 года Google [объявили](https://blog.youtube/news-and-events/update-to-youtube/), что счётчик «Не нравится» на YouTube будет удален. -Кроме того, поле отметок `dislike` в API YouTube было [удалено]](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) 13 декабря 2021 года, удалив любую возможность судить о качестве контента перед просмотром. +Кроме того, поле отметок `dislike` в API YouTube было [удалено](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) 13 декабря 2021 года, убрав любую возможность судить о качестве контента перед просмотром. ## Как оно работает -С удалением статистики отметок из API YouTube наш сервер переключился на использование комбинации собранной статистики отметок «Не нравится», оценок, экстраполированных из пользовательских данных расширения. +С удалением статистики отметок из API YouTube наш сервер переключился на использование комбинации собранной статистики отметок «Не нравится» и оценок, экстраполированных из пользовательских данных расширения. -[ЧаВО](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQru.md) +[FAQ](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQru.md) ## Почему это важно @@ -39,7 +41,7 @@ Стороннее использование этого открытого API разрешено со следующими ограничениями: - **Атрибуция**: Этот проект должен быть чётко описан со ссылкой на [returnyoutubedislike.com](https://returnyoutubedislike.com/). -- **Ограничение**: Существуют ограничения скорости для каждого клиента - 100 в минуту и 10 000 в день. Это выдаст код ошибки _429_, указывающий на то, что ваше приложение должно быть отключено. +- **Ограничение**: Существуют ограничения скорости для каждого клиента — 100 в минуту и 10 000 в день. Это выдаст код ошибки _429_, указывающий на то, что ваше приложение должно быть отключено. API доступен по следующему основному URL-адресу: https://returnyoutubedislikeapi.com @@ -49,7 +51,7 @@ https://returnyoutubedislikeapi.com/swagger/index.html ### Получить голоса -Пример получения голосов за заданный идентификатор видео на YouTube: +Пример получения голосов для заданного идентификатора видео на YouTube: `/votes?videoId=kxOuG8jMIgI` ```json @@ -64,8 +66,8 @@ https://returnyoutubedislikeapi.com/swagger/index.html } ``` -Неверный идентификатор YouTube выдаст код ошибки _404_ "Не найдено". -Неправильно отформатированный идентификатор YouTube выдаст код ошибки _400_ "Неверный запрос". +Неверный идентификатор YouTube выдаст код ошибки _404_ «Не найдено». +Неправильно отформатированный идентификатор YouTube выдаст код ошибки _400_ «Неверный запрос». + +Den 10 november 2021 [meddelade Google](https://blog.youtube/news-and-events/update-to-youtube/) att YouTubes dislikes skulle tas bort från plattformen. + +Dessutom blev `dislike`-fältet i YouTubes API [borttaget](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) den 13 december 2021, vilket tog bort möjligheten att bedöma innehållets kvalitet innan visning. + +## Vad det gör + +Med borttagandet av dislike-statistiken från YouTubes API, bytte vår backend till att använda en kombination av skrapad dislike-statistik och uppskattningar utifrån data av tilläggsanvändare. + +[FAQ](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) + +## Varför det är viktigt + +Du kan läsa mer på vår webbplats: [returnyoutubedislike.com](https://www.returnyoutubedislike.com/) + +## API dokumentation + +Tredjepartsanvändning av detta öppna API är tillåtet med följande restriktioner: + +- **Attribution**: Detta projekt ska tydligt tillskrivas med en länk till [returnyoutubedislike.com](https://returnyoutubedislike.com/). +- **Frekvensbegränsning**: Det finns per klient hastighetsbegränsningar på 100 per minut och 10'000 per dag. Detta kommer att returnera en _429_ statuskod som indikerar att din applikation bör backa. + +API:et är tillgängligt på följande bas-URL: +https://returnyoutubedislikeapi.com + +En lista över tillgängliga ändpunkter finns här: +https://returnyoutubedislikeapi.com/swagger/index.html + +### Hämta röster + +Exempel för att hämta röster för en given YouTube-video-ID: +`/votes?videoId=kxOuG8jMIgI` + +```json +{ + "id": "kxOuG8jMIgI", + "dateCreated": "2021-12-20T12:25:54.418014Z", + "likes": 27326, + "dislikes": 498153, + "rating": 1.212014408444885, + "viewCount": 3149885, + "deleted": false +} +``` + +Inga existerande YouTube-ID returnerar statuskoden _404_ "Not Found". +Felaktigt formade YouTube-ID returnerar _400_ "Bad Request". + + + +## Bidra + +Läs gärna [bidragsguiden](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTING.md). + +## Stöd detta projekt! + +Du kan stödja detta projekt genom att donera till oss på länken nedan: + +[Donera](https://returnyoutubedislike.com/donate) + +## Sponsorer + +[Piepacker](https://piepacker.com) + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[PocketTube](https://yousub.info/?utm_source=returnyoutubedislike) + +[Stöd oss på Patreon](https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601) diff --git a/READMEtr.md b/READMEtr.md index 6376d843..084bd953 100644 --- a/READMEtr.md +++ b/READMEtr.md @@ -3,11 +3,13 @@ [![Mozilla oylaması](https://img.shields.io/amo/stars/return-youtube-dislikes?label=Firefox%20Rating&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) [![Mozilla indirmeleri](https://img.shields.io/amo/users/return-youtube-dislikes?label=Firefox%20Users&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) [![Commit sayısı](https://img.shields.io/github/commit-activity/m/Anarios/return-youtube-dislike?label=Commits&style=flat)](https://github.com/Anarios/return-youtube-dislike/commits/main) -[![Issue'ler](https://img.shields.io/github/issues/Anarios/return-youtube-dislike?style=flat&label=Issues)](https://github.com/Anarios/return-youtube-dislike/issues) +[![Issue'lar](https://img.shields.io/github/issues/Anarios/return-youtube-dislike?style=flat&label=Issues)](https://github.com/Anarios/return-youtube-dislike/issues) [![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) [![Lisans](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) -Bunu diğer dillerde okuyun: [English](README.md), [Español](READMEes.md), [Français](READMEfr.md), [русский](READMEru.md), [日本語](READMEja.md) + +Bunu diğer dillerde okuyun: [English](README.md), [русский](READMEru.md), [Español](READMEes.md), [Français](READMEfr.md), [Nederlands](READMEnl.md), [日本語](READMEja.md), [українська](READMEuk.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md) + # YouTube Dislike Sayısını Geri Getir @@ -22,13 +24,13 @@ Bunu diğer dillerde okuyun: [English](README.md), [Español](READMEes.md), [Fra 10 Kasım 2021 tarihinde Google, YouTube dislike sayısının kaldırılacağını [duyurdu](https://blog.youtube/news-and-events/update-to-youtube/). -Ek olarak, YouTube API'sindeki "dislike" alanı 13 Aralık 2021 tarihinde [kaldırıldı](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) ve içeriğin kalitesini izlemeden önce yargılayabilme olanağı ortadan kaldırıldı. +Ek olarak, YouTube API'sindeki `dislike` alanı 13 Aralık 2021 tarihinde [kaldırıldı](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) ve içeriğin kalitesini izlemeden önce yargılayabilme olanağı ortadan kaldırıldı. ## Ne İşe Yarar YouTube API'sinden dislike istatistiklerinin kaldırılmasıyla, backend'imiz, uzantı kullanıcı verilerinden tahmin edilen, toplanmış dislike istatistiklerinin bir birleşimini kullanmaya başladı. -[SSS](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQ.md) +[SSS](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQtr.md) ## Neden Önemlidir @@ -39,12 +41,12 @@ Sitemizden daha fazla bilgi edinebilirsiniz: [returnyoutubedislike.com](https:// Bu açık API'nin üçüncü taraflarca kullanımına, aşağıdaki kısıtlamalarla izin verilir: - **Atfetme**: Bu proje, açık bir biçimde [returnyoutubedislike.com](https://returnyoutubedislike.com/) adresine yönlendirilmelidir. -- **Hız Sınırlaması**: Kullanıcı başına dakikada 100 ve günde 10.000 hız sınırlaması vardır. Bu, uygulamanızın geri çekilmesi gerektiğini belirten 429 durum kodunu döndürür +- **Hız Sınırlaması**: Kullanıcı başına dakikada 100 ve günde 10.000 hız sınırlaması vardır. Bu, uygulamanızın geri çekilmesi gerektiğini belirten _429_ durum kodunu döndürür. API'ye aşağıdaki temel URL üzerinden erişilebilir: https://returnyoutubedislikeapi.com -Kullanılabilir endpoint'lerin listesi burada mevcuttur: +Kullanılabilir endpoint'lerin bir listesi burada mevcuttur: https://returnyoutubedislikeapi.com/swagger/index.html ### Oylamaları Elde Etme @@ -75,13 +77,13 @@ Tüm belgelemeleri sitemizden inceleyebilirsiniz. ## Katkıda Bulunma -Lütfen [katkı kılavuzu](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTING.md)nu okuyun. +Lütfen [katkı kılavuzu](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTINGtr.md)nu okuyun. ## Bu Projeyi Destekle! Aşağıdaki bağlantıdan bize bağış yapabilir ve bu projeye destek olabilirsiniz: -[Bağış Yapın](https://returnyoutubedislike.com/donate) +[Bağış Yap](https://returnyoutubedislike.com/donate) ## Sponsorlar diff --git a/READMEuk.md b/READMEuk.md new file mode 100644 index 00000000..38f2faca --- /dev/null +++ b/READMEuk.md @@ -0,0 +1,96 @@ +[![Chrome Web Store](https://img.shields.io/chrome-web-store/stars/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Rating&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Chrome Web Store Users](https://img.shields.io/chrome-web-store/users/gebbhagfogifgggkldgodflihgfeippi?label=Chrome%20Users&style=flat&logo=google)](https://chrome.google.com/webstore/detail/youtube-dislike-button/gebbhagfogifgggkldgodflihgfeippi/) +[![Mozilla rating](https://img.shields.io/amo/stars/return-youtube-dislikes?label=Firefox%20Rating&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Mozilla downloads](https://img.shields.io/amo/users/return-youtube-dislikes?label=Firefox%20Users&style=flat&logo=firefox)](https://addons.mozilla.org/en-US/firefox/addon/return-youtube-dislikes/) +[![Commit rate](https://img.shields.io/github/commit-activity/m/Anarios/return-youtube-dislike?label=Commits&style=flat)](https://github.com/Anarios/return-youtube-dislike/commits/main) +[![Issues](https://img.shields.io/github/issues/Anarios/return-youtube-dislike?style=flat&label=Issues)](https://github.com/Anarios/return-youtube-dislike/issues) +[![Discord](https://img.shields.io/discord/909435648170160229?label=Discord&style=flat&logo=discord)](https://discord.gg/UMxyMmCgfF) +[![License](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat)](https://github.com/Anarios/return-youtube-dislike/blob/main/LICENSE) + + +Read this in other languages: [English](README.md), [Español](READMEes.md), [русский](READMEru.md), [Français](READMEfr.md), [日本語](READMEja.md), [Türkçe](READMEtr.md), [Deutsch](READMEde.md), [Ελληνικά](READMEgr.md), [Svenska](READMEsv.md), [中文](READMEcn.md) + + +# Return YouTube Dislike + +

+ Return YouTube Dislike - це розширення з відкритим вихідним кодом, яке повертає лічильник відміток «Не подобається» на YouTube.
+ Доступно для Chrome та Firefox як веброзширення.
+ Також доступно для інших браузерів як JS UserScript.

+ +

+ +## Історія + +10 листопада 2021 року Google [оголосили](https://blog.youtube/news-and-events/update-to-youtube/), що лічильник відміток «Не подобається» на YouTube буде видалено. + +Крім того, поле позначок `dislike` у YouTube API було [видалено](https://support.google.com/youtube/thread/134791097/update-to-youtube-dislike-counts) 13 грудня 2021 року, прибравши єдину можливість оцінити якість вмісту перед переглядом. + +## Як це працює + +Після видаленням статистики відміток з API YouTube наш сервер перейшов на використання комбінації заархівованих статистичних даних відміток «Не подобається» екстрапольованих із даними користувачів розширення. + +[ЧаПи](https://github.com/Anarios/return-youtube-dislike/blob/main/Docs/FAQuk.md) + +## Чому це важливо + +Ви можете дізнатися більше на нашому вебсайті: [returnyoutubedislike.com](https://www.returnyoutubedislike.com/) + +## Документація API + +Використання цього відкритого API сторонніми особами дозволено з наступними обмеженнями: + +- **Атрибуція**: Цей проєкт має бути чітко описано, використовуючи посилання на [returnyoutubedislike.com](https://returnyoutubedislike.com/). +- **Обмеження**: Існують обмеження на швидкісті для кожного клієнта - 100 за хвилину і 10 000 за день. Це видасть код помилки 429, який вказує на те, що вашому додатку слід завершити роботу. + +API доступно за наступною URL-адресою: +https://returnyoutubedislikeapi.com + +Перелік доступних «ендпоінтів» можна переглянути тут: +https://returnyoutubedislikeapi.com/swagger/index.html + +### Отримати оцінки + +Приклад отримання оцінок відео на YouTube за ID: +`/votes?videoId=kxOuG8jMIgI` + +```json +{ + "id": "kxOuG8jMIgI", + "dateCreated": "2021-12-20T12:25:54.418014Z", + "likes": 27326, + "dislikes": 498153, + "rating": 1.212014408444885, + "viewCount": 3149885, + "deleted": false +} +``` + +Недійсний YouTube ID видасть код помилки 404 "Not Found". +YouTube ID у невірному форматі видасть код помилки 400 "Bad Request". + + + +## Взяти участь у розробці + +Будь ласка, ознайомтеся із [посібником внеску в проєкт](https://github.com/Anarios/return-youtube-dislike/blob/main/CONTRIBUTINGuk.md). + +## Підтримайте цей проєкт! + +Ви можете підтримати цей проєкт пожертвою за посиланням нижче: + +[Підтримати](https://returnyoutubedislike.com/donate) + +## Спонсори + +[Piepacker](https://piepacker.com) + +[Seed4.Me VPN](https://www.seed4.me/users/register?gift=ReturnYoutubeDislike) + +[PocketTube](https://yousub.info/?utm_source=returnyoutubedislike) + +[Станьте нашим спонсором](https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601) diff --git a/Website/README.md b/Website/README.md index 05e18612..abd5c2b5 100644 --- a/Website/README.md +++ b/Website/README.md @@ -1,3 +1,5 @@ +Read this in other languages: [Nederlands](READMEnl.md), [Türkçe](READMEtr.md) + # return-youtube-dislike-site ## Build Setup diff --git a/Website/READMEnl.md b/Website/READMEnl.md new file mode 100644 index 00000000..ceaeb0f3 --- /dev/null +++ b/Website/READMEnl.md @@ -0,0 +1,89 @@ +Read this in other languages: [English](README.md), [Türkçe](READMEtr.md) + +# return-youtube-dislike-site + +## Opstelling bouwen + +```bash +# install dependencies +$ npm install + +# serve with hot reload at localhost:3000 +$ npm run dev + +# lint your changes +$ npm run lint + +# build for production and launch server +$ npm run build +$ npm run start + +# generate static project +$ npm run generate +``` + +Voor gedetailleerde uitleg over hoe dingen werken, bekijk de [documentatie](https://nuxtjs.org). + +## Aanbevolen VSCode-instellingen + +- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) `ext install dbaeumer.vscode-eslint` +- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) `ext install esbenp.prettier-vscode` +- [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) + +> `Ctrl(Cmd)` + `Shift` + `P` > Instellingen Openen (JSON) + +``` +"editor.formatOnSave": true, +"editor.codeActionsOnSave": { + "source.fixAll.eslint": true +} +"vetur.validation.template": false, +``` + +## Speciale mappen + +U kunt de volgende extra mappen maken, waarvan sommige speciaal gedrag vertonen. Alleen `pagina's` zijn vereist; u kunt ze verwijderen als u hun functionaliteit niet wilt gebruiken. + +### `assets` + +De assets-map bevat uw niet-gecompileerde activa zoals Stylus- of Sass-bestanden, afbeeldingen of lettertypen. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/directory-structure/assets). + +### `componenten` + +De componentenmap bevat uw Vue.js-componenten. Componenten vormen de verschillende delen van uw pagina en kunnen opnieuw worden gebruikt en geïmporteerd in uw pagina's, lay-outs en zelfs andere componenten. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/directory-structure/components). + +### `lay-outs` + +Lay-outs zijn een grote hulp wanneer je het uiterlijk van je Nuxt-app wilt veranderen, of je nu een zijbalk wilt opnemen of verschillende lay-outs voor mobiel en desktop wilt hebben. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/directory-structure/layouts). + +### `pagina's` + +Deze map bevat uw toepassingsweergaven en routes. Nuxt zal alle `*.vue` bestanden in deze map lezen en Vue Router automatisch instellen. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/get-started/routing). + +### `plugins` + +TDe directory met plug-ins bevat JavaScript-plug-ins die u wilt uitvoeren voordat u de roottoepassing Vue.js start. Dit is de plek om Vue-plug-ins toe te voegen en om functies of constanten te injecteren. Elke keer dat je `Vue.use()` moet gebruiken, moet je een bestand maken in `plugins/` en het pad toevoegen aan plug-ins in `nuxt.config.js`. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/directory-structure/plugins). + +### `static` + +Tzijn directory bevat uw statische bestanden. Elk bestand in deze map is toegewezen aan `/`. + +Voorbeeld: `/static/robots.txt` wordt toegewezen als `/robots.txt`. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/directory-structure/static). + +### `store` + +Deze map bevat uw Vuex-winkelbestanden. Door een bestand in deze map aan te maken, wordt Vuex automatisch geactiveerd. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/docs/2.x/directory-structure/store). diff --git a/Website/READMEtr.md b/Website/READMEtr.md new file mode 100644 index 00000000..06d0bbcb --- /dev/null +++ b/Website/READMEtr.md @@ -0,0 +1,89 @@ +Read this in other languages: [English](README.md), [Nederlands](READMEnl.md) + +# youtube-dislike-sayısını-geri-getir-site + +## Yapı Kurulumu + +```bash +# bağımlılıkları yükle +$ npm install + +# localhost:3000'de sıcak yeniden yükleme ile çalıştır +$ npm run dev + +# değişikliklerine lint'i uygula +$ npm run lint + +# üretim için yapıyı oluştur ve sunucuyu başlat +$ npm run build +$ npm run start + +# statik proje oluştur +$ npm run generate +``` + +İşlerin nasıl yürüdüğüyle ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org)ye göz atın. + +## Önerilen VSCode Kurulumu + +- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) `ext install dbaeumer.vscode-eslint` +- [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) `ext install esbenp.prettier-vscode` +- [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) + +> `Ctrl(Cmd)` + `Shift` + `P` > Varsayılan Ayarları Aç (JSON) + +``` +"editor.formatOnSave": true, +"editor.codeActionsOnSave": { + "source.fixAll.eslint": true +} +"vetur.validation.template": false, +``` + +## Özel Dizinler + +You can create the following extra directories, some of which have special behaviors. Only `pages` is required; you can delete them if you don't want to use their functionality. + +### `assets` + +Assets dizini, Stylus veya Sass dosyaları, resimler veya yazı tipleri gibi derlenmemiş varlıklarınızı içerir. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/directory-structure/assets)ye göz atın. + +### `components` + +Components dizini, Vue.js bileşenlerinizi içerir. Component'ler, sayfanızın farklı bölümlerini oluşturur ve yeniden kullanılabilir. Ayrıca sayfalarınıza, mizanpajlarınıza ve hatta diğer component'lerinize de aktarılabilir. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/directory-structure/components)ye göz atın. + +### `layouts` + +Layouts dizini, Nuxt uygulamanızın görünümünü ve verdiği hissi değiştirmek istediğinizde, bir kenar çubuğu eklemek istediğinizde veya mobil ve masaüstü için farklı düzenlere sahip olmak istediğinizde çok yardımcı olabilir. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/directory-structure/layouts)ye göz atın. + +### `pages` + +Bu dizin, uygulama görünümlerinizi ve rotalarınızı içerir. Nuxt, bu dizindeki tüm `*.vue` dosyalarını okuyacak ve Vue Router'ı otomatik olarak kuracaktır. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/get-started/routing)ye göz atın. + +### `plugins` + +Plugins dizini, kök Vue.js Uygulamasını başlatmadan önce çalıştırmak istediğiniz JavaScript eklentilerini içerir. Burası Vue eklentileri eklemek ve işlevler veya sabitler enjekte etmek için kullanılan yerdir. `Vue.use()`u her kullanmanız gerektiğinde, `plugins/` içinde bir dosya oluşturmalı ve yolunu `nuxt.config.js` içinde eklentilere eklemelisiniz. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/directory-structure/plugins)ye göz atın. + +### `static` + +Bu dizin statik dosyalarınızı içerir. Bu dizindeki her dosya `/` ile eşlenir. + +Örnek: `/static/robots.txt`, `/robots.txt` olarak eşlenir. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/directory-structure/static)ye göz atın. + +### `store` + +Bu dizin, Vuex mağaza dosyalarınızı içerir. Bu dizinde bir dosya oluşturmak, Vuex'i otomatik olarak etkinleştirecektir. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/docs/2.x/directory-structure/store)ye göz atın. diff --git a/Website/_locales/en.ts b/Website/_locales/en.ts index 8cc26f66..31f8d183 100644 --- a/Website/_locales/en.ts +++ b/Website/_locales/en.ts @@ -67,13 +67,13 @@ export default { bullet41: "in our", bullet4a: "Tell us your Operating System, Browser Name and Browser Version", bullet4b: - "Take screenshot of page with problem (i.e. youtube video page) with console open (press ", + "Take a screenshot of the page with the problem (i.e. Youtube video page) with the console open (press ", bullet4b1: ") - example screenshot below.", bullet4c: - "Take screenshot of extensions page of your browser with extension installed.", + "Take a screenshot of the extensions page of your browser with the extension installed.", bullet4c1: "To see extensions put this into address bar: ", firefox: "for Firefox", - chrome: "for Chrome, Edge, Brave, Opera, Vivaldi", + chrome: "for Chrome, Edge, Brave, Opera, and Vivaldi", }, faq: { name: "FAQ", @@ -81,19 +81,19 @@ export default { subtitle: "Still have questions? Feel free to join our Discord!", bullet1: "Where does the extension get its data?", bullet1text: - "A combination of archived data from before the offical YouTube dislike API shut down, and extrapolated extension user behavior.", + "A combination of archived data from before the official YouTube dislike API shut down, and extrapolated extension user behavior.", bullet2: "Why isn't the dislike count updating?", bullet2text: "Right now video dislikes are cached and they aren't updated very frequently. It varies depending on a video's popularity but can take anywhere between a few hours and a few days to update.", bullet3: "How does this work?", bullet3text: - "The extension collects the video ID of the video you are watching, and fetches the dislike (and other fields like views, likes etc) using our API. The extension then displays the dislike count and ratio on the page. If you like or dislike a video, that is recorded and sent to the database so an accurate dislike count can be extrapolated.", + "The extension collects the video ID of the video you are watching, and fetches the number of dislikes (and other fields like views, likes etc) using our API. The extension then displays the dislike count and ratio on the page. If you like or dislike a video, that is recorded and sent to the database so an accurate dislike count can be extrapolated.", bullet4: "Can I share my dislike count with you?", bullet4text: "Coming soon. We are looking into using Oauth or a different read only API with a limited scope so creators can share their dislike counts verifiability.", bullet5: "What data do you collect and how is it treated?", bullet5text: - 'The extension only collects data that is strictly necessary for it to function properly, such as IP address or ID of the video you\'re watching. None of your data will ever be sold to 3rd parties. If you would like to know more about how we handle security and privacy check out our security FAQ.', + 'The extension only collects data that is strictly necessary for it to function properly, such as the IP address or ID of the video you\'re watching. None of your data will ever be sold to 3rd parties. If you would like to know more about how we handle security and privacy check out our security FAQ.', bullet6: "How does the API/Backend work?", bullet6text: "The backend is using archived data from when the youtube api was still returning the dislike count, extension users like/dislike count and extrapolation. In the near future we will be allowing content creators to submit their dislike count easily and safely and we will be adding ArchiveTeam's archived data (4.56 billion videos) into our current database. You can also view a video on the topic.", diff --git a/Website/_locales/fr.ts b/Website/_locales/fr.ts index bbaa533e..96eb5857 100644 --- a/Website/_locales/fr.ts +++ b/Website/_locales/fr.ts @@ -54,8 +54,8 @@ export default { headers: "En-têtes (headers) : ", response: "Réponse : ", error1: - 'Si aucunne vidéo YouTube à cet ID, il sera retourner le code d\'erreur 404 "Not Found"', - error2: 'Un ID YouTube invilide renverra *400* "Bad Request"', + 'Si aucune vidéo YouTube n\'a cet ID, le code d\'erreur 404 "Not Found" sera retourné', + error2: 'Un ID YouTube invalide renverra le code d\'erreur *400* "Bad Request"', }, }, help: { @@ -123,7 +123,7 @@ export default { subtitle: "Liens vers le projet et ses développeurs", contact: "Contactez-moi", translators: "Traducteurs", - coolProjects: "Projets Cool", + coolProjects: "Projets Cools", sponsorBlockDescription: "Ignorer les publicités intégrées (sponso) dans la vidéo", filmotDescription: "Rechercher des vidéos YouTube par sous-titres", diff --git a/Website/_locales/ja.ts b/Website/_locales/ja.ts index d68c6065..45029660 100644 --- a/Website/_locales/ja.ts +++ b/Website/_locales/ja.ts @@ -1,101 +1,121 @@ -import { en } from 'vuetify/src/locale' +import { ja } from "vuetify/src/locale"; export default { - ...ja, - home: { - name: 'z[', - title: 'Return YouTube Dislike', - subtitle: 'YouTube̒]̕\𕜌uEUg@\API', - ukraine: 'ENCiT|[g', - sponsors: 'X|T[', + ...ja, + home: { + name: "ホーム", + title: "Return YouTube Dislike", + subtitle: "YouTubeの低評価数の表示を復元するブラウザ拡張機能とAPI", + ukraine: "ウクライナをサポート", + sponsors: "スポンサー", + }, + install: { + name: "インストール", + title: "プラットフォームの選択", + subtitle: "FirefoxとすべてのChromiumブラウザに対応しています。", + title2: "その他のプラットフォーム", + subtitle2: + "未対応のブラウザをお使いの場合は、以下のUserScriptをお試しください。", + title3: "サードパーティーによる実装", + subtitle3: + "開発者では責任を負いかねますので、ご自身の判断にてご利用ください。", + }, + api: { + name: "API", + title: "RYD公式ドキュメントへようこそ!", + subtitle: "まず、メニューからセクションを選択してください。", + rights: { + title: "使用権", + subtitle: + "このオープンAPIを第三者が使用することは、以下の制限付きで許可されています:", + bullet1: "属性:", + bullet1text: + "このレポ、もしくは returnyoutubedislike.com へのリンクのどちらかによって、明確に帰属させる必要があります。", + bullet2: "通信量制限:", + bullet2text: + "クライアントごとに、1分あたり100・1日あたり10,000という通信量制限が設けられています。これを超えた場合には、アプリケーションに通信を控えるよう促すステータスコード 429 を返します。", }, - install: { - name: 'CXg[', - title: 'vbgtH[̑I', - subtitle: 'FirefoxƂׂĂChromiumuEUɑΉĂ܂B', - title2: '̑̃vbgtH[', - subtitle2: 'Ή̃uEUg̏ꍇ́AȉUserScriptB', - title3: 'T[hp[eB[ɂ', - subtitle3: 'J҂ł͐ӔC𕉂˂܂̂ŁAg̔fɂĂpB', + url: { + title: "URL情報", + subtitle: "APIへのアクセスは、以下のベースURLから可能です:", }, - api: { - name: 'API', - title: 'RYDhLgւ悤!', - subtitle: '܂Aj[ZNVIĂB, - rights: { - title: 'gp', - subtitle: '̃I[vAPIO҂gp邱Ƃ́Aȉ̐tŋ‚Ă܂F', - bullet1: 'F', - bullet1text: '̃|A returnyoutubedislike.com ւ̃N̂ǂ炩ɂāAmɋAKv܂B', - bullet2: 'ʐMʐF', - bullet2text: 'NCAgƂɁA1100E110,000ƂʐMʐ݂Ă܂B𒴂ꍇɂ́AAvP[VɒʐMT悤Xe[^XR[h 429 Ԃ܂B', - }, - url: { - title: 'URL', - subtitle: 'APIւ̃ANZX́Aȉ̃x[XURL”\łF', - }, - endpoints: { - title: 'p”\ȃGh|Cg', - subtitle: 'p”\ȃGh|Cg̈ꗗ͂ł܂F', - }, - fetching: { - title: '{IȃtFb`̃`[gA', - subtitle: 'ȉYouTube ID]oꍇ̗łF', - title2: 'NGXgF', - url: 'NGXgURLF', - method: 'NGXg@F', - headers: 'wb_[F', - response: 'X|XF', - error1: 'YouTube IDȏꍇAXe[^XR[h 404 "Not Found" Ԃ܂B', - error2: 'YouTube ID̃tH[}bgȂꍇAXe[^XR[h 400 "Bad Request" Ԃ܂B' - }, + endpoints: { + title: "利用可能なエンドポイント", + subtitle: "利用可能なエンドポイントの一覧はこちらでご覧いただけます:", }, - help: { - name: 'wv', - title: 'guV[eBO', - bullet1: 'ŐVo[W̊g@\', - bullet11: 'CXg[Ă邱ƂmFĂB', - bullet2: 'g@\폜čăCXg[AׂẴEBhE‚ŃuEUċNĂB', - bullet3: 'ȉ̃NJƂmFĂF', - bullet31: 'ȉ̃v[eLXg\܂F', - bullet4: 'LŖ肪ȂꍇAȉ̃`lɂĖ񍐂ĂB', - bullet41: 'QƁF', - bullet4a: 'gOSAuEUƃo[WĂB', - bullet4b: 'R\[Ji', - bullet4b1: 'L[jÂy[WiFYouTube̓y[Wj̃XN[VbgBe܂B', - bullet4c: 'g@\CXg[ĂuEŮg@\y[W̃XN[VbgBe܂B', - bullet4c1: 'g@\y[W\ɂ́Aȉ̂悤ɓ͂ĂF', - firefox: 'FFirefox', - chrome: 'FChrome, Edge, Brave, Opera, Vivaldi', + fetching: { + title: "基本的なフェッチ操作のチュートリアル", + subtitle: "以下のYouTube IDから評価数を取り出した場合の例です:", + title2: "リクエスト例:", + url: "リクエストURL:", + method: "リクエスト方法:", + headers: "ヘッダー:", + response: "レスポンス:", + error1: + 'YouTube IDが無効な場合、ステータスコード 404 "Not Found" が返されます。', + error2: + 'YouTube IDのフォーマットが正しくない場合、ステータスコード 400 "Bad Request" が返されます。', }, - faq: { - name: 'Q&A', - title: '悭鎿', - subtitle: 'ɂ₪܂HXDiscordɂCyɂQB', - bullet1: 'g@\̃f[^͂ǂ擾Ă̂łH', - bullet1text: 'YouTube̒]API~Oɕۑf[^ƁAg@\[U[̍]/]ɂlgݍ킹Ď擾Ă܂B', - bullet2: ']XVȂ̂͂ȂłH', - bullet2text: '݁A]̓f[^x[XĂ邽߁A܂pɂɍXV܂B̍ĐɂĈقȂ܂AXVɂ͐Ԃ琔邱Ƃ܂B', - bullet3: 'ǂ̂悤Ȏdg݂œ삵Ă܂H', - bullet3text: '܂A̓ID WAAPI gpĒ]AĐA]Ȃǂ̍ڂ擾܂BɁAy[Wɒ]Ɣ䗦\܂Bɍ]]ƁAꂪL^ăf[^x[Xɒ~ς邽߁AmȒ]𐄒肷邱Ƃł܂B', - bullet4: ']L邱Ƃ͂ł܂H', - bullet4text: 'ߓɌJ\łB@\̎̂߂ɁAOauth ܂͔͈͂肵ʂ̓ǂݎpAPIgp邱ƂĂ܂B', - bullet5: 'ǂ̂悤ȃf[^WAǂ̂悤Ɏ舵Ă܂H', - bullet5text: '{g@\ł́AIPAhX⎋Ă铮IDȂǁA@\邽߂ɕKvȃf[^݂̂WĂ܂BȂ̃f[^́AO҂ɔ̔邱Ƃ͌Ă܂BZLeBƃvCoV[̎舵ɂ‚Ăƒm肽ꍇɂ́A ZLeBFAQ QƂB ', - bullet6: 'API/obNGh͂ǂ̂悤Ȏdg݂œ삵Ă܂H', - bullet6text: 'obNGh́AYouTube̒]API~Oɕۑf[^Ɗg@\[U[̍]/]ɂlgݍ킹Ď擾Ă܂B߂ARec҂ȒPˆSɒ]񋟂ł悤ɂAArchive Team ̃A[JCuf[^i456000j݂̃f[^x[Xɒlj\łB܂ÃgsbNɊւrfI܂B', - bullet7: ']Ɂue҂ɂ薳vƕ\̂͂ȂłH', - bullet7text: 'ŋߓeꂽł́Ae҂ɂĖɂĂȂĂue҂ɂ薳vƕ\邱Ƃ܂B́A]̕\ɂȂĂ邩ǂoVXeɂ镛pŁAԌA܂͓ɍ]Ȃ]ăy[WXVƏ̂Ǝv܂B', - }, - donate: { - name: 't', - subtitle: 'C^[lbg̎R邽߂̉X̊AtɂĉĂI', - }, - links: { - name: 'N', - title: 'vWFNgNW', - subtitle: 'vWFNgъJ҂ւ̃N', - contact: '₢킹', - translators: '|', - }, -} \ No newline at end of file + }, + help: { + name: "ヘルプ", + title: "トラブルシューティング", + bullet1: "最新バージョンの拡張機能", + bullet11: "がインストールされていることを確認してください。", + bullet2: + "拡張機能を削除して再インストールし、すべてのウィンドウを閉じた上でブラウザを再起動してください。", + bullet3: "以下のリンクが開くことを確認してください:", + bullet31: "以下のプレーンテキストが表示されます:", + bullet4: + "上記で問題が解決しない場合、以下のチャンネルにて問題を報告してください。", + bullet41: "参照:", + bullet4a: "お使いのOS、ブラウザ名とバージョンを教えてください。", + bullet4b: "コンソールを開き(", + bullet4b1: + "キー)、問題のあるページ(例:YouTubeの動画ページ)のスクリーンショットを撮影します。", + bullet4c: + "拡張機能がインストールされているブラウザの拡張機能ページのスクリーンショットを撮影します。", + bullet4c1: "拡張機能ページを表示するには、以下のように入力してください:", + firefox: ":Firefox", + chrome: ":Chrome, Edge, Brave, Opera, Vivaldi", + }, + faq: { + name: "Q&A", + title: "よくある質問", + subtitle: + "他にも何か質問がありますか?我々のDiscordにお気軽にご参加ください。", + bullet1: "拡張機能のデータはどこから取得しているのですか?", + bullet1text: + "YouTube公式の低評価APIが停止する前に保存したデータと、拡張機能ユーザーの高評価/低評価数を元にした推定値を組み合わせて取得しています。", + bullet2: "低評価数が更新されないのはなぜですか?", + bullet2text: + "現在、低評価数はデータベース化されているため、あまり頻繁に更新されません。動画の再生数によって異なりますが、更新には数時間から数日かかることがあります。", + bullet3: "どのような仕組みで動作していますか?", + bullet3text: + "まず、視聴中の動画のID を収集し、API を使用して低評価数、再生数、高評価などの項目を取得します。次に、ページ上に低評価数と比率を表示します。動画に高評価や低評価があると、それが記録されてデータベースに蓄積されるため、正確な低評価数を推定することができます。", + bullet4: "低評価数を共有することはできますか?", + bullet4text: + "近日中に公開予定です。機能の実装のために、Oauth または範囲を限定した別の読み取り専用APIを使用することを検討しています。", + bullet5: "どのようなデータを収集し、どのように取り扱っていますか?", + bullet5text: + '本拡張機能では、IPアドレスや視聴している動画のIDなど、正しく機能するために必要なデータのみを収集しています。あなたのデータは、第三者に販売されることは決してありません。セキュリティとプライバシーの取り扱いについてもっと知りたい場合には、 セキュリティFAQ をご参照ください。 ', + bullet6: "API/バックエンドはどのような仕組みで動作していますか?", + bullet6text: + "バックエンドは、YouTube公式の低評価APIが停止する前に保存したデータと拡張機能ユーザーの高評価/低評価数を元にした推定値を組み合わせて取得しています。近い将来、コンテンツ制作者が簡単かつ安全に低評価数を提供できるようにし、Archive Team のアーカイブデータ(45億6000万動画)も現在のデータベースに追加する予定です。また、このトピックに関するビデオもご覧いただけます。", + bullet7: "低評価数に「投稿者により無効化」と表示されるのはなぜですか?", + bullet7text: + "最近投稿された動画では、投稿者によって無効にされていなくても「投稿者により無効化」と表示されることがあります。これは、評価数の表示が無効になっているかどうかを検出するシステムによる副作用で、数時間後、または動画に高評価ないし低評価をしてページを更新すると消えるものだと思われます。", + }, + donate: { + name: "寄付", + subtitle: + "インターネットの自由を守るための我々の活動を、寄付によって応援してください!", + }, + links: { + name: "リンク", + title: "プロジェクトリンク集", + subtitle: "プロジェクトおよび開発者へのリンク", + contact: "お問い合わせ先", + translators: "翻訳者", + }, +}; diff --git a/Website/_locales/ko.ts b/Website/_locales/ko.ts new file mode 100644 index 00000000..7e394a27 --- /dev/null +++ b/Website/_locales/ko.ts @@ -0,0 +1,119 @@ +import { ko } from "vuetify/src/locale"; + +export default { + ...ko, + home: { + name: "홈", + title: "Return YouTube Dislike", + subtitle: "유튜브에서 싫어요를 표시해주는 브라우저 확장 프로그램 및 API", + ukraine: "우크라이나 지원", + sponsors: "스폰서", + }, + install: { + name: "설치", + title: "플랫폼 선택", + subtitle: "파이어폭스와 모든 크로미엄 기반 브라우저에서 사용 가능", + title2: "다른 플랫폼", + subtitle2: "당신의 브라우저가 아직 지원하지 않는 경우, 이 유저스크립트를 시도할 수 있습니다", + title3: "서드파티 구현", + subtitle3: "우리 측의 책임이 없으며, 사용자의 책임하에 사용하십시오", + }, + api: { + name: "API", + title: "공식 RYD 문서에 오신 것을 환영합니다!", + subtitle: "시작하려면 메뉴에서 섹션을 선택하세요.", + rights: { + title: "사용 권한", + subtitle: + "이 오픈 API의 제 3자 사용은 다음 제한 사항들과 함꼐 허용됩니다:", + bullet1: "저작자 표시: ", + bullet1text: + "이 프로젝트의 사용자는 저장소 또는 returnyoutubedislike.com에 대한 링크와 함께 명확하게 저자를 표기해야 합니다.", + bullet2: "속도 제한: ", + bullet2text: + "하나의 클라이언트당 분당 100개와 하루당 10,000개의 요청 제한이 있습니다. 당신의 애플리케이션이 이를 초과할 경우 429 상태 코드를 반환할 것입니다.", + }, + url: { + title: "URL 정보", + subtitle: "API는 다음 베이스 URL을 통해 액세스할 수 있습니다.: ", + }, + endpoints: { + title: "사용 가능한 엔드포인트", + subtitle: "사용 가능한 엔드포인트 리스트는 여기에서 사용 가능합니다: ", + }, + fetching: { + title: "기본 Fetching 튜토리얼", + subtitle: "주어진 유튜브 영상 ID에 대한 투표 수를 가져오는 예시: ", + title2: "요청 예시: ", + url: "요청 URL: ", + method: "요청 메소드: ", + headers: "헤더: ", + response: "응답: ", + error1: '유효하지 않은 유튜브 ID는 상태 코드 404 "Not Found"를 리턴합니다', + error2: + '잘못된 포멧의 유튜브 ID는 400 "Bad Request"를 리턴합니다', + }, + }, + help: { + name: "도움말", + title: "트러블슈팅", + bullet1: "지금 최신 버전이 설치되어 있는지 확인하세요. ", + bullet11: "버전이 현재 최신 버전입니다.", + bullet2: + "확장 프로그램을 제거하고 재설치한 다음, 브라우저를 재시작 하세요(모든 활성 창을 말하며, 단지 하나의 탭을 말하는 것이 아닙니다)", + bullet3: "이 링크가 열리는지 확인하세요: ", + bullet31: "평문이 표시되어야 합니다: ", + bullet4: "위의 내용이 도움이 되지 않는 경우, 우리의 디스코드에서 다음과 같은 채널에서 당신의 문제를 보고하세요.", + bullet41: "디스코드: ", + bullet4a: "운영체제, 브라우저 이름과 브라우저 버전을 우리한테 말해주세요", + bullet4b: + "콘솔창과 함께 문제가 된 페이지(예시: 유튜브 영상 페이지)의 스크린샷을 찍으세요.(", + bullet4b1: "키를 누르세요) 아래는 스크린샷의 예시입니다.", + bullet4c: + "확장 브로그램이 설치된 당신의 브라우저의 확장 프로그램 페이지의 스크린샷을 촬영하세요.", + bullet4c1: "확장 프로그램들을 보려면 이것을 주소창에 입력하세요", + firefox: ": 파이어폭스의 경우", + chrome: ": 크롬, 엣지, 브레이브, 오페라, 그리고 비발디의 경우", + }, + faq: { + name: "FAQ", + title: "자주 묻는 질문", + subtitle: "여전히 의문점이 있으신가요? 우리의 디스코드에 무료로 가입하세요!", + bullet1: "확장 프로그램은 어디에서 데이터를 가져옵니까?", + bullet1text: + "공식 유튜브 싫어요 API가 닫히기 전에 보환된 데이터와 확장 프로그램 사용자 행동을 추정한 값의 조합입니다", + bullet2: "왜 싫어요 수가 업데이트 되지 않는거죠?", + bullet2text: + "현재 동영상 싫어요는 캐시되며 자주 업데이트 되지는 않습니다. 동영상의 인기도에 따라 다르지만, 업데이트되는 데 몇 시간에서 며칠이 걸릴 수 있습니다.", + bullet3: "어떻게 작동합니까?", + bullet3text: + "확장 프로그램은 시청 중인 동영상의 동영상 ID를 수집하며, 우리의 API를 사용하여 싫어요 수(및 조회수, 좋아요 등과 같은 기타 필드)를 가져옵니다. 그런 다음 확장 프로그램은 싫어요 수와 비율을 페이지에 표시합니다. 당신이 비디오에 좋아요나 싫어요를 할 경우, 그것은 기록되고 데이터베이스로 전송되어 정확한 싫어요 수를 추정할 수 있습니다.", + bullet4: "저의 싫어요 수를 공유할 수 있나요?", + bullet4text: + "곧 출시됩니다. 우리는 크리에이터가 검증이 된 싫어요 수를 공유할 수 있도록 Oauth 또는 제한된 범위의 다른 읽기 전용 API를 사용하는 방법을 검토하고 있습니다", + bullet5: "어떤 데이터를 수집하고 어떻게 처리합니까?", + bullet5text: + '확장 프로그램은 제대로 작동하기 위해서 IP 주소 또는 당신이 본 영상의 ID 같은 순전히 필수적인 데이터만 수집합니다. 귀하의 데이터는 3자한테 판매되지 않습니다. 귀하가 우리가 어떻게 개인정보와 보안을 처리하는지 알고 싶다면 우리의 보안 FAQ를 확인하세요.', + bullet6: "API/백엔드는 어떻게 작동하나요?", + bullet6text: + "백엔드는 유튜브 api가 여전히 싫어요 수를 반환할 때의 싫어요 수, 확장기능 사용자들의 좋아요/싫어요 수와 추정치로부터 보관된 데이터를 사용합니다. 가까운 미래에는 콘텐츠 제작자가 쉽고 안전하게 싫어요 수를 제출할 수 있게 될 것이며 우리는 ArchiveTeam의 보관 데이터(45억 6천만 동영상)를 현재 데이터베이스에 추가할 것입니다. 주제에 대한 비디오를 볼 수도 있습니다.", + bullet7: "싫어요 수에 '싫어요 비활성화됨'이 왜 표시됩니까?", + bullet7text: + "때때로 최근에 업로드한 동영상은 제작자가 비활성화하지 않았더라도 '싫어요 비활성화됨'으로 표시될 수 있습니다. 이는 싫어요가 비활성화되어 있는지 감지하는 방법 때문입니다. 몇 시간 내에 동영상에 좋아요 또는 싫어요 표시를 하거나 페이지를 새로고침을 하면(희망 사항) 사라집니다.", + }, + donate: { + name: "기부", + subtitle: + "기부를 통해 인터넷의 자유를 유지하려는 우리의 노력을 지원할 수 있습니다!", + }, + links: { + name: "링크", + title: "프로젝트 링크", + subtitle: "프로젝트와 개발자들로 향하는 링크", + contact: "문의하기", + translators: "번역가들", + coolProjects: "Cool Projects", + sponsorBlockDescription: "동영상에 포함된 광고 건너뛰기", + filmotDescription: "자막으로 유튜브 동영상 검색", + }, +}; diff --git a/Website/_locales/nl.ts b/Website/_locales/nl.ts new file mode 100644 index 00000000..f5786cce --- /dev/null +++ b/Website/_locales/nl.ts @@ -0,0 +1,119 @@ +import { nl } from "vuetify/src/locale"; + +export default { + ...nl, + home: { + name: "Home", + title: "Return YouTube Dislike", + subtitle: "Browser-extensie en een API die je antipathieën op YouTube laat zien", + ukraine: "Support Ukraine", + sponsors: "Sponsors", + }, + install: { + name: "Installeren", + title: "Kies je platform", + subtitle: "Beschikbaar voor Firefox en alle Chromium-browsers", + title2: "Andere Platformen", + subtitle2: "Als uw browser nog niet wordt ondersteund, probeer dan dit UserScript", + title3: "Implementaties van derden", + subtitle3: "Geen aansprakelijkheid aan onze kant, gebruik op eigen risico", + }, + api: { + name: "API", + title: "Welkom bij de officiële RYD-documenten!", + subtitle: "Selecteer een sectie in het menu om aan de slag te gaan.", + rights: { + title: "Gebruiksrechten", + subtitle: + "Gebruik door derden van deze open API is toegestaan met de volgende beperkingen:", + bullet1: "Attributie: ", + bullet1text: + "Dit project moet duidelijk worden toegeschreven met een link naar deze repo of een link om terug te keren naar youtubedislike.com", + bullet2: "Snelheidsbeperking: ", + bullet2text: + "Er zijn per klant tarieflimieten in plaats van 100 per minuut en 10.000 per dag. Dit geeft een 429-statuscode terug die aangeeft dat uw toepassing moet worden uitgeschakeld", + }, + url: { + title: "URL Informatie", + subtitle: "De API is toegankelijk via de volgende basis-URL: ", + }, + endpoints: { + title: "Beschikbare eindpunten", + subtitle: "Lijst met beschikbare eindpunten is hier beschikbaar: ", + }, + fetching: { + title: "Basiscursus ophalen", + subtitle: "Voorbeeld om stemmen te krijgen voor een bepaalde YouTube-video-ID: ", + title2: "Voorbeeld aanvraag: ", + url: "Verzoek-URL: ", + method: "Verzoekmethode:: ", + headers: "Koppen: ", + response: "Antwoord: ", + error1: 'Een ongeldige YouTube-ID retourneert statuscode 404 "Niet gevonden"', + error2: + 'Een onjuist opgemaakte YouTube-ID retourneert 400 "Slecht verzoek"', + }, + }, + help: { + name: "Help", + title: "Probleemoplossen", + bullet1: "Zorg ervoor dat u de nieuwste versie van de extensie hebt geïnstalleerd, ", + bullet11: "direct", + bullet2: + "Probeer de extensie te verwijderen en opnieuw te installeren, en start vervolgens de browser opnieuw (alle actieve vensters, niet slechts één tabblad)", + bullet3: "Zorg ervoor dat deze link opent: ", + bullet31: "je zou platte tekst moeten zien: ", + bullet4: "Als niets van het bovenstaande helpt - meld uw probleem dan in", + bullet41: "in onze", + bullet4a: "Vertel ons uw besturingssysteem, browsernaam en browserversie", + bullet4b: + "Maak een screenshot van de pagina met het probleem (d.w.z. de YouTube-videopagina) met de console open (druk op ", + bullet4b1: ") - voorbeeld screenshot hieronder.", + bullet4c: + "Maak een screenshot van de extensiepagina van uw browser waarop de extensie is geïnstalleerd.", + bullet4c1: "Om extensies te zien, plaats dit in de adresbalk: ", + firefox: "voor Firefox", + chrome: "voor Chrome, Edge, Brave, Opera, Vivaldi", + }, + faq: { + name: "FAQ", + title: "Veel Gestelde Vragen", + subtitle: "Heeft u nog vragen? Voel je vrij om lid te worden van onze Discord!", + bullet1: "Waar haalt de extensie zijn gegevens vandaan?", + bullet1text: + "Een combinatie van gearchiveerde gegevens van voordat de officiële YouTube-dislike-API werd afgesloten, en geëxtrapoleerd gebruikersgedrag van extensies.", + bullet2: "Waarom wordt het aantal dislikes niet bijgewerkt?", + bullet2text: + "Op dit moment worden video's die niet leuk zijn in de cache opgeslagen en worden ze niet vaak bijgewerkt. Het varieert afhankelijk van de populariteit van een video, maar het kan een paar uur tot een paar dagen duren om te updaten.", + bullet3: "Hoe werkt dit?", + bullet3text: + "De extensie verzamelt de video-ID van de video die je aan het bekijken bent en haalt de afkeer (en andere velden zoals weergaven, vind-ik-leuks enz.) op met behulp van onze API. De extensie geeft vervolgens het aantal dislikes en de verhouding weer op de pagina. Als je een video leuk of niet leuk vindt, wordt deze opgenomen en naar de database gestuurd, zodat een nauwkeurige telling van de dislikes kan worden geëxtrapoleerd.", + bullet4: "Kan ik mijn niet leuk-teller met je delen?", + bullet4text: + "Binnenkort beschikbaar. We onderzoeken het gebruik van Oauth of een andere alleen-lezen API met een beperkte reikwijdte, zodat makers hun afkeer-aantallen verifieerbaarheid kunnen delen.", + bullet5: "Welke gegevens verzamelt u en hoe worden deze verwerkt?", + bullet5text: + 'De extensie verzamelt alleen gegevens die strikt noodzakelijk zijn om goed te kunnen functioneren, zoals het IP-adres of de ID van de video die u bekijkt. Geen van uw gegevens zal ooit worden verkocht aan derden. Als u meer wilt weten over hoe wij omgaan met beveiliging en privacy, bekijk dan onze beveilings FAQ.', + bullet6: "Hoe werkt de API/Backend?", + bullet6text: + "De backend gebruikt gearchiveerde gegevens van toen de youtube-api nog steeds het aantal dislikes retourneerde, extensiegebruikers zoals het aantal likes/dislikes en extrapolatie. In de nabije toekomst zullen we het voor makers van inhoud mogelijk maken om eenvoudig en veilig hun afkeuren-aantal in te dienen en we zullen de gearchiveerde gegevens van ArchiveTeam (4,56 miljard video's) toevoegen aan onze huidige database. U kunt ook een video over het onderwerp bekijken.", + bullet7: "Waarom wordt bij het aantal dislikes 'DISLIKES DISABLED' weergegeven?", + bullet7text: + "Soms kan een recent geüploade video 'DISLIKES UITGESCHAKELD' weergeven, zelfs als de maker dit niet heeft uitgeschakeld. Dit komt door de manier waarop we detecteren of dislikes zijn uitgeschakeld, het zou binnen een paar uur moeten verdwijnen of door de video leuk of niet leuk te vinden en de pagina vernieuwen (hopelijk).", + }, + donate: { + name: "Doneer", + subtitle: + "Met een donatie kunt u onze inspanningen om het internet gratis te houden steunen!", + }, + links: { + name: "Linken", + title: "Project Linken", + subtitle: "Linken naar het project en zijn ontwikkelaars", + contact: "Neem contact op met me", + translators: "Vertalers", + coolProjects: "Coole Projecten", + sponsorBlockDescription: "In video geïntegreerde advertenties overslaan", + filmotDescription: "Zoek YouTube-video's op ondertiteling", + }, +}; diff --git a/Website/_locales/sv_SE.ts b/Website/_locales/sv_SE.ts new file mode 100644 index 00000000..ab7d9673 --- /dev/null +++ b/Website/_locales/sv_SE.ts @@ -0,0 +1,119 @@ +import { sv_SE } from "vuetify/src/locale"; + +export default { + ...sv_SE, + home: { + name: "Hem", + title: "Return YouTube Dislike", + subtitle: "Webbläsartillägg och ett API som visar antalet ogilla på Youtube", + ukraine: "Stöd Ukraina", + sponsors: "Sponsorer", + }, + install: { + name: "Installera", + title: "Välj din webbläsare", + subtitle: "Tillgängligt för Firefox och alla Chromium-webbläsare", + title2: "Andra webbläsare", + subtitle2: "Om din webbläsare ännu inte stöds, prova detta UserScript", + title3: "Tredjepartsimplementeringar", + subtitle3: "Inget ansvar från vår sida, använd på egen risk", + }, + api: { + name: "API", + title: "Välkommen till de officiella RYD-dokumenten!", + subtitle: "För att komma igång, välj ett avsnitt från menyn.", + rights: { + title: "Användningsrättigheter", + subtitle: + "Tredjepartsanvändning av detta öppna API är tillåtet med följande begränsningar:", + bullet1: "Tillskrivning: ", + bullet1text: + "Detta projekt bör tydligt tillskrivas med antingen en länk till denna repo eller en länk till returnyoutubedislike.com", + bullet2: "Satsbegränsning: ", + bullet2text: + "Det finns satsbegränsningar per användare med 100 per minut och 10000 per dag. Detta kommer att returnera en statushod 429 som indikerar att din applikation ska hålla sig borta", + }, + url: { + title: "Webbadressinformation", + subtitle: "API:et är tillgängligt via följande baswebbadress: ", + }, + endpoints: { + title: "Tillgängliga slutpunkter", + subtitle: "Lista över tillgängliga slutpunkter finns här: ", + }, + fetching: { + title: "Grundläggande handledning för hämtning", + subtitle: "Exempel för att hämta röster för ett bestämt YouTubevideo-ID: ", + title2: "Example Request: ", + url: "Request URL: ", + method: "Request Method: ", + headers: "Headers: ", + response: "Response: ", + error1: 'Ett ogiltigt YouTube-ID returnerar statuskoden 404 "Not Found"', + error2: + 'Ett felaktigt formaterat YouTube-ID returnerar 400 "Bad Request"', + }, + }, + help: { + name: "Hjälp", + title: "Felsökning", + bullet1: "Se till att du har den senaste versionen av tillägget installerat, ", + bullet11: "just nu", + bullet2: + "Försök att avinstallera tillägget och installera det igen, starta sedan om webbläsaren (alla aktiva fönster, inte bara en flik)", + bullet3: "Se till att den här länken öppnas: ", + bullet31: "du bör se vanlig text: ", + bullet4: "Om inget av ovanstående hjälper - rapportera ditt problem i", + bullet41: "i vår", + bullet4a: "Tala om för oss ditt operativsystem, webbläsarnamn och webbläsarversion", + bullet4b: + "Ta en skärmdump av sidan du har problem med (t.ex en youtube-videosida) med konsolfönstret öppet (tryck ", + bullet4b1: ") - exempel på skärmdump nedan.", + bullet4c: + "Ta en skärmdump av tilläggssidan i din webbläsare med tillägg installerat.", + bullet4c1: "För att se tilläggen skriv in detta i adressfältet: ", + firefox: "för Firefox", + chrome: "för Chrome, Edge, Brave, Opera och Vivaldi", + }, + faq: { + name: "FAQ", + title: "Vanliga frågor", + subtitle: "Har du fortfarande frågor? Gå gärna med i vår Discord!", + bullet1: "Var får tillägget sina data?", + bullet1text: + "En kombination av arkiverad data från innan det officiella YouTube ogilla-API:et stängdes av och och extrapolerat tilläggsanvändarbeteende.", + bullet2: "Varför uppdateras inte antalet ogilla?", + bullet2text: + "Just nu cachelagras ogilla för videoklipp och de uppdateras inte särskilt ofta. Det varierar beroende på en videos popularitet, men det kan ta allt från några timmar till några dagar att uppdatera.", + bullet3: "Hur fungerar detta?", + bullet3text: + "Tillägget samlar in video-ID:t för videon du tittar på och hämtar ogilla (and other fields like views, likes etc) med hjälp av vårt API. Tillägget visar sedan antalet ogilla och förhållandet på sidan. Om du gillar eller ogillar en video, spelas det in och skickas till databasen så att ett korrekt antal ogilla kan extrapoleras.", + bullet4: "Kan jag dela mina antalet ogilla med dig?", + bullet4text: + "Kommer snart. Vi tittar på att använda Oauth eller ett annat skrivskyddat API med ett begränsat omfång så att kreatörer kan dela med sig av verifierbarheten av sina antal ogilla.", + bullet5: "Vilken data samlar du in och hur behandlas den?", + bullet5text: + 'Tillägget samlar bara in data som är absolut nödvändig för att den ska fungera korrekt, som IP-adressen eller ID:t på videon du tittar på. Inga uppgifter kommer någonsin att säljas till tredjepart. Om du vill veta mer om hur vi hanterar säkerhet och integritet läs då vår vanliga frågor om säkerhet.', + bullet6: "Hur fungerar API/Backend?", + bullet6text: + "Backend använder arkiverad data från när YouTubes API fortfarande returnerade antalet ogilla. Inom en snar framtid kommer vi att tillåta innehållsskapare att enkelt och säkert skicka in sina ogilla och vi kommer att lägga till ArchiveTeams arkiverade data (4,56 miljarder videor) i vår nuvarande databas. Du kan också se en video om ämnet.", + bullet7: "Varför visar antalet ogilla "OGILLA ÄR INAKTIVERAT"?", + bullet7text: + "I bland kan en nyligen uppladdad video visa 'OGILLA ÄR INAKTIVERAT' även om ägaren inte har inaktiverat den. Detta beror på hur informationen om ogilla är inaktiverat hämtas ut. Det bör försvinna inom några timmar eller genom att gilla eller ogilla videon och uppdatera sidan (förhoppningsvis).", + }, + donate: { + name: "Donera", + subtitle: + "Du kan stöda våra ansträngningar att hålla internet fritt med en donation!", + }, + links: { + name: "Länkar", + title: "Projektlänkar", + subtitle: "Länkar till projektet och dess utvecklare", + contact: "Kontakta mig", + translators: "Översättare", + coolProjects: "Häftiga projekt", + sponsorBlockDescription: "Hoppar över annonser integrerade i videon", + filmotDescription: "Sök efter YouTube-videor i undertexterna", + }, +}; diff --git a/Website/_locales/tr.ts b/Website/_locales/tr.ts index 25f695ba..4fc64f2e 100644 --- a/Website/_locales/tr.ts +++ b/Website/_locales/tr.ts @@ -5,8 +5,7 @@ export default { home: { name: "Ana Sayfa", title: "YouTube Dislike Sayısını Geri Getir", - subtitle: - "Tarayıcı uzantısı ve bir API, YouTube'daki dislike sayınızı geri getirir", + subtitle: "YouTube'daki dislike sayılarınızı geri getiren bir tarayıcı uzantısı ve API", ukraine: "Ukrayna'ya Destek Ol", sponsors: "Sponsorlar", }, @@ -15,11 +14,9 @@ export default { title: "Platformunuzu Seçin", subtitle: "Firefox ve bütün Chromium tabanlı tarayıcılarda kullanılabilir", title2: "Diğer Platformlar", - subtitle2: - "Tarayıcınız henüz desteklenmiyorsa UserScript yöntemini deneyin", + subtitle2: "Tarayıcınız henüz desteklenmiyorsa UserScript yöntemini deneyin", title3: "Üçüncü Parti Uygulamalar", - subtitle3: - "Riski tamamen size aittir, bizim tarafımızda sorumluluk kabul edilmemektedir", + subtitle3: "Riski tamamen size aittir, bizim tarafımızda sorumluluk kabul edilmemektedir", }, api: { name: "API", @@ -31,10 +28,10 @@ export default { "Herkese açık API'nin üçüncü parti kişilerin kullanımında aşağıdaki kısıtlamalara izin verir:", bullet1: "Atıf: ", bullet1text: - "Bu proje, bu depoya ya da returnyoutubedislike.com sitesine bir bağlantı ile açıkça atfedilmelidir", + "Bu proje, bu depoya ya da returnyoutubedislike.com sitesine bir bağlantı ile açıkça atfedilmelidir.", bullet2: "Hız Sınırlaması: ", bullet2text: - "Kullanıcı başına dakikada 100 ve günde 10.000 hız sınırlaması vardır. Bu, uygulamanızın geri çekilmesi gerektiğini belirten 429 durum kodunu döndürür", + "Kullanıcı başına dakikada 100 ve günde 10.000 hız sınırlaması vardır. Bu, uygulamanızın geri çekilmesi gerektiğini belirten 429 durum kodunu döndürür.", }, url: { title: "URL Bilgisi", @@ -46,16 +43,15 @@ export default { }, fetching: { title: "Temel Veri Alma Eğitimi", - subtitle: - "Belirli bir YouTube ID'sinin oylamalarını elde etmek için bir örnek: ", + subtitle: "Belirli bir YouTube ID'sinin oylamalarını elde etmek için bir örnek: ", title2: "Örnek İstek: ", url: "İstek URL'si: ", method: "İstek Yöntemi: ", headers: "Header'lar: ", response: "Sonuç: ", - error1: 'Geçersiz bir YouTube ID\'si, 404 "Not Found" olarak döndürülür', + error1: 'Geçersiz bir YouTube ID\'si, 404 "Not Found" olarak döndürülür.', error2: - 'Yanlış biçimlendirilmiş bir YouTube ID\'si, 400 "Bad Request" olarak döndürülür', + 'Yanlış biçimlendirilmiş bir YouTube ID\'si, 400 "Bad Request" olarak döndürülür.', }, }, help: { @@ -68,13 +64,11 @@ export default { bullet3: "Şu bağlantıyı açtığınızdan emin olun: ", bullet31: "şöyle bir düz metin görmelisiniz: ", bullet4: "Yukarıdakiler yardımcı olmadıysa - Discord sunucumuzdaki ", - bullet41: - " kanalından problemi bildirin (İngilizce bir şekilde) Discord sunucumuz: ", - bullet4a: - "Bize İşletim Sisteminizi, Tarayıcı Adınızı ve Tarayıcı Sürümünüzü söyleyin", - bullet4b: "Konsol açıkken (açmak için ", - bullet4b1: - " tuşuna basın) sorunu yaşadığınız sayfanın ekran görüntüsünü alın (yani YouTube watch sayfasının) - Ekran görüntüsü örneği aşağıdadır.", + bullet41: " kanalından problemi bildirin (İngilizce bir şekilde) Discord sunucumuz: ", + bullet4a: "Bize İşletim Sisteminizi, Tarayıcı Adınızı ve Tarayıcı Sürümünüzü söyleyin", + bullet4b: + "Konsol açıkken (açmak için ", + bullet4b1: " tuşuna basın) sorunu yaşadığınız sayfanın ekran görüntüsünü alın (yani YouTube watch sayfasının) - Ekran görüntüsü örneği aşağıdadır.", bullet4c: "Uzantı yüklüyken tarayıcınızın uzantılar sayfasının ekran görüntüsünü alın.", bullet4c1: "Uzantıları görmek için şu linki adres çubuğuna yapıştırın: ", @@ -84,8 +78,7 @@ export default { faq: { name: "SSS", title: "Sıkça Sorulan Sorular", - subtitle: - "Hâlâ sorun mu yaşıyorsunuz? Discord sunucumuza katılmaktan çekinmeyin! (İngilizce)", + subtitle: "Hâlâ sorun mu yaşıyorsunuz? Discord sunucumuza katılmaktan çekinmeyin! (İngilizce)", bullet1: "Uzantı, verileri nereden alıyor?", bullet1text: "Resmî YouTube dislike sayısı API'si kapatılmadan önceki arşivlenmiş verilerden ve tahmin edilen uzantı kullanıcısı davranışının bir birleşimiyle.", @@ -101,13 +94,12 @@ export default { bullet5: "Hangi verileri topluyorsunuz ve bunlar nasıl işleniyor?", bullet5text: "Uzantı, yalnızca izlediğiniz videonun IP adresi veya videonun ID'si gibi düzgün çalışması için kesinlikle gerekli olan verileri toplar. Verileriniz asla 3. taraflara satılmayacaktır. Güvenliği ve gizliliği nasıl ele aldığımız hakkında daha fazla bilgi için security FAQ'ya gidin.", - bullet6: "API/Yazılım(Backend) nasıl çalışıyor?", + bullet6: "API/Backend nasıl çalışıyor?", bullet6text: "Yazılım, YouTube API'sinin dislike sayısını ve uzantı kullanıcılarının like/dislike sayısı sonuçların genişletilmesinin döndürmeye devam ettiği zamana ait arşivlenmiş verileri kullanır. Yakın zamanda içerik üreticilerin dislike sayısını kolay ve güvenli bir şekilde göndermelerine izin vereceğiz ve ArchiveTeam'in arşivlenmiş verilerini (4,56 milyar video) veri tabanımıza ekleyeceğiz. Ayrıca konu ile ilgili videoyu da izleyebilirsiniz.", - bullet7: - "Dislike sayısı neden 'DISLIKES DISABLED'(DISLIKE'LAR AKTİF DEĞİL) olarak gözüküyor?", + bullet7: "Dislike sayısı neden 'DISLIKE'LAR KAPALI' olarak gözüküyor?", bullet7text: - "Yazma sırasında like ve dislike sayısını devre dışı bırakan videoların dislike sayılarını göstermiyoruz. Uzantı, bu videolar için 'DISLIKES DISABLED'(DISLIKE'LAR AKTİF DEĞİL) mesajını görüntüler. Yakında tüm videolarda dislike sayısını göstereceğiz. Bu, yalnızca geçici bir çözümdür. Bu nedenle insanlar uzantının bozuk olduğunu düşünmez (zaten iyi çalışmıyor). Bazen yakın zamanda yüklenen bir videoda, içerik üreticisi onu devre dışı bırakmamış olsa bile 'DISLIKES DISABLED' olarak gözükebilir. Bunun nedeni, dislike sayısını devre dışı bırakıp bırakmadığını tespit etmemizdir. Birkaç saat içinde videoyu like ya da dislike atarsanız veya sayfayı yenilerseniz kaybolması gerekir (umarız).", + "Yazma sırasında like ve dislike sayısını devre dışı bırakan videoların dislike sayılarını göstermiyoruz. Uzantı, bu videolar için 'DISLIKE'LAR KAPALI' mesajını görüntüler. Yakında tüm videolarda dislike sayısını göstereceğiz. Bu, yalnızca geçici bir çözümdür. Bu nedenle insanlar uzantının bozuk olduğunu düşünmez (zaten iyi çalışmıyor). Bazen yakın zamanda yüklenen bir videoda, içerik üreticisi onu devre dışı bırakmamış olsa bile 'DISLIKE'LAR KAPALI' olarak gözükebilir. Bunun nedeni, dislike sayısını devre dışı bırakıp bırakmadığını tespit etmemizdir. Birkaç saat içinde videoyu like ya da dislike atarsanız veya sayfayı yenilerseniz kaybolması gerekir (umarız).", }, donate: { name: "Bağış Yap", @@ -120,7 +112,7 @@ export default { subtitle: "Projeye ve geliştiricilerine bağlantılar", contact: "Bana Ulaşın", translators: "Çevirmenler", - coolProjects: "Hoş Projeler", + coolProjects: "Havalı Projeler", sponsorBlockDescription: "Videolara gömülü reklamları pas geçer", filmotDescription: "YouTube videolarını alt yazılara göre aramanızı sağlar", }, diff --git a/Website/_locales/uk.ts b/Website/_locales/uk.ts new file mode 100644 index 00000000..17d06abc --- /dev/null +++ b/Website/_locales/uk.ts @@ -0,0 +1,119 @@ +import { uk } from "vuetify/src/locale"; +// By dsty#1614 +export default { + ...uk, + home: { + name: "Головна", + title: "Return YouTube Dislike", + subtitle: "Браузерне розширення та API, що дозволяє вам бачити відмітки «Не подобається» на YouTube", + ukraine: "Підтримати Україну", + sponsors: "Спонсори", + }, + install: { + name: "Завантажити", + title: "Оберіть вашу платформу", + subtitle: "Доступно на Firefox та усіх Chromium браузерах", + title2: "Інші платформи", + subtitle2: "Якщо ваш браузер не підтримується, спробуйте цей UserScript", + title3: "Стороннє ПЗ", + subtitle3: "Ми не маємо відношення до цього, використовуйте на свій страх і ризик", + }, + api: { + name: "API", + title: "Вітаємо у офіційній документації RYD!", + subtitle: "Щоб почати, виберіть розділ у меню.", + rights: { + title: "Права використання", + subtitle: + "Використання цього відкритого API сторонніми особами дозволено з наступними обмеженнями:", + bullet1: "Атрибуція: ", + bullet1text: + "Цей проєкт має бути чітко описано, використовуючи посилання, або ж на цей репозиторій, або ж на returnyoutubedislike.com", + bullet2: "Обмеження: ", + bullet2text: + "Існують обмеження на швидкісті для кожного клієнта - 100 за хвилину і 10 000 за день. Це видасть код помилки 429, який вказує на те, що вашому додатку слід завершити роботу", + }, + url: { + title: "Інформація про посилання", + subtitle: "API доступний за наступним посиланням: ", + }, + endpoints: { + title: "Достпупні «ендпоінти»", + subtitle: "Перелік доступних «ендпоінтів» можна переглянути тут: ", + }, + fetching: { + title: "Базовий посібник по отриманню", + subtitle: "Приклад отримання оцінок відео на YouTube за ID ", + title2: "Приклад запиту: ", + url: "Посилання запиту: ", + method: "Метод запиту: ", + headers: "Заголовок: ", + response: "Відповідь: ", + error1: 'Недійсний YouTube ID видасть код помилки 404 "Not Found"', + error2: + 'YouTube ID у невірному форматі видасть код помилки 400 "Bad Request"', + }, + }, + help: { + name: "Допомога", + title: "Усунення несправностей", + bullet1: "Переконайтеся, що у вас встановлена остання версія розширення, наразі це - ", + bullet11: "", + bullet2: + "Спробуйте видалити розширення і встановити його знову, а потім перезавантажте браузер (усі активні вікна, а не лише одну вкладку).", + bullet3: "Переконайтеся, що наступне посилання відкривається: ", + bullet31: "і ви бачите там цей текст: ", + bullet4: "Якщо нічого з перерахованого вище не допомогло - повідомте про проблему в каналі", + bullet41: "у нашому", + bullet4a: "Повідомте нам вашу операційну систему, назву та версію браузера", + bullet4b: + "Зробіть знімок екрана сторінки з проблемою (тобто сторінки відео на YouTube) із відкритою консоллю (натисніть ", + bullet4b1: ") - приклад знімка екрана нижче.", + bullet4c: + "Зробіть знімок екрана сторінки з встановленими розширеннями вашого браузера.", + bullet4c1: "Щоб побачити розширення, напишіть це в адресний рядок: ", + firefox: "для Firefox", + chrome: "для Chrome, Edge, Brave, Opera, Vivaldi", + }, + faq: { + name: "ЧаПи", + title: "Часті питання", + subtitle: "Залишилися питання? Не соромтеся приєднуватися до нашого Discord!", + bullet1: "Звідки розширення отримує дані?", + bullet1text: + "Комбінація архівних даних, отриманих до закриття офіційного API відміток «Не подобається» на YouTube та екстрапольованої поведінки користувачів розширення.", + bullet2: "Чому кількість відміток «Не подобається» не оновлюється?", + bullet2text: + "Наразі відмітки «Не подобається» кешуються й не оновлюються надто часто. Це залежить від популярності відео, але для оновлення може знадобитися від кількох годин до кількох днів.", + bullet3: "Як це працює?", + bullet3text: + "Розширення отримує ID відео, яке ви переглядаєте, та дізнається кількість відміток «Не подобається» (та інші дані: перегляди, відмітки «Подобається» тощо) за допомогою нашого API. Потім розширення відображає кількість відміток «Не подобається» та їх коефіцієнт на сторінці. Якщо ви ставите відмітки «Подобається» чи «Не подобається», це записується та надсилається до бази даних, щоб можна було екстраполювати точну їх кількість нелайків.", + bullet4: "Чи можу я поділитися з вами своїми відмітками «Не подобається»?", + bullet4text: + "Незабаром. Ми розглядаємо можливість використання Oauth або іншого API, доступного тільки для читання, з обмеженою областю дій, щоб творці могли ділитися своїми відмітками «Не подобається»", + bullet5: "Які дані ви збираєте та як вони обробляються?", + bullet5text: + 'Розширення збирає лише ті дані, які необхідні для правильної його роботи, такі як IP-адреси або ID відео, яке ви дивитеся. Ваші дані ніколи не будуть продані третім особам. Якщо ви хочете дізнатися більше про те, як ми забезпечуємо безпеку та конфіденційність, ознайомтесь з нашими ЧаПи по безпеці.', + bullet6: "Як працює API/серверна сторона?", + bullet6text: + "Серверна частина використовує архівні дані з тих пір, доки YouTube API все ще видавав кількість відміток «Не подобається», а також відмітки «Подобається»/«Не подобається» користувачів розширення та екстраполяцію. В найближчому майбутньому ми дозволимо творцям контенту легко та безпечно надсилати свої відмітки «Не подобається», а також ми додамо архівні дані ArchiveTeam (4,56 мільярди відео) до нашої поточної бази даних. Ви можете переглянути відео на цю тему.", + bullet7: "Чому лічильник відміток «Не подобається» пише 'DISLIKES DISABLED'?", + bullet7text: + "Іноді на нещодавно завантаженому відео може з'являтися повідомлення 'DISLIKES DISABLED', навіть попри те, що автор не вимикав відмітки «Не подобається». Це пов’язано з тим, як ми визначаємо, чи вимкнені оцінки «Не подобається». Це повідомлення має зникнути через кілька годин або після отримання відмітки «Подобається»/«Не подобається» і оновлення сторінки (сподіваюся).", + }, + donate: { + name: "Підтримати", + subtitle: + "Ви можете підтримати пожертвою наші зусилля зробити Інтернет вільнішим!", + }, + links: { + name: "Посилання", + title: "Посилання проєкту", + subtitle: "Посилання на проєкт і його розробників", + contact: "Зв'язок зі мною", + translators: "Перекладачі", + coolProjects: "Круті проєкти", + sponsorBlockDescription: "пропускає вбудовану у відео рекламу", + filmotDescription: "пошук відео на YouTube по субтитрах", + }, +}; \ No newline at end of file diff --git a/Website/layouts/default.vue b/Website/layouts/default.vue index 4d5e195d..2aa63b37 100644 --- a/Website/layouts/default.vue +++ b/Website/layouts/default.vue @@ -107,7 +107,8 @@ export default { { name: "日本語", locale: "ja" }, { name: "Français", locale: "fr" }, // { name: "Deutsch", locale: "de" }, - // ... + { name: "Українська", locale: "uk" }, + { name: "한국어", locale: "ko" }, ], alert: { show: false, diff --git a/Website/nuxt.config.js b/Website/nuxt.config.js index bf5bbbc7..5d126e5a 100644 --- a/Website/nuxt.config.js +++ b/Website/nuxt.config.js @@ -5,6 +5,8 @@ import ru from "./_locales/ru"; import cs from "./_locales/cs"; import ja from "./_locales/ja"; import fr from "./_locales/fr"; +import uk from "./_locales/uk"; +import ko from "./_locales/ko"; // import de from "./_locales/de"; // ... export default { @@ -50,7 +52,7 @@ export default { // Vuetify module configuration: https://go.nuxtjs.dev/config-vuetify vuetify: { lang: { - locales: { en, es, tr, ru, cs, ja, fr /* de, ...*/ }, + locales: { en, es, tr, ru, cs, ja, fr, uk, ko /* de, ...*/ }, current: "en", }, theme: { diff --git a/Website/package.json b/Website/package.json index 10a61155..ac7c0074 100644 --- a/Website/package.json +++ b/Website/package.json @@ -3,10 +3,10 @@ "version": "1.1.0", "private": true, "scripts": { - "dev": "nuxt", + "dev": "set NODE_OPTIONS=--openssl-legacy-provider && nuxt", "build": "nuxt build", "start": "nuxt start", - "generate": "nuxt generate", + "generate": "set NODE_OPTIONS=--openssl-legacy-provider && nuxt generate", "lint": "eslint --fix --ext .js,.vue --ignore-path .eslintignore ." }, "dependencies": { diff --git a/Website/pages/index.vue b/Website/pages/index.vue index 3b21ceef..745631fa 100644 --- a/Website/pages/index.vue +++ b/Website/pages/index.vue @@ -63,13 +63,13 @@ -
+

mdi-heart {{ $vuetify.lang.t("$vuetify.home.sponsors") }} @@ -109,14 +109,6 @@ export default { discordLink: "https://discord.gg/mYnESY4Md5", sponsors: [ { name: "Piepacker", link: "https://piepacker.com/" }, - { - name: "Seed4.Me VPN", - link: "https://www.seed4.me/users/register?gift=ReturnYoutubeDislike", - }, - { - name: "PocketTube", - link: "https://yousub.info/?utm_source=returnyoutubedislike", - }, { name: "Become our sponsor", link: "https://www.patreon.com/join/returnyoutubedislike/checkout?rid=8008601", diff --git a/Website/pages/links.vue b/Website/pages/links.vue index cd6c4469..d438594d 100644 --- a/Website/pages/links.vue +++ b/Website/pages/links.vue @@ -113,6 +113,10 @@ export default { tag: "NiniKo", lang: "Français", }, + { + tag: "dsty#1614", + lang: "Українська", + }, ], coolProjects: [ { diff --git a/Website/raw_assets/troubleshooting.png b/Website/raw_assets/troubleshooting.png index 00b77ade..47878b52 100644 Binary files a/Website/raw_assets/troubleshooting.png and b/Website/raw_assets/troubleshooting.png differ diff --git a/Website/raw_assets/ukraine-flag-xs.png b/Website/raw_assets/ukraine-flag-xs.png index 3d9e39a9..3e18d6fa 100644 Binary files a/Website/raw_assets/ukraine-flag-xs.png and b/Website/raw_assets/ukraine-flag-xs.png differ diff --git a/Website/static/ui/abstract.svg b/Website/static/ui/abstract.svg index 6298c427..661445c8 100644 --- a/Website/static/ui/abstract.svg +++ b/Website/static/ui/abstract.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/Website/store/README.md b/Website/store/README.md index 1972d277..2cc89d1e 100644 --- a/Website/store/README.md +++ b/Website/store/README.md @@ -1,3 +1,5 @@ +Read this in other languages: [Nederlands](READMEnl.md), [Türkçe](READMEtr.md) + # STORE **This directory is not required, you can delete it if you don't want to use it.** diff --git a/Website/store/READMEnl.md b/Website/store/READMEnl.md new file mode 100644 index 00000000..3006a01f --- /dev/null +++ b/Website/store/READMEnl.md @@ -0,0 +1,12 @@ +Read this in other languages: [English](READMEen.md), [Türkçe](READMEtr.md) + +# OPSLAAN + +**Deze map is niet vereist, u kunt deze verwijderen als u deze niet wilt gebruiken.** + +Deze map bevat uw Vuex Store-bestanden. +De Vuex Store-optie is geïmplementeerd in het Nuxt.js-framework. + +Het aanmaken van een bestand in deze map activeert automatisch de optie in het framework. + +Meer informatie over het gebruik van deze directory in [de documentatie](https://nuxtjs.org/guide/vuex-store). diff --git a/Website/store/READMEtr.md b/Website/store/READMEtr.md new file mode 100644 index 00000000..24128db1 --- /dev/null +++ b/Website/store/READMEtr.md @@ -0,0 +1,12 @@ +Read this in other languages: [English](README.md), [Nederlands](READMEnl.md) + +# MAĞAZA + +**Bu dizin gerekli değildir, kullanmak istemiyorsanız silebilirsiniz.** + +Bu dizin, Vuex Store dosyalarınızı içerir. +Vuex Store seçeneği Nuxt.js çerçevesinde uygulanmaktadır. + +Bu dizinde bir dosya oluşturmak, çerçevedeki seçeneği otomatik olarak etkinleştirecektir. + +Bu dizinin kullanımı ile ilgili daha fazla bilgi için [belgeleme](https://nuxtjs.org/guide/vuex-store)ye göz atın. diff --git a/extension-description-store-Chinese.txt b/extension-description-store-Chinese.txt new file mode 100644 index 00000000..4de6d9a6 --- /dev/null +++ b/extension-description-store-Chinese.txt @@ -0,0 +1,20 @@ +"Return YouTube Dislike" 恢复了在 YouTube 上查看不喜欢的功能。 + +如果它不起作用:打开扩展选项卡(chrome://extensions/),禁用此扩展,然后重新启用它。这应该可以解决大多数问题,因为在某些情况下,Chromium 中存在一个破坏扩展的错误。希望 Chromium 团队能尽快修复这个问题。 + +从2021年12月13日开始,YouTube 移除了从其API中查看不喜欢的功能。 +这个扩展旨在通过使用归档的喜欢和不喜欢数据以及扩展用户所做的喜欢和不喜欢来显示最准确的评分,以恢复用户的权力。 + +当前已经存储了超过2亿多个视频的喜欢和不喜欢数据,截止到2021年12月13日。 + +积极增长并保持更新,以跟踪2021年12月13日之后的上传内容。 + +使用该扩展的用户越多,它的准确性就越高。 + +2021年12月13日之后上传的不受欢迎的视频可能显示的数据比更受欢迎的视频不太准确。 + +该扩展目前处于积极开发阶段,因此如果您遇到任何问题,请毫不犹豫地在我们的GitHub页面或我们的Discord服务器上报告它们。 + +更多功能即将推出! + +https://github.com/Anarios/return-youtube-dislike diff --git a/extension-description-store-french.txt b/extension-description-store-french.txt index d4a45d5f..958e8b3a 100644 --- a/extension-description-store-french.txt +++ b/extension-description-store-french.txt @@ -11,7 +11,7 @@ Croissance active et reste à jour avec les uploads datant d'après le 13 décem Plus il y aura d'utilisateurs de l'extension, plus elle sera précise. -Les vidéos impopulaires mises en ligne ultérieurement au 13 décembre 2021 peuvent présenter des données moins précises que les vidéos plus populaires. +Les vidéos moins populaires mises en ligne ultérieurement au 13 décembre 2021 peuvent présenter des données moins précises que les vidéos plus populaires. Cette extension est actuellement en développement actif, donc si vous rencontrez des problèmes, n'hésitez pas à les signaler sur notre page GitHub ou sur notre serveur Discord. diff --git a/extension-description-store-greek.txt b/extension-description-store-greek.txt new file mode 100644 index 00000000..5a24b7fe --- /dev/null +++ b/extension-description-store-greek.txt @@ -0,0 +1,20 @@ +Το Return YouTube Dislike είναι μια επέκταση ανοιχτού κώδικα η οποία επαναφέρει στο YouTube τον μετρητή dislike. + +Εάν δεν λειτουργεί: ανοίξτε την καρτέλα Επεκτάσεις (chrome://extensions/), απενεργοποιήστε αυτήν την επέκταση και ενεργοποιήστε την ξανά. Αυτό θα διορθώσει τα περισσότερα προβλήματα, καθώς υπάρχει ένα σφάλμα στο Chromium που σπάει την επέκταση σε ορισμένες περιπτώσεις. Ας ελπίσουμε ότι η ομάδα του Chromium θα το διορθώσει σύντομα. + +Στις 13 Δεκεμβρίου 2021, το YouTube αφαίρεσε απο το API την δυνατότητα να εμφανίζονται τα dislikes. +Η επέκταση αυτή στοχεύει να επαναφέρει αυτή την δυνατότατα στους χρήστες. Ένας συνδυασμός αρχειοθετημένων δεδομένων like και dislike, καθώς και η χρήση των like και dislike των χρηστών της επέκτασης, προβάλουν με τον πιό ακριβή τρόπο την ακροαματικότητα των βίντεο. + +Αυτή την στιγμή υπάρχει μια βάση με 200+ εκατομμύρια καταχωρημένα βίντεο και τα likes/dislikes τους, προερχόμενα πριν απο τις 13 Δεκεμβρίου 2021. + +Αναπτύσσεται ενεργά και ενημερώνεται για τις μεταφορτώσεις βίντεο μετά τις 13 Δεκεμβρίου 2021. + +Όσο περισσότεροι χρήστες χρησιμοποιούν την επέκταση, τόσο πιο ακριβής θα είναι. + +Μη δημοφιλή βίντεο που ανέβηκαν μετά τις 13 Δεκεμβρίου 2021 ενδέχεται να εμφανίζουν λιγότερο ακριβή δεδομένα από τα πιο δημοφιλή βίντεο. + +Η επέκταση βρίσκεται επί του παρόντος σε ενεργό φάση ανάπτυξης, επομένως εάν αντιμετωπίζετε προβλήματα, μη διστάσετε να τα αναφέρετε στη σελίδα μας στο GitHub ή στον διακομιστή Discord. + +Σύντομα με περισσότερες δυνατότητες! + +https://github.com/Anarios/return-youtube-dislike diff --git a/extension-description-store-turkish.txt b/extension-description-store-turkish.txt index 067eecee..c7f40598 100644 --- a/extension-description-store-turkish.txt +++ b/extension-description-store-turkish.txt @@ -1,4 +1,4 @@ -YouTube Dislike Sayısını Geri Getir, YouTube'da dislike durumlarını görme özelliğini geri getirir. +YouTube Dislike Sayısını Geri Getir YouTube'da beğenmeme durumlarını görme özelliğini geri getirir. Eğer çalışmazsa: uzantılar sekmesini açın (chrome://extensions/) bu uzantıyı devre dışı bırakın ve yeniden aktifleştirin. Bu, chromium'daki bazı durumlarda uzantıyı bozan bir hatadır. Bu, sorunların çoğunu çözmelidir. Umarız chromium ekibi bunu yakın zamanda düzeltir. diff --git a/extension-description-store-ukrainian.txt b/extension-description-store-ukrainian.txt new file mode 100644 index 00000000..881a4986 --- /dev/null +++ b/extension-description-store-ukrainian.txt @@ -0,0 +1,20 @@ +Return YouTube Dislike відновлює можливість бачити кількість відміток «Не подобається» на YouTube. + +Якщо не працює: відкрийте вкладку розширень (chrome://extensions/), вимкніть це розширення та увімкніть його знову. Це має вирішити більшість проблем, оскільки в Chromium є помилка, яка в деяких випадках перешкоджає роботі розширення. Сподіваюся, команда Chromium незабаром виправить це. + +Починаючи з 13 грудня 2021 року YouTube видалив можливість бачити відмітки «Не подобається» зі свого API. +Це розширення має намір повернути владу користувачам, використовуючи поєднання архівних даних про кількість відміток «Подобається» та «Не подобається», а також кількість цих відміток серед користувачів розширення, аби показати найточніші рейтинги. + +Наразі більше ніж 200 мільйонів даних про відмітки «Подобається»/«Не подобається» збережено до 13 грудня 2021 року. + +Активно росте та оновюється новими відео, що завантажені після 13 грудня 2021 року. + +Що більше користувачів використовує розширення, тим точніше воно буде. + +Не надто популярні відео, завантажені після 13 грудня 2021 року, можуть містити менш точні дані, ніж популярні відео. + +Це розширення наразі знаходиться в активній стадії розробки, тому, якщо у вас виникнуть будь-які проблеми, не соромтесь повідомляти про них на нашій сторінці GitHub або на нашому сервері в Discord. + +Більше можливостей з'явиться найближчим часом! + +https://github.com/Anarios/return-youtube-dislike diff --git a/globals.d.ts b/globals.d.ts new file mode 100644 index 00000000..74680222 --- /dev/null +++ b/globals.d.ts @@ -0,0 +1,7 @@ +// https://github.com/oven-sh/bun/issues/358#issuecomment-1715648224 + +/// + +declare interface Window { + returnDislikeButtonlistenersSet: boolean; +} diff --git a/package-lock.json b/package-lock.json index 066995c6..81fcccd8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,12 @@ "@babel/core": "^7.16.5", "@babel/preset-env": "^7.16.5", "@babel/runtime": "^7.16.5", + "@types/chrome": "^0.0.246", "babel-loader": "^8.2.3", "copy-webpack-plugin": "^10.2.0", - "filemanager-webpack-plugin": "^6.1.7", + "filemanager-webpack-plugin": "^8.0.0", + "ts-loader": "^9.5.0", + "typescript": "^5.2.2", "webpack-cli": "^4.9.1" } }, @@ -1798,25 +1801,6 @@ "node": ">=10.0.0" } }, - "node_modules/@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "dependencies": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@mrmlnc/readdir-enhanced/node_modules/glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", - "dev": true - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1861,6 +1845,16 @@ "@types/glob": "*" } }, + "node_modules/@types/chrome": { + "version": "0.0.246", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.246.tgz", + "integrity": "sha512-MxGxEomGxsJiL9xe/7ZwVgwdn8XVKWbPvxpVQl3nWOjrS0Ce63JsfzxUc4aU3GvRcUPYsfufHmJ17BFyKxeA4g==", + "dev": true, + "dependencies": { + "@types/filesystem": "*", + "@types/har-format": "*" + } + }, "node_modules/@types/eslint": { "version": "8.2.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz", @@ -1890,6 +1884,21 @@ "dev": true, "peer": true }, + "node_modules/@types/filesystem": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.33.tgz", + "integrity": "sha512-2KedRPzwu2K528vFkoXnnWdsG0MtUwPjuA7pRy4vKxlxHEe8qUDZibYHXJKZZr2Cl/ELdCWYqyb/MKwsUuzBWw==", + "dev": true, + "dependencies": { + "@types/filewriter": "*" + } + }, + "node_modules/@types/filewriter": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.30.tgz", + "integrity": "sha512-lB98tui0uxc7erbj0serZfJlHKLNJHwBltPnbmO1WRpL5T325GOHRiQfr2E29V2q+S1brDO63Fpdt6vb3bES9Q==", + "dev": true + }, "node_modules/@types/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", @@ -1900,6 +1909,12 @@ "@types/node": "*" } }, + "node_modules/@types/har-format": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.13.tgz", + "integrity": "sha512-PwBsCBD3lDODn4xpje3Y1di0aDJp4Ww7aSfMRVw6ysnxD4I7Wmq2mBkSKaDtN403hqH5sp6c9xQUvFYY3+lkBg==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -2222,17 +2237,50 @@ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansi-styles/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ansi-styles/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "node_modules/archiver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.0.tgz", - "integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", "dev": true, "dependencies": { "archiver-utils": "^2.1.0", - "async": "^3.2.0", + "async": "^3.2.4", "buffer-crc32": "^0.2.1", "readable-stream": "^3.6.0", - "readdir-glob": "^1.0.0", + "readdir-glob": "^1.1.2", "tar-stream": "^2.2.0", "zip-stream": "^4.1.0" }, @@ -2262,9 +2310,9 @@ } }, "node_modules/archiver-utils/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", @@ -2285,33 +2333,6 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-union": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", @@ -2324,60 +2345,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/async": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", - "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", "dev": true }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, "node_modules/babel-loader": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.3.tgz", @@ -2447,36 +2420,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -2589,7 +2532,7 @@ "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true, "engines": { "node": "*" @@ -2602,26 +2545,6 @@ "dev": true, "peer": true }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -2635,12 +2558,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", - "dev": true - }, "node_modules/caniuse-lite": { "version": "1.0.30001287", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001287.tgz", @@ -2651,112 +2568,30 @@ "url": "https://opencollective.com/browserslist" } }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "peer": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "node": ">=10" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/class-utils/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true, + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=6.0" } }, "node_modules/clean-stack": { @@ -2782,19 +2617,6 @@ "node": ">=6" } }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -2829,16 +2651,10 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, "node_modules/compress-commons": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", - "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", "dev": true, "dependencies": { "buffer-crc32": "^0.2.13", @@ -2853,7 +2669,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "node_modules/convert-source-map": { @@ -2865,15 +2681,6 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/copy-webpack-plugin": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-10.2.0.tgz", @@ -2980,404 +2787,71 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, - "node_modules/cp-file": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-7.0.0.tgz", - "integrity": "sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw==", + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "nested-error-stacks": "^2.0.0", - "p-event": "^4.1.0" + "bin": { + "crc32": "bin/crc32.njs" }, "engines": { - "node": ">=8" + "node": ">=0.8" } }, - "node_modules/cpy": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/cpy/-/cpy-8.1.2.tgz", - "integrity": "sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg==", + "node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", "dev": true, "dependencies": { - "arrify": "^2.0.1", - "cp-file": "^7.0.0", - "globby": "^9.2.0", - "has-glob": "^1.0.0", - "junk": "^3.1.0", - "nested-error-stacks": "^2.1.0", - "p-all": "^2.1.0", - "p-filter": "^2.1.0", - "p-map": "^3.0.0" - }, - "engines": { - "node": ">=8" + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cpy/node_modules/@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true, "engines": { - "node": ">= 6" + "node": ">= 10" } }, - "node_modules/cpy/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { - "array-uniq": "^1.0.1" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 8" } }, - "node_modules/cpy/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "object-keys": "^1.0.12" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/cpy/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/del": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cpy/node_modules/dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "dependencies": { - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cpy/node_modules/fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "dependencies": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/cpy/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cpy/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cpy/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/cpy/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cpy/node_modules/globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/cpy/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/cpy/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cpy/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cpy/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cpy/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cpy/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cpy/node_modules/path-type/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/cpy/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cpy/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/crc-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", - "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", - "dev": true, - "dependencies": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - }, - "bin": { - "crc32": "bin/crc32.njs" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/crc32-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", - "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", - "dev": true, - "dependencies": { - "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "dependencies": { - "object-keys": "^1.0.12" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/del": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", - "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", - "dev": true, - "dependencies": { - "globby": "^11.0.1", - "graceful-fs": "^4.2.4", - "is-glob": "^4.0.1", - "is-path-cwd": "^2.2.0", - "is-path-inside": "^3.0.2", - "p-map": "^4.0.0", - "rimraf": "^3.0.2", - "slash": "^3.0.0" + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" }, "engines": { "node": ">=10" @@ -3415,21 +2889,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/del/node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -3471,7 +2930,6 @@ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", "dev": true, - "peer": true, "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -3606,290 +3064,130 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", - "dev": true, - "engines": { - "node": ">=0.8" - } + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": ">=0.10.0" + "node": ">=8.6.0" } }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "is-descriptor": "^0.1.0" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "reusify": "^1.0.4" } }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "node_modules/filemanager-webpack-plugin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-8.0.0.tgz", + "integrity": "sha512-TYwu62wgq2O2c3K80Sfj8vEys/tP5wdgYoySHgUwWoc2hPbQY3Mq3ahcAW634JvHCTcSV7IAfRxMI3wTXRt2Vw==", "dev": true, "dependencies": { - "kind-of": "^3.0.2" + "@types/archiver": "^5.3.1", + "archiver": "^5.3.1", + "del": "^6.1.1", + "fast-glob": "^3.2.12", + "fs-extra": "^10.1.0", + "is-glob": "^4.0.3", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" + "node": "^14.13.1 || >=16.0.0" }, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "webpack": "^5.0.0" } }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "node_modules/filemanager-webpack-plugin/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "engines": { - "node": ">=0.10.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/expand-brackets/node_modules/kind-of": { + "node_modules/filemanager-webpack-plugin/node_modules/ajv-keywords": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "dev": true, "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "fast-deep-equal": "^3.1.3" }, - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "ajv": "^8.8.2" } }, - "node_modules/extglob/node_modules/define-property": { + "node_modules/filemanager-webpack-plugin/node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.9.tgz", - "integrity": "sha512-MBwILhhD92sziIrMQwpqcuGERF+BH99ei2a3XsGJuqEKcSycAL+w0HWokFenZXona+kjFr82Lf71eTxNRC06XQ==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/filemanager-webpack-plugin": { - "version": "6.1.7", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-6.1.7.tgz", - "integrity": "sha512-0hhPpmod5t0xy1hBSA9gXi0WlOHL3+x56IBt0b/VMhvbZ5/z6jakXvNOTuVmn4wOZwAORvAeH5qQ5Qs6NdPyiw==", - "dev": true, - "dependencies": { - "@types/archiver": "^5.1.1", - "archiver": "^5.3.0", - "cpy": "^8.1.2", - "del": "^6.0.0", - "fs-extra": "^10.0.0", - "is-glob": "^4.0.1", - "schema-utils": "^3.1.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, "node_modules/filemanager-webpack-plugin/node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" }, "engines": { - "node": ">= 10.13.0" + "node": ">= 12.13.0" }, "funding": { "type": "opencollective", @@ -3935,27 +3233,6 @@ "node": ">=8" } }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -3963,9 +3240,9 @@ "dev": true }, "node_modules/fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -3979,7 +3256,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "node_modules/function-bind": { @@ -4023,25 +3300,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -4130,30 +3398,6 @@ "node": ">=4" } }, - "node_modules/has-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-1.0.0.tgz", - "integrity": "sha1-mqqe7b/7G6OZCnsAEPtnjuAIEgc=", - "dev": true, - "dependencies": { - "is-glob": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-glob/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", @@ -4166,69 +3410,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -4295,7 +3476,7 @@ "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "dependencies": { "once": "^1.3.0", @@ -4317,24 +3498,6 @@ "node": ">= 0.10" } }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "node_modules/is-core-module": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", @@ -4347,60 +3510,22 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, "engines": { "node": ">=0.10.0" } }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" + "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" @@ -4457,19 +3582,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, "node_modules/isexe": { @@ -4574,15 +3690,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/junk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", - "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -4605,9 +3712,9 @@ } }, "node_modules/lazystream/node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "dependencies": { "core-util-is": "~1.0.0", @@ -4673,64 +3780,55 @@ "node_modules/lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", "dev": true }, "node_modules/lodash.difference": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", "dev": true }, "node_modules/lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", "dev": true }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", "dev": true }, "node_modules/lodash.union": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", "dev": true }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { - "semver": "^6.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "dependencies": { - "object-visit": "^1.0.0" + "semver": "^6.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/merge-stream": { @@ -4794,9 +3892,9 @@ } }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -4811,47 +3909,6 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -4859,12 +3916,6 @@ "dev": true, "peer": true }, - "node_modules/nested-error-stacks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", - "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", - "dev": true - }, "node_modules/node-releases": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", @@ -4892,91 +3943,6 @@ "node": ">=8" } }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", @@ -4986,18 +3952,6 @@ "node": ">= 0.4" } }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", @@ -5016,22 +3970,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "dependencies": { "wrappy": "1" @@ -5052,72 +3994,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-all": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-all/-/p-all-2.1.0.tgz", - "integrity": "sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA==", - "dev": true, - "dependencies": { - "p-map": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-all/node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, - "dependencies": { - "p-timeout": "^3.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-filter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", - "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", - "dev": true, - "dependencies": { - "p-map": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-filter/node_modules/p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -5143,27 +4019,18 @@ } }, "node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, "dependencies": { "aggregate-error": "^3.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "dependencies": { - "p-finally": "^1.0.0" + "node": ">=10" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { @@ -5175,21 +4042,6 @@ "node": ">=6" } }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5202,7 +4054,7 @@ "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -5250,15 +4102,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -5271,27 +4114,6 @@ "node": ">=8" } }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", - "dev": true, - "bin": { - "printj": "bin/printj.njs" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -5337,9 +4159,9 @@ } }, "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "dependencies": { "inherits": "^2.0.3", @@ -5351,12 +4173,33 @@ } }, "node_modules/readdir-glob": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", - "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "dev": true, "dependencies": { - "minimatch": "^3.0.4" + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" } }, "node_modules/rechoir": { @@ -5389,37 +4232,6 @@ "node": ">=4" } }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -5463,22 +4275,6 @@ "node": ">=8" } }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -5531,437 +4327,92 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - } - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "dev": true }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", "dev": true, "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 8.9.0" } }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "node_modules/serialize-javascript": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", + "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", "dev": true, "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "randombytes": "^2.1.0" } }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "kind-of": "^6.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { - "kind-of": "^3.0.2" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "node_modules/signal-exit": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", + "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/static-extend/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, "engines": { "node": ">=0.10.0" @@ -6005,12 +4456,32 @@ "node": ">=6" } }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -6152,55 +4623,73 @@ "node": ">=0.10.0" } }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "dependencies": { - "kind-of": "^3.0.2" + "is-number": "^7.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8.0" } }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/ts-loader": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.0.tgz", + "integrity": "sha512-LLlB/pkB4q9mW2yLdFMnK3dEHbrBjeZTYguaaIfusyojBgAGf5kF+O6KcWqiGzWqHk0LBsoolrp4VftEURhybg==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" }, "engines": { - "node": ">=0.10.0" + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" } }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "node_modules/ts-loader/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "dev": true, - "dependencies": { - "is-number": "^7.0.0" + "engines": { + "node": ">= 8" + } + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=8.0" + "node": ">=14.17" } }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -6243,30 +4732,6 @@ "node": ">=4" } }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/union-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -6276,54 +4741,6 @@ "node": ">= 10.0.0" } }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -6333,26 +4750,10 @@ "punycode": "^2.1.0" } }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, "node_modules/watchpack": { @@ -6535,17 +4936,44 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "node_modules/zip-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", - "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", "dev": true, "dependencies": { - "archiver-utils": "^2.1.0", - "compress-commons": "^4.1.0", + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dev": true, + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", "readable-stream": "^3.6.0" }, "engines": { @@ -7817,24 +6245,6 @@ "integrity": "sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA==", "dev": true }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - }, - "dependencies": { - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", - "dev": true - } - } - }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7870,6 +6280,16 @@ "@types/glob": "*" } }, + "@types/chrome": { + "version": "0.0.246", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.246.tgz", + "integrity": "sha512-MxGxEomGxsJiL9xe/7ZwVgwdn8XVKWbPvxpVQl3nWOjrS0Ce63JsfzxUc4aU3GvRcUPYsfufHmJ17BFyKxeA4g==", + "dev": true, + "requires": { + "@types/filesystem": "*", + "@types/har-format": "*" + } + }, "@types/eslint": { "version": "8.2.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz", @@ -7899,6 +6319,21 @@ "dev": true, "peer": true }, + "@types/filesystem": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/filesystem/-/filesystem-0.0.33.tgz", + "integrity": "sha512-2KedRPzwu2K528vFkoXnnWdsG0MtUwPjuA7pRy4vKxlxHEe8qUDZibYHXJKZZr2Cl/ELdCWYqyb/MKwsUuzBWw==", + "dev": true, + "requires": { + "@types/filewriter": "*" + } + }, + "@types/filewriter": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/filewriter/-/filewriter-0.0.30.tgz", + "integrity": "sha512-lB98tui0uxc7erbj0serZfJlHKLNJHwBltPnbmO1WRpL5T325GOHRiQfr2E29V2q+S1brDO63Fpdt6vb3bES9Q==", + "dev": true + }, "@types/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", @@ -7909,6 +6344,12 @@ "@types/node": "*" } }, + "@types/har-format": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.13.tgz", + "integrity": "sha512-PwBsCBD3lDODn4xpje3Y1di0aDJp4Ww7aSfMRVw6ysnxD4I7Wmq2mBkSKaDtN403hqH5sp6c9xQUvFYY3+lkBg==", + "dev": true + }, "@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -8197,17 +6638,43 @@ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + }, + "dependencies": { + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, "archiver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.0.tgz", - "integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", "dev": true, "requires": { "archiver-utils": "^2.1.0", - "async": "^3.2.0", + "async": "^3.2.4", "buffer-crc32": "^0.2.1", "readable-stream": "^3.6.0", - "readdir-glob": "^1.0.0", + "readdir-glob": "^1.1.2", "tar-stream": "^2.2.0", "zip-stream": "^4.1.0" } @@ -8231,9 +6698,9 @@ }, "dependencies": { "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -8256,64 +6723,16 @@ } } }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, "array-union": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", "dev": true }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz", - "integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", "dev": true }, "babel-loader": { @@ -8373,32 +6792,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -8467,7 +6860,7 @@ "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", "dev": true }, "buffer-from": { @@ -8477,23 +6870,6 @@ "dev": true, "peer": true }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -8504,18 +6880,22 @@ "get-intrinsic": "^1.0.2" } }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", - "dev": true - }, "caniuse-lite": { "version": "1.0.30001287", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001287.tgz", "integrity": "sha512-4udbs9bc0hfNrcje++AxBuc6PfLNHwh3PO9kbwnfCQWyqtlzg3py0YgFu8jyRTTo85VAz4U+VLxSlID09vNtWA==", "dev": true }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, "chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -8523,86 +6903,6 @@ "dev": true, "peer": true }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -8620,16 +6920,6 @@ "shallow-clone": "^3.0.0" } }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -8664,16 +6954,10 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, "compress-commons": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", - "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", "dev": true, "requires": { "buffer-crc32": "^0.2.13", @@ -8685,7 +6969,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "convert-source-map": { @@ -8697,12 +6981,6 @@ "safe-buffer": "~5.1.1" } }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, "copy-webpack-plugin": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-10.2.0.tgz", @@ -8782,264 +7060,16 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, - "cp-file": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-7.0.0.tgz", - "integrity": "sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "nested-error-stacks": "^2.0.0", - "p-event": "^4.1.0" - } - }, - "cpy": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/cpy/-/cpy-8.1.2.tgz", - "integrity": "sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg==", - "dev": true, - "requires": { - "arrify": "^2.0.1", - "cp-file": "^7.0.0", - "globby": "^9.2.0", - "has-glob": "^1.0.0", - "junk": "^3.1.0", - "nested-error-stacks": "^2.1.0", - "p-all": "^2.1.0", - "p-filter": "^2.1.0", - "p-map": "^3.0.0" - }, - "dependencies": { - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "requires": { - "path-type": "^3.0.0" - } - }, - "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, "crc-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", - "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", - "dev": true, - "requires": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - } + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true }, "crc32-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", - "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", "dev": true, "requires": { "crc-32": "^1.2.0", @@ -9057,21 +7087,6 @@ "which": "^2.0.1" } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -9081,20 +7096,10 @@ "object-keys": "^1.0.12" } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, "del": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", - "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", + "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", "dev": true, "requires": { "globby": "^11.0.1", @@ -9126,15 +7131,6 @@ "merge2": "^1.4.1", "slash": "^3.0.0" } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } } } }, @@ -9173,7 +7169,6 @@ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", "dev": true, - "peer": true, "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -9241,190 +7236,34 @@ "dev": true, "peer": true }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "peer": true - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", - "dev": true - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } + "peer": true }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - } + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" } }, "fast-deep-equal": { @@ -9434,9 +7273,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.9", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.9.tgz", - "integrity": "sha512-MBwILhhD92sziIrMQwpqcuGERF+BH99ei2a3XsGJuqEKcSycAL+w0HWokFenZXona+kjFr82Lf71eTxNRC06XQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -9479,29 +7318,58 @@ } }, "filemanager-webpack-plugin": { - "version": "6.1.7", - "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-6.1.7.tgz", - "integrity": "sha512-0hhPpmod5t0xy1hBSA9gXi0WlOHL3+x56IBt0b/VMhvbZ5/z6jakXvNOTuVmn4wOZwAORvAeH5qQ5Qs6NdPyiw==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/filemanager-webpack-plugin/-/filemanager-webpack-plugin-8.0.0.tgz", + "integrity": "sha512-TYwu62wgq2O2c3K80Sfj8vEys/tP5wdgYoySHgUwWoc2hPbQY3Mq3ahcAW634JvHCTcSV7IAfRxMI3wTXRt2Vw==", "dev": true, "requires": { - "@types/archiver": "^5.1.1", - "archiver": "^5.3.0", - "cpy": "^8.1.2", - "del": "^6.0.0", - "fs-extra": "^10.0.0", - "is-glob": "^4.0.1", - "schema-utils": "^3.1.1" + "@types/archiver": "^5.3.1", + "archiver": "^5.3.1", + "del": "^6.1.1", + "fast-glob": "^3.2.12", + "fs-extra": "^10.1.0", + "is-glob": "^4.0.3", + "normalize-path": "^3.0.0", + "schema-utils": "^4.0.0" }, "dependencies": { + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", "dev": true, "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" } } } @@ -9536,21 +7404,6 @@ "path-exists": "^4.0.0" } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -9558,9 +7411,9 @@ "dev": true }, "fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "requires": { "graceful-fs": "^4.2.0", @@ -9571,7 +7424,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "function-bind": { @@ -9603,22 +7456,16 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -9682,84 +7529,12 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "has-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-glob/-/has-glob-1.0.0.tgz", - "integrity": "sha1-mqqe7b/7G6OZCnsAEPtnjuAIEgc=", - "dev": true, - "requires": { - "is-glob": "^3.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -9797,7 +7572,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -9816,21 +7591,6 @@ "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", "dev": true }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "is-core-module": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", @@ -9840,35 +7600,6 @@ "has": "^1.0.3" } }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -9917,16 +7648,10 @@ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, "isexe": { @@ -10010,12 +7735,6 @@ "universalify": "^2.0.0" } }, - "junk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", - "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", - "dev": true - }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -10032,9 +7751,9 @@ }, "dependencies": { "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -10093,33 +7812,42 @@ "lodash.defaults": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", "dev": true }, "lodash.difference": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", "dev": true }, "lodash.flatten": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", "dev": true }, "lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", "dev": true }, "lodash.union": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", "dev": true }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -10129,21 +7857,6 @@ "semver": "^6.0.0" } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -10190,9 +7903,9 @@ "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -10204,41 +7917,6 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -10246,12 +7924,6 @@ "dev": true, "peer": true }, - "nested-error-stacks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", - "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", - "dev": true - }, "node-releases": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz", @@ -10273,89 +7945,12 @@ "path-key": "^3.0.0" } }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, "object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", @@ -10368,19 +7963,10 @@ "object-keys": "^1.1.1" } }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" @@ -10395,55 +7981,6 @@ "mimic-fn": "^2.1.0" } }, - "p-all": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-all/-/p-all-2.1.0.tgz", - "integrity": "sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA==", - "dev": true, - "requires": { - "p-map": "^2.0.0" - }, - "dependencies": { - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - } - } - }, - "p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, - "requires": { - "p-timeout": "^3.1.0" - } - }, - "p-filter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", - "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", - "dev": true, - "requires": { - "p-map": "^2.0.0" - }, - "dependencies": { - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - } - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -10463,41 +8000,20 @@ } }, "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "dev": true, "requires": { "aggregate-error": "^3.0.0" } }, - "p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -10507,7 +8023,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-key": { @@ -10540,12 +8056,6 @@ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -10555,18 +8065,6 @@ "find-up": "^4.0.0" } }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -10595,9 +8093,9 @@ } }, "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -10606,12 +8104,32 @@ } }, "readdir-glob": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", - "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "dev": true, "requires": { - "minimatch": "^3.0.4" + "minimatch": "^5.1.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "rechoir": { @@ -10638,28 +8156,6 @@ "regenerate": "^1.4.2" } }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -10691,18 +8187,6 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -10733,15 +8217,6 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, "schema-utils": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", @@ -10768,35 +8243,6 @@ "randombytes": "^2.1.0" } }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - } - } - }, "shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -10833,259 +8279,12 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -11109,12 +8308,28 @@ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + } + } + }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "peer": true + "dev": true }, "tar-stream": { "version": "2.2.0", @@ -11205,46 +8420,50 @@ } } }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "ts-loader": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.0.tgz", + "integrity": "sha512-LLlB/pkB4q9mW2yLdFMnK3dEHbrBjeZTYguaaIfusyojBgAGf5kF+O6KcWqiGzWqHk0LBsoolrp4VftEURhybg==", "dev": true, "requires": { - "kind-of": "^3.0.2" + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" }, "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "lru-cache": "^6.0.0" } + }, + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true } } }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } + "typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", @@ -11274,72 +8493,12 @@ "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", "dev": true }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - } - } - }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -11349,22 +8508,10 @@ "punycode": "^2.1.0" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, "watchpack": { @@ -11488,18 +8635,44 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "zip-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", - "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", "dev": true, "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^4.1.0", + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", "readable-stream": "^3.6.0" + }, + "dependencies": { + "archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dev": true, + "requires": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + } + } } } } diff --git a/package.json b/package.json index baea34d5..e3bd676f 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "scripts": { "start": "echo To build for development, please use \"npm run dev\". To build for production, please use \"npm run build\".", "dev": "webpack --mode=production --watch", - "build": "webpack --mode=production", + "build": "webpack --mode=production --stats-error-details", + "build:safari": "webpack --mode=production && xcrun safari-web-extension-converter Extensions/combined/dist/safari --project-location Extensions/combined/dist --bundle-identifier com.returnyoutubedislike.safari-ext --force", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { @@ -28,9 +29,12 @@ "@babel/core": "^7.16.5", "@babel/preset-env": "^7.16.5", "@babel/runtime": "^7.16.5", + "@types/chrome": "^0.0.246", "babel-loader": "^8.2.3", "copy-webpack-plugin": "^10.2.0", - "filemanager-webpack-plugin": "^6.1.7", + "filemanager-webpack-plugin": "^8.0.0", + "ts-loader": "^9.5.0", + "typescript": "^5.2.2", "webpack-cli": "^4.9.1" } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..1eccd616 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,35 @@ +{ + "compilerOptions": { + // project options + "lib": ["ESNext", "dom"], // specifies which default set of type definitions to use ("DOM", "ES6", etc) + "outDir": "lib", // .js (as well as .d.ts, .js.map, etc.) files will be emitted into this directory., + "removeComments": true, // Strips all comments from TypeScript files when converting into JavaScript- you rarely read compiled code so this saves space + "target": "ES6", // Target environment. Most modern browsers support ES6, but you may want to set it to newer or older. (defaults to ES3) + + // Module resolution + "baseUrl": "./", // Lets you set a base directory to resolve non-absolute module names. + "esModuleInterop": true, // fixes some issues TS originally had with the ES6 spec where TypeScript treats CommonJS/AMD/UMD modules similar to ES6 module + "moduleResolution": "node", // Pretty much always node for modern JS. Other option is "classic" + "paths": {}, // A series of entries which re-map imports to lookup locations relative to the baseUrl + + // Source Map + "sourceMap": true, // enables the use of source maps for debuggers and error reporting etc + "sourceRoot": "/", // Specify the location where a debugger should locate TypeScript files instead of relative source locations. + + // Strict Checks + "alwaysStrict": true, // Ensures that your files are parsed in the ECMAScript strict mode, and emit “use strict” for each source file. + "allowUnreachableCode": false, // pick up dead code paths + "noImplicitAny": true, // In some cases where no type annotations are present, TypeScript will fall back to a type of any for a variable when it cannot infer the type. + "strictNullChecks": true, // When strictNullChecks is true, null and undefined have their own distinct types and you’ll get a type error if you try to use them where a concrete value is expected. + + // Linter Checks + "noImplicitReturns": true, + "noUncheckedIndexedAccess": true, // accessing index must always check for undefined + "noUnusedLocals": true, // Report errors on unused local variables. + "noUnusedParameters": true, // Report errors on unused parameters in functions. + + "types": ["@types/chrome", "./globals.d.ts"] + }, + "include": ["./**/*.ts"], + "exclude": ["node_modules/**/*", "Website/**/*"] +} diff --git a/webpack.config.js b/webpack.config.js index ef63fef4..21adf011 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,16 +9,19 @@ const ignorePatterns = [ "**/dist/**", "**/src/**", "**/readme.md", - ...entries.map((entry) => `**/${entry}.js`), + ...entries.map((entry) => `**/${entry}.ts`), ]; module.exports = { entry: Object.fromEntries( entries.map((entry) => [ entry, - path.join(__dirname, "./Extensions/combined/", `${entry}.js`), + path.join(__dirname, "./Extensions/combined/", `${entry}.ts`), ]) ), + resolve: { + extensions: [".ts", ".js"], + }, output: { filename: "[name].js", path: path.resolve(__dirname, "Extensions/combined/dist"), @@ -30,6 +33,15 @@ module.exports = { watchOptions: { ignored: "**/dist/**", }, + module: { + rules: [ + { + test: /\.ts$/, + use: "ts-loader", + exclude: /node_modules|Website/, + }, + ], + }, plugins: [ // exclude locale files in moment new CopyPlugin({ @@ -56,6 +68,17 @@ module.exports = { from: "./Extensions/combined/manifest-firefox.json", to: "./firefox/manifest.json", }, + { + from: "./Extensions/combined", + to: "./safari", + globOptions: { + ignore: ignorePatterns, + }, + }, + { + from: "./Extensions/combined/manifest-safari.json", + to: "./safari/manifest.json", + }, ], }), new FileManagerPlugin({ @@ -70,6 +93,10 @@ module.exports = { source: "./Extensions/combined/dist/**.js", destination: "./Extensions/combined/dist/chrome/", }, + { + source: "./Extensions/combined/dist/**.js", + destination: "./Extensions/combined/dist/safari/", + }, ], }, },