From 22c839884dcfa8813d27a9738efd1017e6a62e21 Mon Sep 17 00:00:00 2001 From: BLCK-B <123077751+BLCK-B@users.noreply.github.com> Date: Sat, 11 May 2024 19:30:48 +0200 Subject: [PATCH 01/22] tests rework beginning --- gradlew | 41 ++-- .../blck/MusicReleaseTracker/ConfigTools.java | 2 +- .../MusicReleaseTracker/Core/MRTConfig.java | 6 +- .../MusicReleaseTracker/GUIController.java | 10 +- .../MusicReleaseTracker/ScrapeProcess.java | 11 +- ...ScraperBox.java => ScraperController.java} | 16 +- .../{ScraperParent.java => Scraper.java} | 57 +++--- ...tportScraper.java => ScraperBeatport.java} | 4 +- ...dScraper.java => ScraperJunodownload.java} | 4 +- ...nzScraper.java => ScraperMusicbrainz.java} | 4 +- ...outubeScraper.java => ScraperYoutube.java} | 4 +- .../GUIControllerTest.java | 1 - .../ScrapeProcessTest.java | 90 +++++++++ .../ScrapeProcessingTest.java | 176 ------------------ .../Scrapers/ScraperTest.java | 131 +++++++++++++ src/test/testresources/testdb.db | Bin 32768 -> 32768 bytes 16 files changed, 311 insertions(+), 246 deletions(-) rename src/main/java/com/blck/MusicReleaseTracker/{ScraperBox.java => ScraperController.java} (91%) rename src/main/java/com/blck/MusicReleaseTracker/Scrapers/{ScraperParent.java => Scraper.java} (83%) rename src/main/java/com/blck/MusicReleaseTracker/Scrapers/{BeatportScraper.java => ScraperBeatport.java} (96%) rename src/main/java/com/blck/MusicReleaseTracker/Scrapers/{JunodownloadScraper.java => ScraperJunodownload.java} (97%) rename src/main/java/com/blck/MusicReleaseTracker/Scrapers/{MusicbrainzScraper.java => ScraperMusicbrainz.java} (95%) rename src/main/java/com/blck/MusicReleaseTracker/Scrapers/{YoutubeScraper.java => ScraperYoutube.java} (95%) create mode 100644 src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java delete mode 100644 src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessingTest.java create mode 100644 src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java diff --git a/gradlew b/gradlew index 1b6c787..1aa94a4 100644 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -80,13 +80,11 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,22 +131,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then done fi -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ @@ -205,6 +214,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/src/main/java/com/blck/MusicReleaseTracker/ConfigTools.java b/src/main/java/com/blck/MusicReleaseTracker/ConfigTools.java index a8b0a98..6e8abd4 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/ConfigTools.java +++ b/src/main/java/com/blck/MusicReleaseTracker/ConfigTools.java @@ -113,7 +113,7 @@ public void updateSettings() { VIP=false } theme=Black - accent=Classic + accent=Lavender lastScrape=- longTimeout=false isoDates=false diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java b/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java index 8d8a8d0..2a0b945 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java @@ -1,7 +1,7 @@ package com.blck.MusicReleaseTracker.Core; import com.blck.MusicReleaseTracker.*; -import com.blck.MusicReleaseTracker.Scrapers.ScraperParent; +import com.blck.MusicReleaseTracker.Scrapers.Scraper; import com.blck.MusicReleaseTracker.Simple.SSEController; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -27,8 +27,8 @@ public ScrapeProcess scrapeProcess(ValueStore valueStore, ErrorLogging errorLogg } @Bean - public ScraperParent scraperParent(ValueStore valueStore, ErrorLogging errorLogging) { - return new ScraperParent(valueStore, errorLogging); + public Scraper scraperParent(ValueStore valueStore, ErrorLogging errorLogging) { + return new Scraper(valueStore, errorLogging); } @Bean diff --git a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java index 3ee43cd..720eff6 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java @@ -208,12 +208,12 @@ public void clickAddURL(String url) { tempID = null; String id = null; try { - ScraperParent scraper = null; + Scraper scraper = null; switch (selectedSource) { - case musicbrainz -> scraper = new MusicbrainzScraper(store, log, lastClickedArtist, url); - case beatport -> scraper = new BeatportScraper(store, log, lastClickedArtist, url); - case junodownload -> scraper = new JunodownloadScraper(store, log, lastClickedArtist, url); - case youtube -> scraper = new YoutubeScraper(store, log, lastClickedArtist, url); + case musicbrainz -> scraper = new ScraperMusicbrainz(store, log, lastClickedArtist, url); + case beatport -> scraper = new ScraperBeatport(store, log, lastClickedArtist, url); + case junodownload -> scraper = new ScraperJunodownload(store, log, lastClickedArtist, url); + case youtube -> scraper = new ScraperYoutube(store, log, lastClickedArtist, url); } id = scraper.getID(); scraper.scrape(); diff --git a/src/main/java/com/blck/MusicReleaseTracker/ScrapeProcess.java b/src/main/java/com/blck/MusicReleaseTracker/ScrapeProcess.java index e9cd0a5..3dcf05d 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/ScrapeProcess.java +++ b/src/main/java/com/blck/MusicReleaseTracker/ScrapeProcess.java @@ -29,7 +29,7 @@ along with this program. If not, see .*/ /** - * class handling scraping and data processing logic + * class handling scraping and processing logic */ @Component public class ScrapeProcess { @@ -54,10 +54,9 @@ public ScrapeProcess(ValueStore valueStore, ErrorLogging errorLogging, ConfigToo public void scrapeData() { config.readConfig(ConfigTools.configOptions.longTimeout); scrapeCancel = false; - // clear tables - for new data DB.clearDB(); - ScraperBox box = new ScraperBox(store, log); - final int initSize = box.getInitSize(); + ScraperController scrapers = new ScraperController(store, log); + final int initSize = scrapers.getInitSize(); // triggering scrapers int remaining = 0; double progress = 0.0; @@ -68,14 +67,12 @@ public void scrapeData() { System.gc(); return; } - remaining = box.scrapeNext(); - // 40 remaining / 80 total = 50% + remaining = scrapers.scrapeNext(); progress = ((double) initSize - (double) remaining) / (double) initSize; } System.gc(); } - public void fillCombviewTable() { ArrayList songObjectList = prepareSongs(); List finalSortedList = processSongs(songObjectList); diff --git a/src/main/java/com/blck/MusicReleaseTracker/ScraperBox.java b/src/main/java/com/blck/MusicReleaseTracker/ScraperController.java similarity index 91% rename from src/main/java/com/blck/MusicReleaseTracker/ScraperBox.java rename to src/main/java/com/blck/MusicReleaseTracker/ScraperController.java index b867933..58d6c02 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/ScraperBox.java +++ b/src/main/java/com/blck/MusicReleaseTracker/ScraperController.java @@ -7,15 +7,15 @@ import java.sql.*; import java.util.*; -public class ScraperBox { +public class ScraperController { private final ValueStore store; private final ErrorLogging log; private final int initSize; - private final LinkedList scrapers = new LinkedList<>(); + private final LinkedList scrapers = new LinkedList<>(); private final HashMap sourceTimes = new HashMap<>(); // middleware abstraction for scraping with exception handling - public ScraperBox(ValueStore store, ErrorLogging log) { + public ScraperController(ValueStore store, ErrorLogging log) { this.store = store; this.log = log; // creating a list of scraper objects: one scraper holds one URL @@ -36,10 +36,10 @@ public ScraperBox(ValueStore store, ErrorLogging log) { if (url == null) continue; switch (webSource) { - case musicbrainz -> scrapers.add(new MusicbrainzScraper(store, log, artist, url)); - case beatport -> scrapers.add(new BeatportScraper(store, log, artist, url)); - case junodownload -> scrapers.add(new JunodownloadScraper(store, log, artist, url)); - case youtube -> scrapers.add(new YoutubeScraper(store, log, artist, url)); + case musicbrainz -> scrapers.add(new ScraperMusicbrainz(store, log, artist, url)); + case beatport -> scrapers.add(new ScraperBeatport(store, log, artist, url)); + case junodownload -> scrapers.add(new ScraperJunodownload(store, log, artist, url)); + case youtube -> scrapers.add(new ScraperYoutube(store, log, artist, url)); } } } @@ -62,7 +62,7 @@ public int scrapeNext() { return -1; double startTime = System.currentTimeMillis(); - ScraperParent scraper = scrapers.get(0); + Scraper scraper = scrapers.get(0); for (int i = 0; i <= 2; i++) { try { scraper.scrape(); diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperParent.java b/src/main/java/com/blck/MusicReleaseTracker/Scrapers/Scraper.java similarity index 83% rename from src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperParent.java rename to src/main/java/com/blck/MusicReleaseTracker/Scrapers/Scraper.java index d0bef09..92e634b 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperParent.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scrapers/Scraper.java @@ -20,24 +20,19 @@ import java.util.Set; @Component -public class ScraperParent { +public class Scraper { protected final ValueStore store; protected final ErrorLogging log; - protected ArrayList songList; - SourcesEnum source; + public ArrayList songList = new ArrayList<>(); + public SourcesEnum source; @Autowired - public ScraperParent(ValueStore valueStore, ErrorLogging errorLogging) { + public Scraper(ValueStore valueStore, ErrorLogging errorLogging) { this.store = valueStore; this.log = errorLogging; } - public void setTestData(ArrayList songList, SourcesEnum source) { - this.songList = songList; - this.source = source; - } - public void scrape() throws ScraperTimeoutException { System.out.println("The method scrape() is to be overriden."); } @@ -47,12 +42,23 @@ public String getID() { } public void processInfo() { - // unify apostrophes/grave accents/backticks/quotes... - for (Song object : songList) { - String songName = object.getName().replace("’", "'").replace("`", "'").replace("´", "'"); - object.setName(songName); + unifyApostrophes(); + enforceDateFormat(); + sortByDateDescending(); + removeNameDuplicates(); + + // reverse to newest-oldest + Collections.reverse(songList); + } + + public void unifyApostrophes() { + for (Song song : songList) { + String songName = song.getName().replace("’", "'").replace("`", "'").replace("´", "'"); + song.setName(songName); } - // discard objects with an incorrect date format + } + + public void enforceDateFormat() { songList.removeIf(obj -> { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); try { @@ -62,14 +68,10 @@ public void processInfo() { return true; } }); - // sort by date from oldest - songList.sort((obj1, obj2) -> { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - LocalDate date1 = LocalDate.parse(obj1.getDate(), formatter); - LocalDate date2 = LocalDate.parse(obj2.getDate(), formatter); - return date1.compareTo(date2); - }); - // remove name duplicates + } + + // TODO: discard duplicates from oldest, in any way + public void removeNameDuplicates() { Set recordedNames = new HashSet<>(); songList.removeIf(obj -> { String name = obj.getName().toLowerCase(); @@ -80,8 +82,15 @@ public void processInfo() { return false; } }); - // reverse to newest-oldest - Collections.reverse(songList); + } + + public void sortByDateDescending() { + songList.sort((obj1, obj2) -> { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate date1 = LocalDate.parse(obj1.getDate(), formatter); + LocalDate date2 = LocalDate.parse(obj2.getDate(), formatter); + return date2.compareTo(date1); + }); } public void insertSet() { diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/BeatportScraper.java b/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperBeatport.java similarity index 96% rename from src/main/java/com/blck/MusicReleaseTracker/Scrapers/BeatportScraper.java rename to src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperBeatport.java index a28898f..d49caf7 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/BeatportScraper.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperBeatport.java @@ -14,12 +14,12 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -public final class BeatportScraper extends ScraperParent implements ScraperInterface { +public final class ScraperBeatport extends Scraper implements ScraperInterface { private final String songArtist; private String id; private final boolean isIDnull; - public BeatportScraper(ValueStore store, ErrorLogging log, String songArtist, String id) { + public ScraperBeatport(ValueStore store, ErrorLogging log, String songArtist, String id) { super(store, log); this.songArtist = songArtist; this.id = id; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/JunodownloadScraper.java b/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperJunodownload.java similarity index 97% rename from src/main/java/com/blck/MusicReleaseTracker/Scrapers/JunodownloadScraper.java rename to src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperJunodownload.java index e81f0d0..c8110f4 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/JunodownloadScraper.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperJunodownload.java @@ -15,7 +15,7 @@ import static java.lang.String.valueOf; -public final class JunodownloadScraper extends ScraperParent implements ScraperInterface { +public final class ScraperJunodownload extends Scraper implements ScraperInterface { private enum MonthNumbers { JAN("01"), FEB("02"), MAR("03"), APR("04"), @@ -29,7 +29,7 @@ private enum MonthNumbers { private final String songArtist; private String id; private final boolean isIDnull; - public JunodownloadScraper(ValueStore store, ErrorLogging log, String songArtist, String id) { + public ScraperJunodownload(ValueStore store, ErrorLogging log, String songArtist, String id) { super(store, log); this.songArtist = songArtist; this.id = id; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/MusicbrainzScraper.java b/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperMusicbrainz.java similarity index 95% rename from src/main/java/com/blck/MusicReleaseTracker/Scrapers/MusicbrainzScraper.java rename to src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperMusicbrainz.java index 9e5c91d..f478526 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/MusicbrainzScraper.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperMusicbrainz.java @@ -11,13 +11,13 @@ import java.net.SocketTimeoutException; import java.util.ArrayList; -public final class MusicbrainzScraper extends ScraperParent implements ScraperInterface { +public final class ScraperMusicbrainz extends Scraper implements ScraperInterface { private final String songArtist; private String id; private final boolean isIDnull; - public MusicbrainzScraper(ValueStore store, ErrorLogging log, String songArtist, String id) { + public ScraperMusicbrainz(ValueStore store, ErrorLogging log, String songArtist, String id) { super(store, log); this.songArtist = songArtist; this.id = id; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/YoutubeScraper.java b/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperYoutube.java similarity index 95% rename from src/main/java/com/blck/MusicReleaseTracker/Scrapers/YoutubeScraper.java rename to src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperYoutube.java index a63fa16..80248f2 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/YoutubeScraper.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperYoutube.java @@ -13,12 +13,12 @@ import java.util.ArrayList; import java.util.Arrays; -public final class YoutubeScraper extends ScraperParent implements ScraperInterface { +public final class ScraperYoutube extends Scraper implements ScraperInterface { private final String songArtist; private String id; private final boolean isIDnull; - public YoutubeScraper(ValueStore store, ErrorLogging log, String songArtist, String id) { + public ScraperYoutube(ValueStore store, ErrorLogging log, String songArtist, String id) { super(store, log); this.songArtist = songArtist; this.id = id; diff --git a/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java b/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java index b5f65ed..3bb23e7 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java @@ -22,7 +22,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see .*/ -@SpringBootTest @TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class GUIControllerTest { diff --git a/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java b/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java new file mode 100644 index 0000000..4f03944 --- /dev/null +++ b/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java @@ -0,0 +1,90 @@ +package com.blck.MusicReleaseTracker; + +import com.blck.MusicReleaseTracker.Core.ValueStore; +import com.blck.MusicReleaseTracker.Simple.Song; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.springframework.test.context.event.annotation.BeforeTestClass; + +import java.nio.file.Paths; +import java.sql.*; +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.*; + +/* MusicReleaseTracker + Copyright (C) 2023 BLCK + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see .*/ + +public class ScrapeProcessTest { + + private ValueStore store = new ValueStore(); + private DBtools DB = new DBtools(store, null); + private ScrapeProcess scrapeProcess; + private ArrayList expectedList; + + @BeforeTestClass + void beforeClass() { + // data setup + String DBpath = "jdbc:sqlite:" + Paths.get("src", "test", "testresources", "testdb.db"); + store.setDBpath(DBpath); + + ArrayList filterWords = new ArrayList<>(); + filterWords.add("XXXXX"); + store.setFilterWords(filterWords); + scrapeProcess = new ScrapeProcess(store, null, null, DB, null); + } + + @BeforeEach + void setUp() { + // TODO: granular setup of instance store +// scrapeProcess = new ScrapeProcess(store, null, null, DB, null); + } + + @Disabled("do not forget") + @Test + void fillCombviewTable() { + scrapeProcess.fillCombviewTable(); + + ArrayList songList = new ArrayList<>(); + ArrayList expectedSongList = new ArrayList<>(); + expectedSongList.add(new Song("Collab", "B, L, K", "2023-11-10")); + expectedSongList.add(new Song("duplicates", "K", "2023-07-27")); + expectedSongList.add(new Song("DiffDates", "B", "2000-30-30")); + + try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + String sql = "SELECT * FROM combview ORDER BY date DESC"; + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sql); + while (rs.next()) { + String song = rs.getString("song"); + String artist = rs.getString("artist"); + String date = rs.getString("date"); + songList.add(new Song(song, artist, date)); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + + for (int i = 0; i < expectedSongList.size(); i++) { + Song obj1 = expectedSongList.get(i); + Song obj2 = songList.get(i); + assertAll("Combview table rows", + () -> assertEquals(obj1.getName(), obj2.getName()), + () -> assertEquals(obj1.getArtist(), obj2.getArtist()), + () -> assertEquals(obj1.getDate(), obj2.getDate()) + ); + } + } + +} diff --git a/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessingTest.java b/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessingTest.java deleted file mode 100644 index f32c4b3..0000000 --- a/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessingTest.java +++ /dev/null @@ -1,176 +0,0 @@ -package com.blck.MusicReleaseTracker; - -import com.blck.MusicReleaseTracker.Core.SourcesEnum; -import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.Scrapers.*; -import com.blck.MusicReleaseTracker.Simple.Song; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -import java.nio.file.Paths; -import java.sql.*; -import java.util.ArrayList; - -import static org.junit.jupiter.api.Assertions.assertAll; -import static org.junit.jupiter.api.Assertions.assertEquals; - -/* MusicReleaseTracker - Copyright (C) 2023 BLCK - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see .*/ - -@SpringBootTest -public class ScrapeProcessingTest { - - private final ValueStore store = new ValueStore(); - private final DBtools DB = new DBtools(store, null); - private final ScrapeProcess testedSP; - - public ScrapeProcessingTest() { - // data setup - String DBpath = "jdbc:sqlite:" + Paths.get("src", "test", "testresources", "testdb.db"); - store.setDBpath(DBpath); - - ArrayList filterWords = new ArrayList<>(); - filterWords.add("XXXXX"); - store.setFilterWords(filterWords); - - testedSP = new ScrapeProcess(store, null, null, DB, null); - } - - @Test - void processInfo() { - ScraperParent scraperInstace = new ScraperParent(null, null); - ArrayList songList = new ArrayList<>(); - songList.add(new Song("Song1", "artistName", "2023-01-01")); - songList.add(new Song("Son’g3", "artistName", "2023-03-01")); - songList.add(new Song("Song2", "artistName", "2023-02-01")); - scraperInstace.setTestData(songList, SourcesEnum.beatport); - scraperInstace.processInfo(); - // expected values: sort by date - ArrayList expectedSongList = new ArrayList<>(); - expectedSongList.add(new Song("Son'g3", "artistName", "2023-03-01")); - expectedSongList.add(new Song("Song2", "artistName", "2023-02-01")); - expectedSongList.add(new Song("Song1", "artistName", "2023-01-01")); - - for (int i = 0; i < songList.size(); i++) - assertEquals(songList.get(i).toString(), expectedSongList.get(i).toString()); - - // incorrect dates: discard - songList.add(new Song("Song4", "artistName", "2023")); - songList.add(new Song("Song5", "artistName", "-")); - songList.add(new Song("Song6", "artistName", "08-05-2023")); - scraperInstace.setTestData(songList, SourcesEnum.beatport); - scraperInstace.processInfo(); - - for (int i = 0; i < songList.size(); i++) - assertEquals(songList.get(i).toString(), expectedSongList.get(i).toString()); - - expectedSongList.remove(expectedSongList.size() - 1); - expectedSongList.add(new Song("Song1", "artistName", "2005-05-05")); - - // duplicates: prefer older - songList.add(new Song("Song1", "artistName", "2023-01-01")); - songList.add(new Song("Song1", "artistName", "2019-19-19")); - songList.add(new Song("Song1", "artistName", "2005-05-05")); - scraperInstace.setTestData(songList, SourcesEnum.beatport); - scraperInstace.processInfo(); - - for (int i = 0; i < songList.size(); i++) - assertEquals(songList.get(i).toString(), expectedSongList.get(i).toString()); - } - - @Test - void fillCombviewTable() { - testedSP.fillCombviewTable(); - - ArrayList songList = new ArrayList<>(); - ArrayList expectedSongList = new ArrayList<>(); - expectedSongList.add(new Song("Collab", "B, L, K", "2023-11-10")); - expectedSongList.add(new Song("duplicates", "K", "2023-07-27")); - expectedSongList.add(new Song("DiffDates", "B", "2000-30-30")); - - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "SELECT * FROM combview ORDER BY date DESC"; - Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(sql); - while (rs.next()) { - String song = rs.getString("song"); - String artist = rs.getString("artist"); - String date = rs.getString("date"); - songList.add(new Song(song, artist, date)); - } - } catch (SQLException e) { - throw new RuntimeException(e); - } - - for (int i = 0; i < expectedSongList.size(); i++) { - Song obj1 = expectedSongList.get(i); - Song obj2 = songList.get(i); - assertAll("Combview table rows", - () -> assertEquals(obj1.getName(), obj2.getName()), - () -> assertEquals(obj1.getArtist(), obj2.getArtist()), - () -> assertEquals(obj1.getDate(), obj2.getDate()) - ); - } - - } - - @Test - void reduceToID() { - ArrayList input = new ArrayList<>(); - // beatport - input.add("https://www.beatport.com/artist/artistname/1234/tracks"); - input.add("https://www.beatport.com/artist/artistname/1234"); - input.add("artistname/1234"); - // musicbrainz - input.add("https://musicbrainz.org/artist/123-id-123/releases"); - input.add("https://musicbrainz.org/artist/123-id-123"); - input.add("123-id-123"); - // junodownload - input.add("https://www.junodownload.com/artists/artistname/releases/"); - input.add("https://www.junodownload.com/artists/artistname"); - input.add("artistname"); - // youtube - input.add("https://www.youtube.com/channel/123-id-123"); - input.add("123-id-123"); - - for (int i = 0; i < input.size(); i++) { - // beatport - if (i < 3) { - BeatportScraper scraper = new BeatportScraper(null, null, null, input.get(i)); - String output = scraper.getID(); - assertEquals("artistname/1234", output); - } - // musicbrainz - else if (i < 6) { - MusicbrainzScraper scraper = new MusicbrainzScraper(null, null, null, input.get(i)); - String output = scraper.getID(); - assertEquals("123-id-123", output); - } - // junodownload - else if (i < 9) { - JunodownloadScraper scraper = new JunodownloadScraper(null, null, null, input.get(i)); - String output = scraper.getID(); - assertEquals("artistname", output); - } - // youtube - else { - YoutubeScraper scraper = new YoutubeScraper(null, null, null, input.get(i)); - String output = scraper.getID(); - assertEquals("123-id-123", output); - } - } - - } - - -} diff --git a/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java b/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java new file mode 100644 index 0000000..9459f8e --- /dev/null +++ b/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java @@ -0,0 +1,131 @@ +package com.blck.MusicReleaseTracker.Scrapers; + +import com.blck.MusicReleaseTracker.Simple.Song; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/* MusicReleaseTracker + Copyright (C) 2023 BLCK + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see .*/ + +public class ScraperTest { + + private Scraper scraper; + + @BeforeEach + void setUp() { + scraper = new Scraper(null, null); + } + + @Test + void unifyApostrophesBackticksAndAccents() { + scraper.songList.add(new Song("S’o´n'g", "artistName", "2023-01-01")); + + scraper.unifyApostrophes(); + + assertEquals(scraper.songList.get(0).toString(), new Song("S'o'n'g", "artistName", "2023-01-01").toString()); + } + + @Test + void incorrectDatesAreDiscarded() { + scraper.songList.add(new Song("Song1", "artistName", "2023")); + scraper.songList.add(new Song("Song2", "artistName", "-")); + scraper.songList.add(new Song("Song3", "artistName", "08-05-2023")); + scraper.songList.add(new Song("Song3", "artistName", "")); + + scraper.enforceDateFormat(); + + assertTrue(scraper.songList.isEmpty()); + } + + @Test + void songListSortedByDateDescending() { + ArrayList expectedList = new ArrayList<>(); + scraper.songList.add(new Song("Song3", "artistName", "2015-01-07")); + scraper.songList.add(new Song("Song2", "artistName", "2021-06-08")); + scraper.songList.add(new Song("Song4", "artistName", "2000-03-01")); + scraper.songList.add(new Song("Song1", "artistName", "2024-12-05")); + expectedList.add(new Song("Song1", "artistName", "2024-12-05")); + expectedList.add(new Song("Song2", "artistName", "2021-06-08")); + expectedList.add(new Song("Song3", "artistName", "2015-01-07")); + expectedList.add(new Song("Song4", "artistName", "2000-03-01")); + + scraper.sortByDateDescending(); + + for (int i = 0; i < scraper.songList.size(); i++) + assertEquals(scraper.songList.get(i).toString(), expectedList.get(i).toString()); + } + + @Disabled("do not forget") + @Test + void removeNameDuplicatesLeaveOldest() { + scraper.songList.add(new Song("Song1", "artistName", "2023-01-01")); + scraper.songList.add(new Song("SONG1", "artistName", "2005-05-05")); + scraper.songList.add(new Song("song1", "artistName", "2019-19-19")); + + scraper.removeNameDuplicates(); + // TODO: mind hash + assertEquals(scraper.songList.get(0), new Song("SONG1", "artistName", "2005-05-05")); + } + + @Test + void reduceToIDBeatport() { + scraper = new ScraperBeatport(null, null, null, "https://www.beatport.com/artist/artistname/1234/tracks"); + assertEquals("artistname/1234", scraper.getID()); + + scraper = new ScraperBeatport(null, null, null, "https://www.beatport.com/artist/artistname/1234"); + assertEquals("artistname/1234", scraper.getID()); + + scraper = new ScraperBeatport(null, null, null, "artistname/1234"); + assertEquals("artistname/1234", scraper.getID()); + } + + @Test + void reduceToIDMusicbrainz() { + scraper = new ScraperMusicbrainz(null, null, null, "https://musicbrainz.org/artist/123-id-123/releases"); + assertEquals("123-id-123", scraper.getID()); + + scraper = new ScraperMusicbrainz(null, null, null, "https://musicbrainz.org/artist/123-id-123"); + assertEquals("123-id-123", scraper.getID()); + + scraper = new ScraperMusicbrainz(null, null, null, "123-id-123"); + assertEquals("123-id-123", scraper.getID()); + } + + @Test + void reduceToIDJunodownload() { + scraper = new ScraperJunodownload(null, null, null, "https://www.junodownload.com/artists/artistname/releases/"); + assertEquals("artistname", scraper.getID()); + + scraper = new ScraperJunodownload(null, null, null, "https://www.junodownload.com/artists/artistname"); + assertEquals("artistname", scraper.getID()); + + scraper = new ScraperJunodownload(null, null, null, "artistname"); + assertEquals("artistname", scraper.getID()); + } + + @Test + void reduceToIDYoutube() { + scraper = new ScraperYoutube(null, null, null, "https://www.youtube.com/channel/123-id-123"); + assertEquals("123-id-123", scraper.getID()); + + scraper = new ScraperYoutube(null, null, null, "123-id-123"); + assertEquals("123-id-123", scraper.getID()); + } + +} diff --git a/src/test/testresources/testdb.db b/src/test/testresources/testdb.db index 59c4de5b8dde26e6ff1f8428ce4bde4344210c6b..c48369ea4c7ad633001cd555f9123f29f189d3c8 100644 GIT binary patch delta 35 icmZo@U}|V!njkG$&A`CG0mLw1I8n!#v3g^|f_eaUwg(Xa delta 35 icmZo@U}|V!njkG`#lXP80mLw%GEv8v(Q0GDf_eaMRR)3p From 7fb7e482715b5af55b8d5157c034cee99aa23332 Mon Sep 17 00:00:00 2001 From: BLCK <123077751+BLCK-B@users.noreply.github.com> Date: Tue, 14 May 2024 16:25:35 +0200 Subject: [PATCH 02/22] StartSetup class, removed troubled tests --- .../MusicReleaseTracker/Core/MRTConfig.java | 5 ++ .../MusicReleaseTracker/Core/StartSetup.java | 59 ++++++++++++++ .../com/blck/MusicReleaseTracker/DBtools.java | 37 --------- .../com/blck/MusicReleaseTracker/Main.java | 23 ++---- .../GUIControllerTest.java | 73 ++++-------------- src/test/testresources/testdb.db | Bin 32768 -> 32768 bytes 6 files changed, 86 insertions(+), 111 deletions(-) create mode 100644 src/main/java/com/blck/MusicReleaseTracker/Core/StartSetup.java diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java b/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java index 2a0b945..8c9dacb 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java @@ -46,5 +46,10 @@ public DBtools dBtools(ValueStore valueStore, ErrorLogging errorLogging) { return new DBtools(valueStore, errorLogging); } + @Bean + public StartSetup startSetup(ValueStore valueStore, ErrorLogging errorLogging) { + return new StartSetup(valueStore, errorLogging); + } + } diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/StartSetup.java b/src/main/java/com/blck/MusicReleaseTracker/Core/StartSetup.java new file mode 100644 index 0000000..2b2f93f --- /dev/null +++ b/src/main/java/com/blck/MusicReleaseTracker/Core/StartSetup.java @@ -0,0 +1,59 @@ +package com.blck.MusicReleaseTracker.Core; + + +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.File; + +public class StartSetup { + private final ValueStore store; + private final ErrorLogging log; + final String slash = File.separator; + + @Autowired + public StartSetup(ValueStore valueStore, ErrorLogging errorLogging) { + this.store = valueStore; + this.log = errorLogging; + } + + public void initializeSystem() { + createPaths(); + createDirs(); + } + + private void createPaths() { + String appData = null; + String os = System.getProperty("os.name").toLowerCase(); + if (os.contains("win")) + appData = System.getenv("APPDATA"); + else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) + appData = System.getProperty("user.home"); + else + throw new UnsupportedOperationException("unsupported OS"); + + String appDataPath = appData + slash + "MusicReleaseTracker" + slash; + String DBpath = "jdbc:sqlite:" + appDataPath + "musicdata.db"; + String configPath = appDataPath + "MRTsettings.hocon"; + String errorLogsPath = appDataPath + "errorlogs.txt"; + + store.setAppDataPath(appDataPath); + store.setConfigPath(configPath); + store.setDBpath(DBpath); + store.setErrorLogsPath(errorLogsPath); + } + + private void createDirs() { + String appDataPath = store.getAppDataPath(); + File folder = new File(appDataPath); + if (!folder.exists()) + folder.mkdirs(); + // junk folder because sqlite did not delete temp files in "temp" + File tempfolder = new File(appDataPath + "temp"); + if (!tempfolder.exists()) + tempfolder.mkdirs(); + for (File file : tempfolder.listFiles()) + file.delete(); + System.setProperty("org.sqlite.tmpdir", appDataPath + "temp"); + } + +} diff --git a/src/main/java/com/blck/MusicReleaseTracker/DBtools.java b/src/main/java/com/blck/MusicReleaseTracker/DBtools.java index da6f043..49bd4d7 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/DBtools.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DBtools.java @@ -31,7 +31,6 @@ public class DBtools { private final ValueStore store; private final ErrorLogging log; - final String slash = File.separator; @Autowired public DBtools(ValueStore valueStore, ErrorLogging errorLogging) { @@ -39,42 +38,6 @@ public DBtools(ValueStore valueStore, ErrorLogging errorLogging) { this.log = errorLogging; } - public void path() { - String appData = null; - String os = System.getProperty("os.name").toLowerCase(); - if (os.contains("win")) // Windows - appData = System.getenv("APPDATA"); - else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) // Linux - appData = System.getProperty("user.home"); - else - throw new UnsupportedOperationException("unsupported OS"); - - // paths - String appDataPath = appData + slash + "MusicReleaseTracker" + slash; - String DBpath = "jdbc:sqlite:" + appDataPath + "musicdata.db"; - String configPath = appDataPath + "MRTsettings.hocon"; - String errorLogsPath = appDataPath + "errorlogs.txt"; - // save to settingsStore - store.setAppDataPath(appDataPath); - store.setConfigPath(configPath); - store.setDBpath(DBpath); - store.setErrorLogsPath(errorLogsPath); - - // appdata folder - File folder = new File(appDataPath); - if (!folder.exists()) - folder.mkdirs(); - // junk folder because sqlite did not delete temp files in "temp" - File tempfolder = new File(appDataPath + "temp"); - if (!tempfolder.exists()) - tempfolder.mkdirs(); - File[] tempfiles = tempfolder.listFiles(); - for (File file : tempfiles) { - file.delete(); - } - System.setProperty("org.sqlite.tmpdir", appDataPath + "temp"); - } - public void createTables() { // on start: create DB if not exist, check DB structure, if different -> create new from template and refill with all data possible final String templateFilePath = store.getAppDataPath() + "DBTemplate.db"; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Main.java b/src/main/java/com/blck/MusicReleaseTracker/Main.java index a7fed85..e1ee214 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Main.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Main.java @@ -1,6 +1,7 @@ package com.blck.MusicReleaseTracker; import com.blck.MusicReleaseTracker.Core.ErrorLogging; +import com.blck.MusicReleaseTracker.Core.StartSetup; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; @@ -31,12 +32,14 @@ public static void main(String[] args) { private final ConfigTools config; private final ErrorLogging log; private final DBtools DB; + private final StartSetup startSetup; @Autowired - public Main(ConfigTools configTools, ErrorLogging errorLogging, DBtools dBtools) { + public Main(ConfigTools configTools, ErrorLogging errorLogging, DBtools dBtools, StartSetup startSetup) { this.config = configTools; this.log = errorLogging; this.DB = dBtools; + this.startSetup = startSetup; } @Component @@ -53,21 +56,9 @@ public void run(String... args) { | | | | _ < | | |_| |_|_| \\_\\|_| """); - try { - DB.path(); - } catch (Exception e) { - throw new RuntimeException("error in DB path method", e); - } - try { - DB.createTables(); - } catch (Exception e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error in DBtools createTables method"); - } - try { - config.updateSettings(); - } catch (Exception e) { - log.error(e, ErrorLogging.Severity.WARNING, "error handling config file"); - } + startSetup.initializeSystem(); + DB.createTables(); + config.updateSettings(); // open port in web browser try { String os = System.getProperty("os.name").toLowerCase(); diff --git a/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java b/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java index 3bb23e7..30018a6 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java @@ -3,7 +3,7 @@ import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; import org.junit.jupiter.api.*; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.event.annotation.BeforeTestClass; import java.nio.file.Paths; @@ -22,69 +22,26 @@ You should have received a copy of the GNU General Public License along with this program. If not, see .*/ -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class GUIControllerTest { - private final ValueStore store = new ValueStore(); - private final DBtools DB = new DBtools(store, null); - private final GUIController testedClass; - - public GUIControllerTest() { - // data setup - String DBpath = "jdbc:sqlite:" + Paths.get("src", "test", "testresources", "testdb.db"); + private String DBpath; + private ValueStore store; + private DBtools DB; + private GUIController guiController; + + @BeforeEach + void setUp() { + DBpath = "jdbc:sqlite:" + Paths.get("src", "test", "testresources", "testdb.db"); + store = new ValueStore(); store.setDBpath(DBpath); - - testedClass = new GUIController(store, null, null, null, DB); - testedClass.setTestData("Joe", SourcesEnum.beatport); - } - - @Test - @Order(1) - void AddLoadArtist() { - // artistAddConfirm - testedClass.artistAddConfirm("Joe"); - // verify with loadList - String oneArtist = testedClass.loadList().get(0); - assertEquals(oneArtist, "Joe"); - } - - @Test - @Order(2) - void AddVerifyUrl() { - // saveUrl - testedClass.saveUrl(); - // verify with checkExistUrl - try { - boolean exists = testedClass.checkExistURL(); - assertTrue(exists); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Test - @Order(3) - void DeleteVerifyUrl() { - // deleteUrl - testedClass.deleteUrl(); - // verify with checkExistUrl - try { - boolean exists = testedClass.checkExistURL(); - assertFalse(exists); - } catch (Exception e) { - throw new RuntimeException(e); - } + DB = new DBtools(store, null); + guiController = new GUIController(store, null, null, null, DB); + guiController.setTestData("Joe", SourcesEnum.beatport); } - @Test - @Order(4) - void DeleteArtist() { - // artistClickDelete - testedClass.artistClickDelete(); - // verify with loadList - assertTrue(testedClass.loadList().isEmpty()); + @AfterEach + void cleanUp() { - testedClass.vacuum(); } } \ No newline at end of file diff --git a/src/test/testresources/testdb.db b/src/test/testresources/testdb.db index c48369ea4c7ad633001cd555f9123f29f189d3c8..1ea16fda4d864415976223d79616472959da3ee2 100644 GIT binary patch delta 35 icmZo@U}|V!njkIMz`(%30mLw1G*QQxv0-Dvf_eaVTL&Bf delta 35 icmZo@U}|V!njkG$&A`CG0mLw1I8n!#v3g^|f_eaUwg(Xa From f18ed5fb9f94f67692cc507329dd7b4a35d57122 Mon Sep 17 00:00:00 2001 From: BLCK <123077751+BLCK-B@users.noreply.github.com> Date: Tue, 14 May 2024 16:58:38 +0200 Subject: [PATCH 03/22] packages reorganised, helper DB test class draft --- .../MusicReleaseTracker/Core/MRTConfig.java | 5 +++-- .../com/blck/MusicReleaseTracker/DBtools.java | 4 +++- .../{Simple => DataModels}/Song.java | 2 +- .../{Simple => DataModels}/TableModel.java | 2 +- .../{Core => FrontendAPI}/ApiController.java | 4 ++-- .../SSEController.java | 2 +- .../MusicReleaseTracker/GUIController.java | 5 +++-- .../com/blck/MusicReleaseTracker/Main.java | 3 +-- .../{ => Scraping}/ScrapeProcess.java | 8 +++++--- .../{ => Scraping}/ScraperController.java | 5 +++-- .../ScraperTimeoutException.java | 2 +- .../{ => Scraping}/Scrapers/Scraper.java | 5 +++-- .../Scrapers/ScraperBeatport.java | 5 +++-- .../Scrapers/ScraperInterface.java | 4 +++- .../Scrapers/ScraperJunodownload.java | 5 +++-- .../Scrapers/ScraperMusicbrainz.java | 5 +++-- .../Scrapers/ScraperYoutube.java | 5 +++-- .../{Core => }/StartSetup.java | 4 +++- src/main/java/module-info.java | 8 ++++++-- .../DBToolsTest_structure.java | 20 +++++++++++++++++++ .../blck/MusicReleaseTracker/HelperDB.java | 13 ++++++++++++ .../ScrapeProcessTest.java | 3 ++- .../Scrapers/ScraperTest.java | 3 ++- 23 files changed, 88 insertions(+), 34 deletions(-) rename src/main/java/com/blck/MusicReleaseTracker/{Simple => DataModels}/Song.java (97%) rename src/main/java/com/blck/MusicReleaseTracker/{Simple => DataModels}/TableModel.java (68%) rename src/main/java/com/blck/MusicReleaseTracker/{Core => FrontendAPI}/ApiController.java (97%) rename src/main/java/com/blck/MusicReleaseTracker/{Simple => FrontendAPI}/SSEController.java (97%) rename src/main/java/com/blck/MusicReleaseTracker/{ => Scraping}/ScrapeProcess.java (97%) rename src/main/java/com/blck/MusicReleaseTracker/{ => Scraping}/ScraperController.java (97%) rename src/main/java/com/blck/MusicReleaseTracker/{Scrapers => Scraping}/ScraperTimeoutException.java (74%) rename src/main/java/com/blck/MusicReleaseTracker/{ => Scraping}/Scrapers/Scraper.java (96%) rename src/main/java/com/blck/MusicReleaseTracker/{ => Scraping}/Scrapers/ScraperBeatport.java (95%) rename src/main/java/com/blck/MusicReleaseTracker/{ => Scraping}/Scrapers/ScraperInterface.java (58%) rename src/main/java/com/blck/MusicReleaseTracker/{ => Scraping}/Scrapers/ScraperJunodownload.java (96%) rename src/main/java/com/blck/MusicReleaseTracker/{ => Scraping}/Scrapers/ScraperMusicbrainz.java (94%) rename src/main/java/com/blck/MusicReleaseTracker/{ => Scraping}/Scrapers/ScraperYoutube.java (95%) rename src/main/java/com/blck/MusicReleaseTracker/{Core => }/StartSetup.java (92%) create mode 100644 src/test/java/com/blck/MusicReleaseTracker/DBToolsTest_structure.java create mode 100644 src/test/java/com/blck/MusicReleaseTracker/HelperDB.java diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java b/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java index 8c9dacb..3afa21b 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java @@ -1,8 +1,9 @@ package com.blck.MusicReleaseTracker.Core; import com.blck.MusicReleaseTracker.*; -import com.blck.MusicReleaseTracker.Scrapers.Scraper; -import com.blck.MusicReleaseTracker.Simple.SSEController; +import com.blck.MusicReleaseTracker.Scraping.Scrapers.Scraper; +import com.blck.MusicReleaseTracker.Scraping.ScrapeProcess; +import com.blck.MusicReleaseTracker.FrontendAPI.SSEController; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; diff --git a/src/main/java/com/blck/MusicReleaseTracker/DBtools.java b/src/main/java/com/blck/MusicReleaseTracker/DBtools.java index 49bd4d7..a66a947 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/DBtools.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DBtools.java @@ -38,7 +38,7 @@ public DBtools(ValueStore valueStore, ErrorLogging errorLogging) { this.log = errorLogging; } - public void createTables() { + public void migrateDB() { // on start: create DB if not exist, check DB structure, if different -> create new from template and refill with all data possible final String templateFilePath = store.getAppDataPath() + "DBTemplate.db"; final String DBtemplatePath = "jdbc:sqlite:" + templateFilePath; @@ -170,6 +170,8 @@ CREATE TABLE IF NOT EXISTS combview ( } } + + public void clearDB() { // clear source tables and combview try (Connection conn = DriverManager.getConnection(store.getDBpath())) { diff --git a/src/main/java/com/blck/MusicReleaseTracker/Simple/Song.java b/src/main/java/com/blck/MusicReleaseTracker/DataModels/Song.java similarity index 97% rename from src/main/java/com/blck/MusicReleaseTracker/Simple/Song.java rename to src/main/java/com/blck/MusicReleaseTracker/DataModels/Song.java index b4d7f23..cb57974 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Simple/Song.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DataModels/Song.java @@ -1,4 +1,4 @@ -package com.blck.MusicReleaseTracker.Simple; +package com.blck.MusicReleaseTracker.DataModels; /* MusicReleaseTracker Copyright (C) 2023 BLCK diff --git a/src/main/java/com/blck/MusicReleaseTracker/Simple/TableModel.java b/src/main/java/com/blck/MusicReleaseTracker/DataModels/TableModel.java similarity index 68% rename from src/main/java/com/blck/MusicReleaseTracker/Simple/TableModel.java rename to src/main/java/com/blck/MusicReleaseTracker/DataModels/TableModel.java index ee754f4..a97defb 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Simple/TableModel.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DataModels/TableModel.java @@ -1,4 +1,4 @@ -package com.blck.MusicReleaseTracker.Simple; +package com.blck.MusicReleaseTracker.DataModels; public record TableModel(String song, String artist, String date) { //records are read-only classes diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/ApiController.java b/src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/ApiController.java similarity index 97% rename from src/main/java/com/blck/MusicReleaseTracker/Core/ApiController.java rename to src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/ApiController.java index 707a0ff..fe3e1b6 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Core/ApiController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/ApiController.java @@ -1,7 +1,7 @@ -package com.blck.MusicReleaseTracker.Core; +package com.blck.MusicReleaseTracker.FrontendAPI; import com.blck.MusicReleaseTracker.GUIController; -import com.blck.MusicReleaseTracker.Simple.TableModel; +import com.blck.MusicReleaseTracker.DataModels.TableModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.net.URLDecoder; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Simple/SSEController.java b/src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/SSEController.java similarity index 97% rename from src/main/java/com/blck/MusicReleaseTracker/Simple/SSEController.java rename to src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/SSEController.java index 35aea3f..e1dad17 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Simple/SSEController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/SSEController.java @@ -1,4 +1,4 @@ -package com.blck.MusicReleaseTracker.Simple; +package com.blck.MusicReleaseTracker.FrontendAPI; import com.blck.MusicReleaseTracker.Core.ErrorLogging; import org.springframework.beans.factory.annotation.Autowired; diff --git a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java index 720eff6..0984344 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java @@ -3,8 +3,9 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.Scrapers.*; -import com.blck.MusicReleaseTracker.Simple.TableModel; +import com.blck.MusicReleaseTracker.DataModels.TableModel; +import com.blck.MusicReleaseTracker.Scraping.ScrapeProcess; +import com.blck.MusicReleaseTracker.Scraping.Scrapers.*; import org.springframework.beans.factory.annotation.Autowired; import java.sql.*; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Main.java b/src/main/java/com/blck/MusicReleaseTracker/Main.java index e1ee214..4a7f2f1 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Main.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Main.java @@ -1,7 +1,6 @@ package com.blck.MusicReleaseTracker; import com.blck.MusicReleaseTracker.Core.ErrorLogging; -import com.blck.MusicReleaseTracker.Core.StartSetup; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; @@ -57,7 +56,7 @@ public void run(String... args) { |_| |_|_| \\_\\|_| """); startSetup.initializeSystem(); - DB.createTables(); + DB.migrateDB(); config.updateSettings(); // open port in web browser try { diff --git a/src/main/java/com/blck/MusicReleaseTracker/ScrapeProcess.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java similarity index 97% rename from src/main/java/com/blck/MusicReleaseTracker/ScrapeProcess.java rename to src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java index 3dcf05d..416a02d 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/ScrapeProcess.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java @@ -1,10 +1,12 @@ -package com.blck.MusicReleaseTracker; +package com.blck.MusicReleaseTracker.Scraping; +import com.blck.MusicReleaseTracker.ConfigTools; import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.Simple.SSEController; -import com.blck.MusicReleaseTracker.Simple.Song; +import com.blck.MusicReleaseTracker.DBtools; +import com.blck.MusicReleaseTracker.FrontendAPI.SSEController; +import com.blck.MusicReleaseTracker.DataModels.Song; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/blck/MusicReleaseTracker/ScraperController.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperController.java similarity index 97% rename from src/main/java/com/blck/MusicReleaseTracker/ScraperController.java rename to src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperController.java index 58d6c02..af4fc01 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/ScraperController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperController.java @@ -1,9 +1,10 @@ -package com.blck.MusicReleaseTracker; +package com.blck.MusicReleaseTracker.Scraping; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.Scrapers.*; import com.blck.MusicReleaseTracker.Core.ErrorLogging; +import com.blck.MusicReleaseTracker.Scraping.Scrapers.*; + import java.sql.*; import java.util.*; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTimeoutException.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperTimeoutException.java similarity index 74% rename from src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTimeoutException.java rename to src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperTimeoutException.java index 3aabe10..4564b6a 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTimeoutException.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperTimeoutException.java @@ -1,4 +1,4 @@ -package com.blck.MusicReleaseTracker.Scrapers; +package com.blck.MusicReleaseTracker.Scraping; public class ScraperTimeoutException extends Exception { diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/Scraper.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java similarity index 96% rename from src/main/java/com/blck/MusicReleaseTracker/Scrapers/Scraper.java rename to src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java index 92e634b..b50fc5f 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/Scraper.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java @@ -1,9 +1,10 @@ -package com.blck.MusicReleaseTracker.Scrapers; +package com.blck.MusicReleaseTracker.Scraping.Scrapers; import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.Simple.Song; +import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; +import com.blck.MusicReleaseTracker.DataModels.Song; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperBeatport.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java similarity index 95% rename from src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperBeatport.java rename to src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java index d49caf7..c9e307d 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperBeatport.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java @@ -1,9 +1,10 @@ -package com.blck.MusicReleaseTracker.Scrapers; +package com.blck.MusicReleaseTracker.Scraping.Scrapers; import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.Simple.Song; +import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; +import com.blck.MusicReleaseTracker.DataModels.Song; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperInterface.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperInterface.java similarity index 58% rename from src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperInterface.java rename to src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperInterface.java index 2e36491..def503e 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperInterface.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperInterface.java @@ -1,4 +1,6 @@ -package com.blck.MusicReleaseTracker.Scrapers; +package com.blck.MusicReleaseTracker.Scraping.Scrapers; + +import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; public interface ScraperInterface { diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperJunodownload.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java similarity index 96% rename from src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperJunodownload.java rename to src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java index c8110f4..ad07760 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperJunodownload.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java @@ -1,8 +1,9 @@ -package com.blck.MusicReleaseTracker.Scrapers; +package com.blck.MusicReleaseTracker.Scraping.Scrapers; import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; -import com.blck.MusicReleaseTracker.Simple.Song; +import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; +import com.blck.MusicReleaseTracker.DataModels.Song; import com.blck.MusicReleaseTracker.Core.ValueStore; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperMusicbrainz.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java similarity index 94% rename from src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperMusicbrainz.java rename to src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java index f478526..2eedbf4 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperMusicbrainz.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java @@ -1,8 +1,9 @@ -package com.blck.MusicReleaseTracker.Scrapers; +package com.blck.MusicReleaseTracker.Scraping.Scrapers; import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; -import com.blck.MusicReleaseTracker.Simple.Song; +import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; +import com.blck.MusicReleaseTracker.DataModels.Song; import com.blck.MusicReleaseTracker.Core.ValueStore; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperYoutube.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperYoutube.java similarity index 95% rename from src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperYoutube.java rename to src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperYoutube.java index 80248f2..89ad395 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scrapers/ScraperYoutube.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperYoutube.java @@ -1,8 +1,9 @@ -package com.blck.MusicReleaseTracker.Scrapers; +package com.blck.MusicReleaseTracker.Scraping.Scrapers; import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; -import com.blck.MusicReleaseTracker.Simple.Song; +import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; +import com.blck.MusicReleaseTracker.DataModels.Song; import com.blck.MusicReleaseTracker.Core.ValueStore; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/StartSetup.java b/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java similarity index 92% rename from src/main/java/com/blck/MusicReleaseTracker/Core/StartSetup.java rename to src/main/java/com/blck/MusicReleaseTracker/StartSetup.java index 2b2f93f..c7686b5 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Core/StartSetup.java +++ b/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java @@ -1,6 +1,8 @@ -package com.blck.MusicReleaseTracker.Core; +package com.blck.MusicReleaseTracker; +import com.blck.MusicReleaseTracker.Core.ErrorLogging; +import com.blck.MusicReleaseTracker.Core.ValueStore; import org.springframework.beans.factory.annotation.Autowired; import java.io.File; diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 6db4687..ce09c16 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -12,9 +12,13 @@ opens com.blck.MusicReleaseTracker; exports com.blck.MusicReleaseTracker; - exports com.blck.MusicReleaseTracker.Simple; - opens com.blck.MusicReleaseTracker.Simple; exports com.blck.MusicReleaseTracker.Core; opens com.blck.MusicReleaseTracker.Core; + opens com.blck.MusicReleaseTracker.Scraping; + exports com.blck.MusicReleaseTracker.Scraping; + exports com.blck.MusicReleaseTracker.FrontendAPI; + opens com.blck.MusicReleaseTracker.FrontendAPI; + exports com.blck.MusicReleaseTracker.DataModels; + opens com.blck.MusicReleaseTracker.DataModels; } diff --git a/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest_structure.java b/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest_structure.java new file mode 100644 index 0000000..029200c --- /dev/null +++ b/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest_structure.java @@ -0,0 +1,20 @@ +package com.blck.MusicReleaseTracker; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class DBToolsTest_structure { + + private DBtools dBtools; + + @BeforeEach + public void setUp() { + dBtools = new DBtools(null, null); + } + + @Test + public void createTables() { + + } + +} diff --git a/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java b/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java new file mode 100644 index 0000000..a630b20 --- /dev/null +++ b/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java @@ -0,0 +1,13 @@ +package com.blck.MusicReleaseTracker; + +public class HelperDB { + + public void redoBasicTables() { + + } + + public void redoTestData() { + + } + +} diff --git a/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java b/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java index 4f03944..ed63c41 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java @@ -1,7 +1,8 @@ package com.blck.MusicReleaseTracker; import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.Simple.Song; +import com.blck.MusicReleaseTracker.DataModels.Song; +import com.blck.MusicReleaseTracker.Scraping.ScrapeProcess; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java b/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java index 9459f8e..dc75f61 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java @@ -1,6 +1,7 @@ package com.blck.MusicReleaseTracker.Scrapers; -import com.blck.MusicReleaseTracker.Simple.Song; +import com.blck.MusicReleaseTracker.Scraping.Scrapers.*; +import com.blck.MusicReleaseTracker.DataModels.Song; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; From d2de96a61847f3df70bffaa9ae6d421b59e11076 Mon Sep 17 00:00:00 2001 From: BLCK <123077751+BLCK-B@users.noreply.github.com> Date: Tue, 14 May 2024 18:02:36 +0200 Subject: [PATCH 04/22] DBhelper prepared --- .../MusicReleaseTracker/Core/SourcesEnum.java | 2 +- .../com/blck/MusicReleaseTracker/DBtools.java | 13 ++++------ .../MusicReleaseTracker/GUIController.java | 4 ++-- .../blck/MusicReleaseTracker/DBToolsTest.java | 24 +++++++++++++++++++ .../DBToolsTest_structure.java | 20 ---------------- .../blck/MusicReleaseTracker/HelperDB.java | 16 +++++++++++-- 6 files changed, 46 insertions(+), 33 deletions(-) create mode 100644 src/test/java/com/blck/MusicReleaseTracker/DBToolsTest.java delete mode 100644 src/test/java/com/blck/MusicReleaseTracker/DBToolsTest_structure.java diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/SourcesEnum.java b/src/main/java/com/blck/MusicReleaseTracker/Core/SourcesEnum.java index 66b26f1..4cb715d 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Core/SourcesEnum.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Core/SourcesEnum.java @@ -1,6 +1,6 @@ package com.blck.MusicReleaseTracker.Core; -/** an important enum used throughout the backend */ +/** a central enum declaring web sources */ public enum SourcesEnum { beatport, musicbrainz, diff --git a/src/main/java/com/blck/MusicReleaseTracker/DBtools.java b/src/main/java/com/blck/MusicReleaseTracker/DBtools.java index a66a947..0e39fb2 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/DBtools.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DBtools.java @@ -4,7 +4,6 @@ import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; import org.springframework.beans.factory.annotation.Autowired; - import java.io.File; import java.sql.*; import java.util.ArrayList; @@ -46,8 +45,8 @@ public void migrateDB() { File templateFile = new File(templateFilePath); templateFile.delete(); - createDB(store.getDBpath()); - createDB(DBtemplatePath); + createDBandSourceTables(store.getDBpath()); + createDBandSourceTables(DBtemplatePath); // if different structure, fill template artist table data from musicdata and then rename/delete, make new template // this only preserves "artists" data and assumes that the insertion logic will be adjusted after any changes @@ -98,9 +97,9 @@ public void migrateDB() { } } - private void createDB(String path) { + public void createDBandSourceTables(String path) { + // note: generate by string templates after preview try (Connection conn = DriverManager.getConnection(path)) { - String sql = """ CREATE TABLE IF NOT EXISTS musicbrainz ( song text NOT NULL, @@ -170,8 +169,6 @@ CREATE TABLE IF NOT EXISTS combview ( } } - - public void clearDB() { // clear source tables and combview try (Connection conn = DriverManager.getConnection(store.getDBpath())) { @@ -221,7 +218,7 @@ public void resetDB() { // default the musicdata File musicdata = new File(store.getAppDataPath() + "musicdata.db"); musicdata.delete(); - createDB(store.getDBpath()); + createDBandSourceTables(store.getDBpath()); } } diff --git a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java index 0984344..504ac6b 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java @@ -61,7 +61,7 @@ public List loadList() { List dataList = new ArrayList<>(); try (Connection conn = DriverManager.getConnection(store.getDBpath())) { Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery("SELECT artistname FROM artists ORDER BY artistname ASC LIMIT 500"); + ResultSet rs = stmt.executeQuery("SELECT artistname FROM artists ORDER BY artistname LIMIT 500"); while (rs.next()) { dataList.add(rs.getString("artistname")); } @@ -181,7 +181,7 @@ public void loadCombviewTable() { tableContent.clear(); try (Connection conn = DriverManager.getConnection(store.getDBpath())) { // populating combview table - String sql = "SELECT song, artist, date FROM combview ORDER BY date DESC, artist ASC, song ASC LIMIT 1000"; + String sql = "SELECT song, artist, date FROM combview ORDER BY date DESC, artist, song LIMIT 1000"; PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { diff --git a/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest.java b/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest.java new file mode 100644 index 0000000..15aa66b --- /dev/null +++ b/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest.java @@ -0,0 +1,24 @@ +package com.blck.MusicReleaseTracker; +import com.blck.MusicReleaseTracker.Core.ValueStore; +import org.springframework.test.context.event.annotation.BeforeTestClass; + +import java.nio.file.Paths; + +public class DBToolsTest { + + private String testDBpath; + private ValueStore store; + private DBtools dBtools; + + @BeforeTestClass + public void setUp() { + HelperDB.redoTestDB(); + testDBpath = "jdbc:sqlite:" + Paths.get("src", "test", "testresources", "testdb.db"); + store = new ValueStore(); + store.setDBpath(testDBpath); + dBtools = new DBtools(store, null); + } + + + +} diff --git a/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest_structure.java b/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest_structure.java deleted file mode 100644 index 029200c..0000000 --- a/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest_structure.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.blck.MusicReleaseTracker; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -public class DBToolsTest_structure { - - private DBtools dBtools; - - @BeforeEach - public void setUp() { - dBtools = new DBtools(null, null); - } - - @Test - public void createTables() { - - } - -} diff --git a/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java b/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java index a630b20..a0f63fb 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java +++ b/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java @@ -1,13 +1,25 @@ package com.blck.MusicReleaseTracker; +import java.io.File; +import java.nio.file.Paths; + public class HelperDB { - public void redoBasicTables() { + private static DBtools dBtools; + public static void redoTestDB() { + File testDB = new File(DBpath()); + if (testDB.exists()) + testDB.delete(); + dBtools.createDBandSourceTables(DBpath()); } - public void redoTestData() { + public static void redoTestData() { + + } + private static String DBpath() { + return "jdbc:sqlite:" + Paths.get("src", "test", "testresources", "testdb.db"); } } From eb9451b1120f7f34611636220dc19a80beba68d1 Mon Sep 17 00:00:00 2001 From: BLCK <123077751+BLCK-B@users.noreply.github.com> Date: Wed, 15 May 2024 08:34:12 +0200 Subject: [PATCH 05/22] manageDB class --- .../Core/{MRTConfig.java => BeanConfig.java} | 13 +- .../com/blck/MusicReleaseTracker/DBtools.java | 179 +-------------- .../MusicReleaseTracker/GUIController.java | 9 +- .../com/blck/MusicReleaseTracker/Main.java | 8 +- .../MusicReleaseTracker/ManageMigrateDB.java | 205 ++++++++++++++++++ .../Scraping/ScrapeProcess.java | 2 +- .../GUIControllerTest.java | 2 +- .../blck/MusicReleaseTracker/HelperDB.java | 3 +- 8 files changed, 231 insertions(+), 190 deletions(-) rename src/main/java/com/blck/MusicReleaseTracker/Core/{MRTConfig.java => BeanConfig.java} (80%) create mode 100644 src/main/java/com/blck/MusicReleaseTracker/ManageMigrateDB.java diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java b/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java similarity index 80% rename from src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java rename to src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java index 3afa21b..5af2281 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Core/MRTConfig.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java @@ -10,7 +10,7 @@ /** config class for spring boot to manage lifecycle of the beans, this helps avoid static classes each bean has a single instance, beans defined here can be used by other classes as dependencies */ @Configuration -public class MRTConfig { +public class BeanConfig { @Bean public ValueStore valueStore() { @@ -33,8 +33,10 @@ public Scraper scraperParent(ValueStore valueStore, ErrorLogging errorLogging) { } @Bean - public GUIController guiController(ValueStore valueStore, ErrorLogging errorLogging, ScrapeProcess scrapeProcess, ConfigTools config, DBtools dBtools) { - return new GUIController(valueStore, errorLogging, scrapeProcess, config, dBtools); + public GUIController guiController(ValueStore valueStore, ErrorLogging errorLogging, + ScrapeProcess scrapeProcess, ConfigTools config, + ManageMigrateDB manageMigrateDB, DBtools dBtools) { + return new GUIController(valueStore, errorLogging, scrapeProcess, config, dBtools, manageMigrateDB); } @Bean @@ -42,6 +44,11 @@ public ConfigTools configTools(ValueStore valueStore, ErrorLogging errorLogging) return new ConfigTools(valueStore, errorLogging); } + @Bean + public ManageMigrateDB manageMigrateDB(ValueStore valueStore, ErrorLogging errorLogging) { + return new ManageMigrateDB(valueStore, errorLogging); + } + @Bean public DBtools dBtools(ValueStore valueStore, ErrorLogging errorLogging) { return new DBtools(valueStore, errorLogging); diff --git a/src/main/java/com/blck/MusicReleaseTracker/DBtools.java b/src/main/java/com/blck/MusicReleaseTracker/DBtools.java index 0e39fb2..9a9b309 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/DBtools.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DBtools.java @@ -4,11 +4,8 @@ import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; import org.springframework.beans.factory.annotation.Autowired; -import java.io.File; + import java.sql.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; /* MusicReleaseTracker Copyright (C) 2023 BLCK @@ -23,9 +20,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see .*/ -/** - * class for DB operations - */ public class DBtools { private final ValueStore store; @@ -37,140 +31,7 @@ public DBtools(ValueStore valueStore, ErrorLogging errorLogging) { this.log = errorLogging; } - public void migrateDB() { - // on start: create DB if not exist, check DB structure, if different -> create new from template and refill with all data possible - final String templateFilePath = store.getAppDataPath() + "DBTemplate.db"; - final String DBtemplatePath = "jdbc:sqlite:" + templateFilePath; - final String DBfilePath = store.getAppDataPath() + "musicdata.db"; - - File templateFile = new File(templateFilePath); - templateFile.delete(); - createDBandSourceTables(store.getDBpath()); - createDBandSourceTables(DBtemplatePath); - - // if different structure, fill template artist table data from musicdata and then rename/delete, make new template - // this only preserves "artists" data and assumes that the insertion logic will be adjusted after any changes - // made to the "artists" table: change in order of columns, adding/removing a column or changing a column's name - Map> DBMap = getDBStructure(store.getDBpath()); - Map> DBtemplateMap = getDBStructure(DBtemplatePath); - if (!DBMap.equals(DBtemplateMap)) { - try ( - Connection connDB = DriverManager.getConnection(store.getDBpath()); - Connection connDBtemplate = DriverManager.getConnection(DBtemplatePath) - ) { - // insert data from musicdata's column to template's column - String sql = "SELECT * FROM artists LIMIT 1000"; - Statement stmt = connDB.createStatement(); - ResultSet rs = stmt.executeQuery(sql); - - sql = "insert into artists(artistname, urlmusicbrainz, urlbeatport, urljunodownload, urlyoutube) values(?, ?, ?, ?, ?)"; - PreparedStatement pstmt = connDBtemplate.prepareStatement(sql); - ArrayList columnList = DBMap.get("artists"); - // cycling table rows - while (rs.next()) { - // construct sql query for every column, add to batch - for (int i = 0; i < columnList.size(); i++) { - String column = columnList.get(i); - pstmt.setString(i + 1, rs.getString(column)); - } - pstmt.addBatch(); - } - connDBtemplate.setAutoCommit(false); - pstmt.executeBatch(); - connDBtemplate.commit(); - connDBtemplate.setAutoCommit(true); - pstmt.clearBatch(); - pstmt.close(); - } catch (Exception e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error updating DB file"); - } - try { - File oldFile = new File(DBfilePath); - File newFile = new File(templateFilePath); - // delete old musicdata - oldFile.delete(); - // rename template to musicdata - newFile.renameTo(oldFile); - } catch (Exception e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error renaming/deleting DB files"); - } - } - } - - public void createDBandSourceTables(String path) { - // note: generate by string templates after preview - try (Connection conn = DriverManager.getConnection(path)) { - String sql = """ - CREATE TABLE IF NOT EXISTS musicbrainz ( - song text NOT NULL, - artist text NOT NULL, - date text NOT NULL - ); - """; - Statement stmt = conn.createStatement(); - stmt.execute(sql); - - sql = """ - CREATE TABLE IF NOT EXISTS beatport ( - song text NOT NULL, - artist text NOT NULL, - date text NOT NULL, - type text NOT NULL - ); - """; - stmt = conn.createStatement(); - stmt.execute(sql); - - sql = """ - CREATE TABLE IF NOT EXISTS junodownload ( - song text NOT NULL, - artist text NOT NULL, - date text NOT NULL - ); - """; - stmt = conn.createStatement(); - stmt.execute(sql); - - sql = """ - CREATE TABLE IF NOT EXISTS youtube ( - song text NOT NULL, - artist text NOT NULL, - date text NOT NULL - ); - """; - stmt = conn.createStatement(); - stmt.execute(sql); - - sql = """ - CREATE TABLE IF NOT EXISTS artists ( - artistname text PRIMARY KEY, - urlmusicbrainz text, - urlbeatport text, - urljunodownload text, - urlyoutube text - ); - """; - stmt = conn.createStatement(); - stmt.execute(sql); - - sql = """ - CREATE TABLE IF NOT EXISTS combview ( - song text NOT NULL, - artist text NOT NULL, - date text NOT NULL - ); - """; - stmt = conn.createStatement(); - stmt.execute(sql); - - stmt.close(); - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error creating DB file"); - } - } - - public void clearDB() { - // clear source tables and combview + public void truncateDB() { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { for (SourcesEnum sourceTable : SourcesEnum.values()) { String sql = "DELETE FROM " + sourceTable; @@ -184,42 +45,6 @@ public void clearDB() { log.error(e, ErrorLogging.Severity.WARNING, "error clearing DB"); } } - - public Map> getDBStructure(String path) { - // assembles a structure of tables and their columns - HashMap> tableMap = new HashMap<>(); - - try (Connection conn = DriverManager.getConnection(path)) { - String sql = "SELECT name FROM sqlite_master WHERE type='table'"; - Statement stmt = conn.createStatement(); - ResultSet rsTables = stmt.executeQuery(sql); - ArrayList tablesList = new ArrayList<>(); - - while (rsTables.next()) - tablesList.add(rsTables.getString(1)); - - for (String tableName : tablesList) { - ArrayList tableColumnsList = new ArrayList<>(); - ResultSet rsColumns = stmt.executeQuery("PRAGMA table_info(" + tableName + ")"); - - while (rsColumns.next()) - tableColumnsList.add(rsColumns.getString("name")); - - tableMap.put(tableName, tableColumnsList); - } - stmt.close(); - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error parsing DB structure"); - } - return tableMap; - } - - public void resetDB() { - // default the musicdata - File musicdata = new File(store.getAppDataPath() + "musicdata.db"); - musicdata.delete(); - createDBandSourceTables(store.getDBpath()); - } } diff --git a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java index 504ac6b..5e3671b 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java @@ -37,18 +37,21 @@ public class GUIController { private final ScrapeProcess scrapeProcess; private final ConfigTools config; private final DBtools DB; + private final ManageMigrateDB manageDB; private final List tableContent = new ArrayList<>(); private SourcesEnum selectedSource; private String lastClickedArtist; private String tempID; @Autowired - public GUIController(ValueStore valueStore, ErrorLogging errorLogging, ScrapeProcess scrapeProcess, ConfigTools config, DBtools DB) { + public GUIController(ValueStore valueStore, ErrorLogging errorLogging, ScrapeProcess scrapeProcess, + ConfigTools config, DBtools DB, ManageMigrateDB manageDB) { this.store = valueStore; this.log = errorLogging; this.scrapeProcess = scrapeProcess; this.config = config; this.DB = DB; + this.manageDB = manageDB; } public void setTestData(String lastClickedArtist, SourcesEnum selectedSource) { @@ -93,7 +96,7 @@ public void artistClickDelete() { // delete last selected artist and all entries from artist if (lastClickedArtist != null) { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - Map> tableMap = DB.getDBStructure(store.getDBpath()); + Map> tableMap = manageDB.getDBStructure(store.getDBpath()); String sql; for (String tableName : tableMap.keySet()) { if (tableName.equals("artists")) @@ -338,6 +341,6 @@ public void resetSettings() { } public void resetDB() { - DB.resetDB(); + manageDB.resetDB(); } } \ No newline at end of file diff --git a/src/main/java/com/blck/MusicReleaseTracker/Main.java b/src/main/java/com/blck/MusicReleaseTracker/Main.java index 4a7f2f1..6e326cc 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Main.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Main.java @@ -30,15 +30,15 @@ public static void main(String[] args) { private final ConfigTools config; private final ErrorLogging log; - private final DBtools DB; + private final ManageMigrateDB manageDB; private final StartSetup startSetup; @Autowired - public Main(ConfigTools configTools, ErrorLogging errorLogging, DBtools dBtools, StartSetup startSetup) { + public Main(ConfigTools configTools, ErrorLogging errorLogging, StartSetup startSetup, ManageMigrateDB manageDB) { this.config = configTools; this.log = errorLogging; - this.DB = dBtools; this.startSetup = startSetup; + this.manageDB = manageDB; } @Component @@ -56,7 +56,7 @@ public void run(String... args) { |_| |_|_| \\_\\|_| """); startSetup.initializeSystem(); - DB.migrateDB(); + manageDB.migrateDB(); config.updateSettings(); // open port in web browser try { diff --git a/src/main/java/com/blck/MusicReleaseTracker/ManageMigrateDB.java b/src/main/java/com/blck/MusicReleaseTracker/ManageMigrateDB.java new file mode 100644 index 0000000..74bf6f0 --- /dev/null +++ b/src/main/java/com/blck/MusicReleaseTracker/ManageMigrateDB.java @@ -0,0 +1,205 @@ +package com.blck.MusicReleaseTracker; + +import com.blck.MusicReleaseTracker.Core.ErrorLogging; +import com.blck.MusicReleaseTracker.Core.ValueStore; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.File; +import java.sql.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +/* MusicReleaseTracker + Copyright (C) 2023 BLCK + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see .*/ + +public class ManageMigrateDB { + + private final ValueStore store; + private final ErrorLogging log; + + @Autowired + public ManageMigrateDB(ValueStore valueStore, ErrorLogging errorLogging) { + this.store = valueStore; + this.log = errorLogging; + } + + public void createDBandSourceTables(String path) { + // note: generate by string templates after preview + try (Connection conn = DriverManager.getConnection(path)) { + String sql = """ + CREATE TABLE IF NOT EXISTS musicbrainz ( + song text NOT NULL, + artist text NOT NULL, + date text NOT NULL + ); + """; + Statement stmt = conn.createStatement(); + stmt.execute(sql); + + sql = """ + CREATE TABLE IF NOT EXISTS beatport ( + song text NOT NULL, + artist text NOT NULL, + date text NOT NULL, + type text NOT NULL + ); + """; + stmt = conn.createStatement(); + stmt.execute(sql); + + sql = """ + CREATE TABLE IF NOT EXISTS junodownload ( + song text NOT NULL, + artist text NOT NULL, + date text NOT NULL + ); + """; + stmt = conn.createStatement(); + stmt.execute(sql); + + sql = """ + CREATE TABLE IF NOT EXISTS youtube ( + song text NOT NULL, + artist text NOT NULL, + date text NOT NULL + ); + """; + stmt = conn.createStatement(); + stmt.execute(sql); + + sql = """ + CREATE TABLE IF NOT EXISTS artists ( + artistname text PRIMARY KEY, + urlmusicbrainz text, + urlbeatport text, + urljunodownload text, + urlyoutube text + ); + """; + stmt = conn.createStatement(); + stmt.execute(sql); + + sql = """ + CREATE TABLE IF NOT EXISTS combview ( + song text NOT NULL, + artist text NOT NULL, + date text NOT NULL + ); + """; + stmt = conn.createStatement(); + stmt.execute(sql); + + stmt.close(); + } catch (SQLException e) { + log.error(e, ErrorLogging.Severity.SEVERE, "error creating DB file"); + } + } + + public void resetDB() { + // default the musicdata + File musicdata = new File(store.getAppDataPath() + "musicdata.db"); + musicdata.delete(); + createDBandSourceTables(store.getDBpath()); + } + + public void migrateDB() { + // on start: create DB if not exist, check DB structure, if different -> create new from template and refill with all data possible + final String templateFilePath = store.getAppDataPath() + "DBTemplate.db"; + final String DBtemplatePath = "jdbc:sqlite:" + templateFilePath; + final String DBfilePath = store.getAppDataPath() + "musicdata.db"; + + File templateFile = new File(templateFilePath); + templateFile.delete(); + createDBandSourceTables(store.getDBpath()); + createDBandSourceTables(DBtemplatePath); + + // if different structure, fill template artist table data from musicdata and then rename/delete, make new template + // this only preserves "artists" data and assumes that the insertion logic will be adjusted after any changes + // made to the "artists" table: change in order of columns, adding/removing a column or changing a column's name + Map> DBMap = getDBStructure(store.getDBpath()); + Map> DBtemplateMap = getDBStructure(DBtemplatePath); + if (!DBMap.equals(DBtemplateMap)) { + try ( + Connection connDB = DriverManager.getConnection(store.getDBpath()); + Connection connDBtemplate = DriverManager.getConnection(DBtemplatePath) + ) { + // insert data from musicdata's column to template's column + String sql = "SELECT * FROM artists LIMIT 1000"; + Statement stmt = connDB.createStatement(); + ResultSet rs = stmt.executeQuery(sql); + + sql = "insert into artists(artistname, urlmusicbrainz, urlbeatport, urljunodownload, urlyoutube) values(?, ?, ?, ?, ?)"; + PreparedStatement pstmt = connDBtemplate.prepareStatement(sql); + ArrayList columnList = DBMap.get("artists"); + // cycling table rows + while (rs.next()) { + // construct sql query for every column, add to batch + for (int i = 0; i < columnList.size(); i++) { + String column = columnList.get(i); + pstmt.setString(i + 1, rs.getString(column)); + } + pstmt.addBatch(); + } + connDBtemplate.setAutoCommit(false); + pstmt.executeBatch(); + connDBtemplate.commit(); + connDBtemplate.setAutoCommit(true); + pstmt.clearBatch(); + pstmt.close(); + } catch (Exception e) { + log.error(e, ErrorLogging.Severity.SEVERE, "error updating DB file"); + } + try { + File oldFile = new File(DBfilePath); + File newFile = new File(templateFilePath); + // delete old musicdata + oldFile.delete(); + // rename template to musicdata + newFile.renameTo(oldFile); + } catch (Exception e) { + log.error(e, ErrorLogging.Severity.SEVERE, "error renaming/deleting DB files"); + } + } + } + + public Map> getDBStructure(String path) { + // assembles a structure of tables and their columns + HashMap> tableMap = new HashMap<>(); + + try (Connection conn = DriverManager.getConnection(path)) { + String sql = "SELECT name FROM sqlite_master WHERE type='table'"; + Statement stmt = conn.createStatement(); + ResultSet rsTables = stmt.executeQuery(sql); + ArrayList tablesList = new ArrayList<>(); + + while (rsTables.next()) + tablesList.add(rsTables.getString(1)); + + for (String tableName : tablesList) { + ArrayList tableColumnsList = new ArrayList<>(); + ResultSet rsColumns = stmt.executeQuery("PRAGMA table_info(" + tableName + ")"); + + while (rsColumns.next()) + tableColumnsList.add(rsColumns.getString("name")); + + tableMap.put(tableName, tableColumnsList); + } + stmt.close(); + } catch (SQLException e) { + log.error(e, ErrorLogging.Severity.SEVERE, "error parsing DB structure"); + } + return tableMap; + } + +} diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java index 416a02d..8fea3ac 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java @@ -56,7 +56,7 @@ public ScrapeProcess(ValueStore valueStore, ErrorLogging errorLogging, ConfigToo public void scrapeData() { config.readConfig(ConfigTools.configOptions.longTimeout); scrapeCancel = false; - DB.clearDB(); + DB.truncateDB(); ScraperController scrapers = new ScraperController(store, log); final int initSize = scrapers.getInitSize(); // triggering scrapers diff --git a/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java b/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java index 30018a6..1a68aba 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java @@ -35,7 +35,7 @@ void setUp() { store = new ValueStore(); store.setDBpath(DBpath); DB = new DBtools(store, null); - guiController = new GUIController(store, null, null, null, DB); + guiController = new GUIController(store, null, null, null, DB, null); guiController.setTestData("Joe", SourcesEnum.beatport); } diff --git a/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java b/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java index a0f63fb..1437222 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java +++ b/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java @@ -6,12 +6,13 @@ public class HelperDB { private static DBtools dBtools; + private static ManageMigrateDB manageDB; public static void redoTestDB() { File testDB = new File(DBpath()); if (testDB.exists()) testDB.delete(); - dBtools.createDBandSourceTables(DBpath()); + manageDB.createDBandSourceTables(DBpath()); } public static void redoTestData() { From d3784af887450a0ab75fe43740536c6cb7487b0a Mon Sep 17 00:00:00 2001 From: BLCK <123077751+BLCK-B@users.noreply.github.com> Date: Wed, 15 May 2024 10:32:14 +0200 Subject: [PATCH 06/22] guicontroller DB separation, artistname -> artist --- .../MusicReleaseTracker/Core/BeanConfig.java | 4 +- .../com/blck/MusicReleaseTracker/DBtools.java | 140 ++++++++++++- .../{DataModels => DataObjects}/Song.java | 2 +- .../TableModel.java | 2 +- .../FrontendAPI/ApiController.java | 12 +- .../MusicReleaseTracker/GUIController.java | 186 +++--------------- .../MusicReleaseTracker/ManageMigrateDB.java | 8 +- .../Scraping/ScrapeProcess.java | 4 +- .../Scraping/ScraperController.java | 6 +- .../Scraping/Scrapers/Scraper.java | 2 +- .../Scraping/Scrapers/ScraperBeatport.java | 2 +- .../Scrapers/ScraperJunodownload.java | 2 +- .../Scraping/Scrapers/ScraperMusicbrainz.java | 2 +- .../Scraping/Scrapers/ScraperYoutube.java | 2 +- .../blck/MusicReleaseTracker/StartSetup.java | 24 ++- src/main/java/module-info.java | 4 +- .../blck/MusicReleaseTracker/DBToolsTest.java | 2 +- .../GUIControllerTest.java | 2 +- .../ScrapeProcessTest.java | 4 +- .../Scrapers/ScraperTest.java | 2 +- 20 files changed, 207 insertions(+), 205 deletions(-) rename src/main/java/com/blck/MusicReleaseTracker/{DataModels => DataObjects}/Song.java (97%) rename src/main/java/com/blck/MusicReleaseTracker/{DataModels => DataObjects}/TableModel.java (68%) diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java b/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java index 5af2281..bd8501d 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java @@ -50,8 +50,8 @@ public ManageMigrateDB manageMigrateDB(ValueStore valueStore, ErrorLogging error } @Bean - public DBtools dBtools(ValueStore valueStore, ErrorLogging errorLogging) { - return new DBtools(valueStore, errorLogging); + public DBtools dBtools(ValueStore valueStore, ErrorLogging errorLogging, ManageMigrateDB manageMigrateDB) { + return new DBtools(valueStore, errorLogging, manageMigrateDB); } @Bean diff --git a/src/main/java/com/blck/MusicReleaseTracker/DBtools.java b/src/main/java/com/blck/MusicReleaseTracker/DBtools.java index 9a9b309..62539b8 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/DBtools.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DBtools.java @@ -3,9 +3,12 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; +import com.blck.MusicReleaseTracker.DataObjects.TableModel; import org.springframework.beans.factory.annotation.Autowired; import java.sql.*; +import java.util.ArrayList; +import java.util.List; /* MusicReleaseTracker Copyright (C) 2023 BLCK @@ -24,14 +27,136 @@ public class DBtools { private final ValueStore store; private final ErrorLogging log; + private final ManageMigrateDB manageDB; @Autowired - public DBtools(ValueStore valueStore, ErrorLogging errorLogging) { + public DBtools(ValueStore valueStore, ErrorLogging errorLogging, ManageMigrateDB manageDB) { this.store = valueStore; this.log = errorLogging; + this.manageDB = manageDB; } - public void truncateDB() { + public List getArtistList() { + List dataList = new ArrayList<>(); + try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT artist FROM artists ORDER BY artist LIMIT 500"); + while (rs.next()) { + dataList.add(rs.getString("artist")); + } + stmt.close(); + rs.close(); + } catch (SQLException e) { + log.error(e, ErrorLogging.Severity.SEVERE, "error loading list"); + } + return dataList; + } + + public List loadTable(SourcesEnum source, String name) { + // adding data to tableContent + List tableContent = new ArrayList<>(); + try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + String sql = "SELECT song, date FROM " + source + " WHERE artist = ? ORDER BY date DESC LIMIT 100"; + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.setString(1, name); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + String songsCol = rs.getString("song"); + String datesCol = rs.getString("date"); + tableContent.add(new TableModel(songsCol, null, datesCol)); + } + pstmt.close(); + rs.close(); + } catch (SQLException e) { + log.error(e, ErrorLogging.Severity.SEVERE, "error loading table"); + } + return tableContent; + } + + public List loadCombviewTable() { + List tableContent = new ArrayList<>(); + try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + String sql = "SELECT song, artist, date FROM combview ORDER BY date DESC, artist, song LIMIT 1000"; + PreparedStatement pstmt = conn.prepareStatement(sql); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) { + String songsCol = rs.getString("song"); + String artistsCol = rs.getString("artist"); + String datesCol = rs.getString("date"); + tableContent.add(new TableModel(songsCol, artistsCol, datesCol)); + } + pstmt.close(); + rs.close(); + } catch (SQLException e) { + log.error(e, ErrorLogging.Severity.SEVERE, "error loading combview table"); + } + return tableContent; + } + + public void insertIntoArtistList(String name) { + try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + String sql = "INSERT INTO artists (artist) values(?)"; + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.setString(1, name); + pstmt.executeUpdate(); + pstmt.close(); + } catch (SQLException e) { + System.out.println("artist already exists"); + } + } + + public void updateArtistSourceID(String name, SourcesEnum source, String ID) { + String sql; + if (ID == null) + sql = "UPDATE artists SET url" + source + " = NULL WHERE artist = ?"; + else + sql = "UPDATE artists SET url" + source + " = ? WHERE artist = ?"; + try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + PreparedStatement pstmt = conn.prepareStatement(sql); + if (ID == null) { + pstmt.setString(1, name); + } + else { + pstmt.setString(1, ID); + pstmt.setString(2, name); + } + pstmt.executeUpdate(); + } catch (SQLException e) { + log.error(e, ErrorLogging.Severity.WARNING, "could not save URL"); + } + } + + public String getArtistSourceID(String name, SourcesEnum source) { + String ID = null; + String sql = "SELECT url" + source + " FROM artists WHERE artist = ?"; + try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.setString(1, name); + ID = pstmt.executeQuery().getString(1); + pstmt.close(); + } catch (SQLException e) { + log.error(e, ErrorLogging.Severity.WARNING, "error checking url existence"); + } + return ID; + } + + public void clearArtistDataFrom(String name, String table) { + try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + String sql = "DELETE FROM " + table + " WHERE artist = ?"; + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.setString(1, name); + pstmt.executeUpdate(); + } catch (SQLException e) { + log.error(e, ErrorLogging.Severity.SEVERE, "error deleting artists data in " + table); + } + } + + public void removeArtist(String name) { + for (String tableName : manageDB.getDBStructure(store.getDBpath()).keySet()) + clearArtistDataFrom(name, tableName); + } + + public void truncateAllScrapeData() { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { for (SourcesEnum sourceTable : SourcesEnum.values()) { String sql = "DELETE FROM " + sourceTable; @@ -45,6 +170,17 @@ public void truncateDB() { log.error(e, ErrorLogging.Severity.WARNING, "error clearing DB"); } } + + public void vacuum() { + try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + String sql = "VACUUM;"; + PreparedStatement pstmt = conn.prepareStatement(sql); + pstmt.execute(); + pstmt.close(); + } catch (SQLException e) { + log.error(e, ErrorLogging.Severity.WARNING, "vacuum error"); + } + } } diff --git a/src/main/java/com/blck/MusicReleaseTracker/DataModels/Song.java b/src/main/java/com/blck/MusicReleaseTracker/DataObjects/Song.java similarity index 97% rename from src/main/java/com/blck/MusicReleaseTracker/DataModels/Song.java rename to src/main/java/com/blck/MusicReleaseTracker/DataObjects/Song.java index cb57974..7c3cc8a 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/DataModels/Song.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DataObjects/Song.java @@ -1,4 +1,4 @@ -package com.blck.MusicReleaseTracker.DataModels; +package com.blck.MusicReleaseTracker.DataObjects; /* MusicReleaseTracker Copyright (C) 2023 BLCK diff --git a/src/main/java/com/blck/MusicReleaseTracker/DataModels/TableModel.java b/src/main/java/com/blck/MusicReleaseTracker/DataObjects/TableModel.java similarity index 68% rename from src/main/java/com/blck/MusicReleaseTracker/DataModels/TableModel.java rename to src/main/java/com/blck/MusicReleaseTracker/DataObjects/TableModel.java index a97defb..99f4a1a 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/DataModels/TableModel.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DataObjects/TableModel.java @@ -1,4 +1,4 @@ -package com.blck.MusicReleaseTracker.DataModels; +package com.blck.MusicReleaseTracker.DataObjects; public record TableModel(String song, String artist, String date) { //records are read-only classes diff --git a/src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/ApiController.java b/src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/ApiController.java index fe3e1b6..a38d4f2 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/ApiController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/ApiController.java @@ -1,7 +1,7 @@ package com.blck.MusicReleaseTracker.FrontendAPI; import com.blck.MusicReleaseTracker.GUIController; -import com.blck.MusicReleaseTracker.DataModels.TableModel; +import com.blck.MusicReleaseTracker.DataObjects.TableModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.net.URLDecoder; @@ -44,22 +44,22 @@ public List loadList() { public List listOrTabClick(@RequestBody Map requestData) { String item = requestData.get("item"); String origin = requestData.get("origin"); - return sendRequest.listOrTabClick(item, origin); + return sendRequest.getTableData(item, origin); } @PostMapping("/clickArtistAdd") public void clickArtistAdd(@RequestBody String artistname) { artistname = URLDecoder.decode(artistname, StandardCharsets.UTF_8).replace("=" , "").trim(); - sendRequest.artistAddConfirm(artistname); + sendRequest.addNewArtist(artistname); } @RequestMapping ("/clickArtistDelete") public void clickArtistDelete() { - sendRequest.artistClickDelete(); + sendRequest.deleteArtist(); } @PostMapping("/deleteUrl") public void deleteUrl() { - sendRequest.deleteUrl(); + sendRequest.deleteSourceID(); } @RequestMapping ("/cleanArtistSource") @@ -74,7 +74,7 @@ public void saveUrl() { @PostMapping ("/clickAddURL") public void clickAddURL(@RequestBody String url) { url = URLDecoder.decode(url, StandardCharsets.UTF_8).replace("=" , "").trim(); - sendRequest.clickAddURL(url); + sendRequest.scrapePreview(url); } @RequestMapping ("/clickScrape") diff --git a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java index 5e3671b..3d3941b 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java @@ -3,12 +3,11 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.DataModels.TableModel; +import com.blck.MusicReleaseTracker.DataObjects.TableModel; import com.blck.MusicReleaseTracker.Scraping.ScrapeProcess; import com.blck.MusicReleaseTracker.Scraping.Scrapers.*; import org.springframework.beans.factory.annotation.Autowired; -import java.sql.*; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -38,7 +37,6 @@ public class GUIController { private final ConfigTools config; private final DBtools DB; private final ManageMigrateDB manageDB; - private final List tableContent = new ArrayList<>(); private SourcesEnum selectedSource; private String lastClickedArtist; private String tempID; @@ -61,151 +59,53 @@ public void setTestData(String lastClickedArtist, SourcesEnum selectedSource) { } public List loadList() { - List dataList = new ArrayList<>(); - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery("SELECT artistname FROM artists ORDER BY artistname LIMIT 500"); - while (rs.next()) { - dataList.add(rs.getString("artistname")); - } - stmt.close(); - rs.close(); - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error loading list"); - } - return dataList; + return DB.getArtistList(); } - public void artistAddConfirm(String input) { - // add new artist typed by user - if (input.isEmpty() || input.isBlank()) + public void addNewArtist(String name) { + if (name.isEmpty() || name.isBlank()) return; - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "INSERT INTO artists (artistname) values(?)"; - PreparedStatement pstmt = conn.prepareStatement(sql); - pstmt.setString(1, input); - pstmt.executeUpdate(); - pstmt.close(); - lastClickedArtist = null; - } catch (SQLException e) { - System.out.println("artist already exists"); - } + DB.insertIntoArtistList(name); + lastClickedArtist = null; } - public void artistClickDelete() { - // delete last selected artist and all entries from artist - if (lastClickedArtist != null) { - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - Map> tableMap = manageDB.getDBStructure(store.getDBpath()); - String sql; - for (String tableName : tableMap.keySet()) { - if (tableName.equals("artists")) - sql = "DELETE FROM artists WHERE artistname = ?"; - else - sql = "DELETE FROM " + tableName + " WHERE artist = ?"; - PreparedStatement pstmt = conn.prepareStatement(sql); - pstmt.setString(1, lastClickedArtist); - pstmt.executeUpdate(); - } - lastClickedArtist = null; - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.WARNING, "error deleting an artist"); - } - } + public void deleteArtist() { + if (lastClickedArtist == null) + return; + DB.removeArtist(lastClickedArtist); + lastClickedArtist = null; } - public void deleteUrl() { - // set null specific URL, delete related set + public void deleteSourceID() { if (lastClickedArtist != null && selectedSource != null) { - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "UPDATE artists SET url" + selectedSource + " = NULL WHERE artistname = ?"; - PreparedStatement pstmt = conn.prepareStatement(sql); - pstmt.setString(1, lastClickedArtist); - pstmt.executeUpdate(); - sql = "DELETE FROM " + selectedSource + " WHERE artist = ?"; - pstmt = conn.prepareStatement(sql); - pstmt.setString(1, lastClickedArtist); - pstmt.execute(); - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error deleting an URL"); - } + DB.updateArtistSourceID(lastClickedArtist, selectedSource, null); + DB.clearArtistDataFrom(lastClickedArtist, selectedSource.toString()); } } public void cleanArtistSource() { - // clear artist entries from a source table, used by scrape preview - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "DELETE FROM " + selectedSource + " WHERE artist = ?"; - PreparedStatement pstmt = conn.prepareStatement(sql); - pstmt.setString(1, lastClickedArtist); - pstmt.executeUpdate(); - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error deleting a source URL"); - } + DB.clearArtistDataFrom(selectedSource.toString(), lastClickedArtist); } - public List listOrTabClick(String item, String origin) { - // when source or artist selected, load respective table + public List getTableData(String item, String origin) { if (origin.equals("list")) lastClickedArtist = item; else if (origin.equals("tab")) - // need to account for combview selectedSource = item.equals("combview") ? null : SourcesEnum.valueOf(item); if (selectedSource == null) - loadCombviewTable(); + return DB.loadCombviewTable(); else if (lastClickedArtist != null) - loadTable(); - - return tableContent; - } - - public void loadTable() { - tableContent.clear(); - // adding data to tableContent - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "SELECT song, date FROM " + selectedSource + " WHERE artist = ? ORDER BY date DESC LIMIT 100"; - PreparedStatement pstmt = conn.prepareStatement(sql); - pstmt.setString(1, lastClickedArtist); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - String songsCol = rs.getString("song"); - String datesCol = rs.getString("date"); - tableContent.add(new TableModel(songsCol, null, datesCol)); - } - pstmt.close(); - rs.close(); - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error loading table"); - } - } + return DB.loadTable(selectedSource, lastClickedArtist); - public void loadCombviewTable() { - tableContent.clear(); - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - // populating combview table - String sql = "SELECT song, artist, date FROM combview ORDER BY date DESC, artist, song LIMIT 1000"; - PreparedStatement pstmt = conn.prepareStatement(sql); - ResultSet rs = pstmt.executeQuery(); - while (rs.next()) { - String songsCol = rs.getString("song"); - String artistsCol = rs.getString("artist"); - String datesCol = rs.getString("date"); - tableContent.add(new TableModel(songsCol, artistsCol, datesCol)); - } - pstmt.close(); - rs.close(); - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error loading combview table"); - } + return null; } public void fillCombview() { scrapeProcess.fillCombviewTable(); } - public void clickAddURL(String url) { - // scrape preview functionality + public void scrapePreview(String url) { if (lastClickedArtist == null || selectedSource == null || url.isBlank()) return; @@ -229,60 +129,22 @@ public void clickAddURL(String url) { } public void saveUrl() { - // save artist url to db - String sql = "UPDATE artists SET url" + selectedSource + " = ? WHERE artistname = ?"; - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - PreparedStatement pstmt = conn.prepareStatement(sql); - pstmt.setString(1, tempID); - pstmt.setString(2, lastClickedArtist); - pstmt.executeUpdate(); - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.WARNING, "could not save URL"); - } + DB.updateArtistSourceID(lastClickedArtist, selectedSource, tempID); } public boolean checkExistURL() { - // check for existence of url to determine visibility of url dialog - boolean urlExists = false; try { SourcesEnum.valueOf(String.valueOf(selectedSource)); } catch (IllegalArgumentException e) { - return urlExists; - } - - String sql = "SELECT url" + selectedSource + " FROM artists WHERE artistname = ? LIMIT 10"; - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - PreparedStatement pstmt = conn.prepareStatement(sql); - pstmt.setString(1, lastClickedArtist); - ResultSet rs = pstmt.executeQuery(); - - if (rs.getString(1) != null) - urlExists = true; - - rs.close(); - pstmt.close(); - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.WARNING, "error checking url existence"); + return false; } - return urlExists; + return DB.getArtistSourceID(lastClickedArtist, selectedSource) != null; } public void clickScrape() { - // launch scraping in backend, then fill and load table scrapeProcess.scrapeData(); scrapeProcess.fillCombviewTable(); - vacuum(); - } - - public void vacuum() { - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "VACUUM;"; - PreparedStatement pstmt = conn.prepareStatement(sql); - pstmt.execute(); - pstmt.close(); - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.WARNING, "vacuum error: clickScrape"); - } + DB.vacuum(); } public void cancelScrape() { diff --git a/src/main/java/com/blck/MusicReleaseTracker/ManageMigrateDB.java b/src/main/java/com/blck/MusicReleaseTracker/ManageMigrateDB.java index 74bf6f0..ad8c4ee 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/ManageMigrateDB.java +++ b/src/main/java/com/blck/MusicReleaseTracker/ManageMigrateDB.java @@ -80,7 +80,7 @@ CREATE TABLE IF NOT EXISTS youtube ( sql = """ CREATE TABLE IF NOT EXISTS artists ( - artistname text PRIMARY KEY, + artist text PRIMARY KEY, urlmusicbrainz text, urlbeatport text, urljunodownload text, @@ -134,12 +134,12 @@ public void migrateDB() { Connection connDB = DriverManager.getConnection(store.getDBpath()); Connection connDBtemplate = DriverManager.getConnection(DBtemplatePath) ) { - // insert data from musicdata's column to template's column + // insert data from musicdata column to template column String sql = "SELECT * FROM artists LIMIT 1000"; Statement stmt = connDB.createStatement(); ResultSet rs = stmt.executeQuery(sql); - sql = "insert into artists(artistname, urlmusicbrainz, urlbeatport, urljunodownload, urlyoutube) values(?, ?, ?, ?, ?)"; + sql = "insert into artists(artist, urlmusicbrainz, urlbeatport, urljunodownload, urlyoutube) values(?, ?, ?, ?, ?)"; PreparedStatement pstmt = connDBtemplate.prepareStatement(sql); ArrayList columnList = DBMap.get("artists"); // cycling table rows @@ -174,7 +174,7 @@ public void migrateDB() { } public Map> getDBStructure(String path) { - // assembles a structure of tables and their columns + // returns a structure of tables and their columns HashMap> tableMap = new HashMap<>(); try (Connection conn = DriverManager.getConnection(path)) { diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java index 8fea3ac..46032f5 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java @@ -6,7 +6,7 @@ import com.blck.MusicReleaseTracker.Core.ValueStore; import com.blck.MusicReleaseTracker.DBtools; import com.blck.MusicReleaseTracker.FrontendAPI.SSEController; -import com.blck.MusicReleaseTracker.DataModels.Song; +import com.blck.MusicReleaseTracker.DataObjects.Song; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -56,7 +56,7 @@ public ScrapeProcess(ValueStore valueStore, ErrorLogging errorLogging, ConfigToo public void scrapeData() { config.readConfig(ConfigTools.configOptions.longTimeout); scrapeCancel = false; - DB.truncateDB(); + DB.truncateAllScrapeData(); ScraperController scrapers = new ScraperController(store, log); final int initSize = scrapers.getInitSize(); // triggering scrapers diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperController.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperController.java index af4fc01..8a2289e 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperController.java @@ -21,15 +21,15 @@ public ScraperController(ValueStore store, ErrorLogging log) { this.log = log; // creating a list of scraper objects: one scraper holds one URL try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "SELECT artistname FROM artists LIMIT 500"; + String sql = "SELECT artist FROM artists LIMIT 500"; PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet artistResults = pstmt.executeQuery(); // cycling artists while (artistResults.next()) { - String artist = artistResults.getString("artistname"); + String artist = artistResults.getString("artist"); // cycling sources for (SourcesEnum webSource : SourcesEnum.values()) { - sql = "SELECT * FROM artists WHERE artistname = ? LIMIT 100"; + sql = "SELECT * FROM artists WHERE artist = ? LIMIT 100"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, artist); ResultSet rs = pstmt.executeQuery(); diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java index b50fc5f..32424f9 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java @@ -4,7 +4,7 @@ import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; -import com.blck.MusicReleaseTracker.DataModels.Song; +import com.blck.MusicReleaseTracker.DataObjects.Song; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java index c9e307d..9391422 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java @@ -4,7 +4,7 @@ import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; -import com.blck.MusicReleaseTracker.DataModels.Song; +import com.blck.MusicReleaseTracker.DataObjects.Song; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java index ad07760..d295cc7 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java @@ -3,7 +3,7 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; -import com.blck.MusicReleaseTracker.DataModels.Song; +import com.blck.MusicReleaseTracker.DataObjects.Song; import com.blck.MusicReleaseTracker.Core.ValueStore; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java index 2eedbf4..9d573b8 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java @@ -3,7 +3,7 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; -import com.blck.MusicReleaseTracker.DataModels.Song; +import com.blck.MusicReleaseTracker.DataObjects.Song; import com.blck.MusicReleaseTracker.Core.ValueStore; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperYoutube.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperYoutube.java index 89ad395..04ecc14 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperYoutube.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperYoutube.java @@ -3,7 +3,7 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; -import com.blck.MusicReleaseTracker.DataModels.Song; +import com.blck.MusicReleaseTracker.DataObjects.Song; import com.blck.MusicReleaseTracker.Core.ValueStore; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; diff --git a/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java b/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java index c7686b5..668cfa2 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java +++ b/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java @@ -46,16 +46,20 @@ else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) private void createDirs() { String appDataPath = store.getAppDataPath(); - File folder = new File(appDataPath); - if (!folder.exists()) - folder.mkdirs(); - // junk folder because sqlite did not delete temp files in "temp" - File tempfolder = new File(appDataPath + "temp"); - if (!tempfolder.exists()) - tempfolder.mkdirs(); - for (File file : tempfolder.listFiles()) - file.delete(); - System.setProperty("org.sqlite.tmpdir", appDataPath + "temp"); + try { + File folder = new File(appDataPath); + if (!folder.exists()) + folder.mkdirs(); + // junk folder because sqlite did not delete temp files in "temp" + File tempfolder = new File(appDataPath + "temp"); + if (!tempfolder.exists()) + tempfolder.mkdirs(); + for (File file : tempfolder.listFiles()) + file.delete(); + System.setProperty("org.sqlite.tmpdir", appDataPath + "temp"); + } catch (Exception e) { + log.error(e, ErrorLogging.Severity.WARNING, "something went wrong in directory setup"); + } } } diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index ce09c16..366d43b 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -18,7 +18,7 @@ exports com.blck.MusicReleaseTracker.Scraping; exports com.blck.MusicReleaseTracker.FrontendAPI; opens com.blck.MusicReleaseTracker.FrontendAPI; - exports com.blck.MusicReleaseTracker.DataModels; - opens com.blck.MusicReleaseTracker.DataModels; + exports com.blck.MusicReleaseTracker.DataObjects; + opens com.blck.MusicReleaseTracker.DataObjects; } diff --git a/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest.java b/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest.java index 15aa66b..2ef7f88 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest.java @@ -16,7 +16,7 @@ public void setUp() { testDBpath = "jdbc:sqlite:" + Paths.get("src", "test", "testresources", "testdb.db"); store = new ValueStore(); store.setDBpath(testDBpath); - dBtools = new DBtools(store, null); + dBtools = new DBtools(store, null, null); } diff --git a/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java b/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java index 1a68aba..79629cd 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java @@ -34,7 +34,7 @@ void setUp() { DBpath = "jdbc:sqlite:" + Paths.get("src", "test", "testresources", "testdb.db"); store = new ValueStore(); store.setDBpath(DBpath); - DB = new DBtools(store, null); + DB = new DBtools(store, null, null); guiController = new GUIController(store, null, null, null, DB, null); guiController.setTestData("Joe", SourcesEnum.beatport); } diff --git a/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java b/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java index ed63c41..e73fcde 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java @@ -1,7 +1,7 @@ package com.blck.MusicReleaseTracker; import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.DataModels.Song; +import com.blck.MusicReleaseTracker.DataObjects.Song; import com.blck.MusicReleaseTracker.Scraping.ScrapeProcess; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; @@ -30,7 +30,7 @@ public class ScrapeProcessTest { private ValueStore store = new ValueStore(); - private DBtools DB = new DBtools(store, null); + private DBtools DB = new DBtools(store, null, null); private ScrapeProcess scrapeProcess; private ArrayList expectedList; diff --git a/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java b/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java index dc75f61..cfef32c 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java @@ -1,7 +1,7 @@ package com.blck.MusicReleaseTracker.Scrapers; import com.blck.MusicReleaseTracker.Scraping.Scrapers.*; -import com.blck.MusicReleaseTracker.DataModels.Song; +import com.blck.MusicReleaseTracker.DataObjects.Song; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; From 564b9119004a15de8f90bd0d69d5632877fda6a7 Mon Sep 17 00:00:00 2001 From: BLCK <123077751+BLCK-B@users.noreply.github.com> Date: Wed, 15 May 2024 15:59:22 +0200 Subject: [PATCH 07/22] more refactoring, separated DB from scrapeProcess --- .../MusicReleaseTracker/Core/BeanConfig.java | 17 +-- .../{DBtools.java => DBqueries.java} | 98 +++++++++++++-- .../MusicReleaseTracker/GUIController.java | 49 ++++---- .../Scraping/ScrapeProcess.java | 119 +++--------------- ...perController.java => ScraperManager.java} | 18 +-- .../Scraping/Scrapers/Scraper.java | 50 +------- .../Scraping/Scrapers/ScraperBeatport.java | 9 +- .../Scraping/Scrapers/ScraperInterface.java | 2 +- .../Scrapers/ScraperJunodownload.java | 9 +- .../Scraping/Scrapers/ScraperMusicbrainz.java | 9 +- .../Scraping/Scrapers/ScraperYoutube.java | 9 +- src/main/java/module-info.java | 1 + .../blck/MusicReleaseTracker/DBToolsTest.java | 4 +- .../GUIControllerTest.java | 7 +- .../blck/MusicReleaseTracker/HelperDB.java | 2 +- .../ScrapeProcessTest.java | 2 +- 16 files changed, 183 insertions(+), 222 deletions(-) rename src/main/java/com/blck/MusicReleaseTracker/{DBtools.java => DBqueries.java} (63%) rename src/main/java/com/blck/MusicReleaseTracker/Scraping/{ScraperController.java => ScraperManager.java} (90%) diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java b/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java index bd8501d..5d5d903 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java @@ -23,20 +23,15 @@ public ErrorLogging errorLogging(ValueStore store) { } @Bean - public ScrapeProcess scrapeProcess(ValueStore valueStore, ErrorLogging errorLogging, ConfigTools configTools, DBtools dBtools, SSEController sseController) { - return new ScrapeProcess(valueStore, errorLogging, configTools, dBtools, sseController); - } - - @Bean - public Scraper scraperParent(ValueStore valueStore, ErrorLogging errorLogging) { - return new Scraper(valueStore, errorLogging); + public ScrapeProcess scrapeProcess(ValueStore valueStore, ErrorLogging errorLogging, ConfigTools configTools, DBqueries dBqueries, SSEController sseController) { + return new ScrapeProcess(valueStore, errorLogging, configTools, dBqueries, sseController); } @Bean public GUIController guiController(ValueStore valueStore, ErrorLogging errorLogging, ScrapeProcess scrapeProcess, ConfigTools config, - ManageMigrateDB manageMigrateDB, DBtools dBtools) { - return new GUIController(valueStore, errorLogging, scrapeProcess, config, dBtools, manageMigrateDB); + ManageMigrateDB manageMigrateDB, DBqueries dBqueries) { + return new GUIController(valueStore, errorLogging, scrapeProcess, config, dBqueries, manageMigrateDB); } @Bean @@ -50,8 +45,8 @@ public ManageMigrateDB manageMigrateDB(ValueStore valueStore, ErrorLogging error } @Bean - public DBtools dBtools(ValueStore valueStore, ErrorLogging errorLogging, ManageMigrateDB manageMigrateDB) { - return new DBtools(valueStore, errorLogging, manageMigrateDB); + public DBqueries dBqueries(ValueStore valueStore, ErrorLogging errorLogging, ManageMigrateDB manageMigrateDB) { + return new DBqueries(valueStore, errorLogging, manageMigrateDB); } @Bean diff --git a/src/main/java/com/blck/MusicReleaseTracker/DBtools.java b/src/main/java/com/blck/MusicReleaseTracker/DBqueries.java similarity index 63% rename from src/main/java/com/blck/MusicReleaseTracker/DBtools.java rename to src/main/java/com/blck/MusicReleaseTracker/DBqueries.java index 62539b8..003b529 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/DBtools.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DBqueries.java @@ -3,6 +3,7 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; +import com.blck.MusicReleaseTracker.DataObjects.Song; import com.blck.MusicReleaseTracker.DataObjects.TableModel; import org.springframework.beans.factory.annotation.Autowired; @@ -23,14 +24,14 @@ You should have received a copy of the GNU General Public License along with this program. If not, see .*/ -public class DBtools { +public class DBqueries { private final ValueStore store; private final ErrorLogging log; private final ManageMigrateDB manageDB; @Autowired - public DBtools(ValueStore valueStore, ErrorLogging errorLogging, ManageMigrateDB manageDB) { + public DBqueries(ValueStore valueStore, ErrorLogging errorLogging, ManageMigrateDB manageDB) { this.store = valueStore; this.log = errorLogging; this.manageDB = manageDB; @@ -156,12 +157,14 @@ public void removeArtist(String name) { clearArtistDataFrom(name, tableName); } - public void truncateAllScrapeData() { + public void truncateScrapeData(boolean all) { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - for (SourcesEnum sourceTable : SourcesEnum.values()) { - String sql = "DELETE FROM " + sourceTable; - Statement stmt = conn.createStatement(); - stmt.executeUpdate(sql); + if (all) { + for (SourcesEnum sourceTable : SourcesEnum.values()) { + String sql = "DELETE FROM " + sourceTable; + Statement stmt = conn.createStatement(); + stmt.executeUpdate(sql); + } } String sql = "DELETE FROM combview"; Statement stmt = conn.createStatement(); @@ -171,6 +174,87 @@ public void truncateAllScrapeData() { } } + public ArrayList getAllSourceTableData() { + // song object list with data from all sources + ArrayList songObjectList = new ArrayList<>(); + try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + for (SourcesEnum source : SourcesEnum.values()) { + String sql = "SELECT * FROM " + source + " ORDER BY date DESC LIMIT 200"; + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sql); + while (rs.next()) { + String songName = rs.getString("song"); + String songArtist = rs.getString("artist"); + String songDate = rs.getString("date"); + String songType = null; + if (source == SourcesEnum.beatport) + songType = rs.getString("type"); + + if (filterWords(songName, songType)) { + switch (source) { + case beatport -> + songObjectList.add(new Song(songName, songArtist, songDate, songType)); + case musicbrainz, junodownload, youtube -> + songObjectList.add(new Song(songName, songArtist, songDate)); + } + } + } + } + } catch (Exception e) { + log.error(e, ErrorLogging.Severity.WARNING, "error filtering keywords"); + } + return songObjectList; + } + + private boolean filterWords(String songName, String songType) { + // filtering user-selected keywords + for (String checkword : store.getFilterWords()) { + if (songType != null) { + if ((songType.toLowerCase()).contains(checkword.toLowerCase())) + return false; + } + if ((songName.toLowerCase()).contains(checkword.toLowerCase())) + return false; + } + return true; + } + + public void batchInsertSongs(ArrayList songList, SourcesEnum source, int limit) { + try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + int i = 0; + String sql; + PreparedStatement pstmt = null; + for (Song songObject : songList) { + if (i == limit) + break; + if (songObject.getType() != null && source != null) { + sql = "insert into " + source + "(song, artist, date, type) values(?, ?, ?, ?)"; + pstmt = conn.prepareStatement(sql); + pstmt.setString(1, songObject.getName()); + pstmt.setString(2, songObject.getArtist()); + pstmt.setString(3, songObject.getDate()); + pstmt.setString(4, songObject.getType()); + } else { + if (source != null) + sql = "insert into " + source + "(song, artist, date) values(?, ?, ?)"; + else + sql = "insert into combview(song, artist, date) values(?, ?, ?)"; + pstmt = conn.prepareStatement(sql); + pstmt.setString(1, songObject.getName()); + pstmt.setString(2, songObject.getArtist()); + pstmt.setString(3, songObject.getDate()); + } + pstmt.executeUpdate(); + i++; + } + conn.setAutoCommit(false); + conn.commit(); + conn.setAutoCommit(true); + } catch (SQLException e) { + log.error(e, ErrorLogging.Severity.SEVERE, "error inserting a set of songs"); + } + } + public void vacuum() { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { String sql = "VACUUM;"; diff --git a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java index 3d3941b..fa8bf5a 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java @@ -35,15 +35,16 @@ public class GUIController { private final ErrorLogging log; private final ScrapeProcess scrapeProcess; private final ConfigTools config; - private final DBtools DB; + private final DBqueries DB; private final ManageMigrateDB manageDB; + private SourcesEnum selectedSource; - private String lastClickedArtist; + private String selectedArtist; private String tempID; @Autowired public GUIController(ValueStore valueStore, ErrorLogging errorLogging, ScrapeProcess scrapeProcess, - ConfigTools config, DBtools DB, ManageMigrateDB manageDB) { + ConfigTools config, DBqueries DB, ManageMigrateDB manageDB) { this.store = valueStore; this.log = errorLogging; this.scrapeProcess = scrapeProcess; @@ -53,7 +54,7 @@ public GUIController(ValueStore valueStore, ErrorLogging errorLogging, ScrapePro } public void setTestData(String lastClickedArtist, SourcesEnum selectedSource) { - this.lastClickedArtist = lastClickedArtist; + this.selectedArtist = lastClickedArtist; this.selectedSource = selectedSource; tempID = "testingUrl"; } @@ -66,37 +67,37 @@ public void addNewArtist(String name) { if (name.isEmpty() || name.isBlank()) return; DB.insertIntoArtistList(name); - lastClickedArtist = null; + selectedArtist = null; } public void deleteArtist() { - if (lastClickedArtist == null) + if (selectedArtist == null) return; - DB.removeArtist(lastClickedArtist); - lastClickedArtist = null; + DB.removeArtist(selectedArtist); + selectedArtist = null; } public void deleteSourceID() { - if (lastClickedArtist != null && selectedSource != null) { - DB.updateArtistSourceID(lastClickedArtist, selectedSource, null); - DB.clearArtistDataFrom(lastClickedArtist, selectedSource.toString()); + if (selectedArtist != null && selectedSource != null) { + DB.updateArtistSourceID(selectedArtist, selectedSource, null); + DB.clearArtistDataFrom(selectedArtist, selectedSource.toString()); } } public void cleanArtistSource() { - DB.clearArtistDataFrom(selectedSource.toString(), lastClickedArtist); + DB.clearArtistDataFrom(selectedSource.toString(), selectedArtist); } public List getTableData(String item, String origin) { if (origin.equals("list")) - lastClickedArtist = item; + selectedArtist = item; else if (origin.equals("tab")) selectedSource = item.equals("combview") ? null : SourcesEnum.valueOf(item); if (selectedSource == null) return DB.loadCombviewTable(); - else if (lastClickedArtist != null) - return DB.loadTable(selectedSource, lastClickedArtist); + else if (selectedArtist != null) + return DB.loadTable(selectedSource, selectedArtist); return null; } @@ -106,7 +107,7 @@ public void fillCombview() { } public void scrapePreview(String url) { - if (lastClickedArtist == null || selectedSource == null || url.isBlank()) + if (selectedArtist == null || selectedSource == null || url.isBlank()) return; tempID = null; @@ -114,13 +115,13 @@ public void scrapePreview(String url) { try { Scraper scraper = null; switch (selectedSource) { - case musicbrainz -> scraper = new ScraperMusicbrainz(store, log, lastClickedArtist, url); - case beatport -> scraper = new ScraperBeatport(store, log, lastClickedArtist, url); - case junodownload -> scraper = new ScraperJunodownload(store, log, lastClickedArtist, url); - case youtube -> scraper = new ScraperYoutube(store, log, lastClickedArtist, url); + case musicbrainz -> scraper = new ScraperMusicbrainz(log, DB, selectedArtist, url); + case beatport -> scraper = new ScraperBeatport(log, DB, selectedArtist, url); + case junodownload -> scraper = new ScraperJunodownload(log, DB, selectedArtist, url); + case youtube -> scraper = new ScraperYoutube(log, DB, selectedArtist, url); } id = scraper.getID(); - scraper.scrape(); + scraper.scrape(store.getTimeout()); } catch (Exception e) { log.error(e, ErrorLogging.Severity.WARNING, "error scraping " + selectedSource + ", perhaps an incorrect link"); } @@ -129,7 +130,7 @@ public void scrapePreview(String url) { } public void saveUrl() { - DB.updateArtistSourceID(lastClickedArtist, selectedSource, tempID); + DB.updateArtistSourceID(selectedArtist, selectedSource, tempID); } public boolean checkExistURL() { @@ -138,7 +139,7 @@ public boolean checkExistURL() { } catch (IllegalArgumentException e) { return false; } - return DB.getArtistSourceID(lastClickedArtist, selectedSource) != null; + return DB.getArtistSourceID(selectedArtist, selectedSource) != null; } public void clickScrape() { @@ -195,7 +196,7 @@ public String getScrapeDate() { } public String getLastArtist() { - return lastClickedArtist; + return selectedArtist; } public void resetSettings() { diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java index 46032f5..88d1242 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java @@ -2,15 +2,13 @@ import com.blck.MusicReleaseTracker.ConfigTools; import com.blck.MusicReleaseTracker.Core.ErrorLogging; -import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.DBtools; +import com.blck.MusicReleaseTracker.DBqueries; import com.blck.MusicReleaseTracker.FrontendAPI.SSEController; import com.blck.MusicReleaseTracker.DataObjects.Song; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.sql.*; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -39,11 +37,11 @@ public class ScrapeProcess { private final ValueStore store; private final ErrorLogging log; private final ConfigTools config; - private final DBtools DB; + private final DBqueries DB; private final SSEController SSE; @Autowired - public ScrapeProcess(ValueStore valueStore, ErrorLogging errorLogging, ConfigTools configTools, DBtools DB, SSEController sseController) { + public ScrapeProcess(ValueStore valueStore, ErrorLogging errorLogging, ConfigTools configTools, DBqueries DB, SSEController sseController) { this.store = valueStore; this.log = errorLogging; this.config = configTools; @@ -56,82 +54,38 @@ public ScrapeProcess(ValueStore valueStore, ErrorLogging errorLogging, ConfigToo public void scrapeData() { config.readConfig(ConfigTools.configOptions.longTimeout); scrapeCancel = false; - DB.truncateAllScrapeData(); - ScraperController scrapers = new ScraperController(store, log); + DB.truncateScrapeData(true); + ScraperManager scrapers = new ScraperManager(store, log, DB); final int initSize = scrapers.getInitSize(); - // triggering scrapers int remaining = 0; double progress = 0.0; while (remaining != -1) { SSE.sendProgress(progress); - if (scrapeCancel) { - SSE.sendProgress(1.0); - System.gc(); - return; - } + if (scrapeCancel) + break; remaining = scrapers.scrapeNext(); progress = ((double) initSize - (double) remaining) / (double) initSize; } + SSE.sendProgress(1.0); System.gc(); } public void fillCombviewTable() { ArrayList songObjectList = prepareSongs(); - List finalSortedList = processSongs(songObjectList); - insertIntoCombview(finalSortedList); + ArrayList finalSortedList = processSongs(songObjectList); + DB.batchInsertSongs(finalSortedList, null, 115); + System.gc(); } public ArrayList prepareSongs() { - // assembles table for combined view: filters unwanted words, looks for duplicates - // load filterwords and entrieslimit if (!store.getDBpath().contains("testdb")) config.readConfig(ConfigTools.configOptions.filters); - // clear table - String sql = null; - Statement stmt = null; - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - sql = "DELETE FROM combview"; - stmt = conn.createStatement(); - stmt.executeUpdate(sql); - } catch (Exception e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error cleaning combview table"); - } - - // song object list with data from all sources - ArrayList songObjectList = new ArrayList<>(); - - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - for (SourcesEnum source : SourcesEnum.values()) { - // limit defines max combview rows - sql = "SELECT * FROM " + source + " ORDER BY date DESC LIMIT 200"; - stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(sql); - while (rs.next()) { - String songName = rs.getString("song"); - String songArtist = rs.getString("artist"); - String songDate = rs.getString("date"); - String songType = null; - if (source == SourcesEnum.beatport) - songType = rs.getString("type"); - if (filterWords(songName, songType)) { - switch (source) { - case beatport -> - songObjectList.add(new Song(songName, songArtist, songDate, songType)); - case musicbrainz, junodownload, youtube -> - songObjectList.add(new Song(songName, songArtist, songDate)); - } - } - } - } - stmt.close(); - } catch (Exception e) { - log.error(e, ErrorLogging.Severity.WARNING, "error filtering keywords"); - } - return songObjectList; + DB.truncateScrapeData(false); + return DB.getAllSourceTableData(); } - public List processSongs(List songObjectList) { + public ArrayList processSongs(List songObjectList) { // map songObjectList to get rid of name-artist duplicates, prefer older, example key: neverenoughbensley // eg: Never Enough - Bensley - 2023-05-12 : Never Enough - Bensley - 2022-12-16 = Never Enough - Bensley - 2022-12-16 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); @@ -166,9 +120,9 @@ public List processSongs(List songObjectList) { } )); // create a list of SongClass objects from map, sorted by date - List finalSortedList = nameDateMap.values().stream() + ArrayList finalSortedList = nameDateMap.values().stream() .sorted(Comparator.comparing(Song::getDate, Comparator.reverseOrder())) - .toList(); + .collect(Collectors.toCollection(ArrayList::new)); songObjectList = null; nameDateMap = null; @@ -177,45 +131,4 @@ public List processSongs(List songObjectList) { return finalSortedList; } - private void insertIntoCombview(List finalSortedList) { - // insert data into table - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "insert into combview(song, artist, date) values(?, ?, ?)"; - PreparedStatement pstmt = conn.prepareStatement(sql); - // precomitting batch insert is way faster - int i = 0; - for (Song item : finalSortedList) { - // table size limit - if (i == 115) - break; - pstmt.setString(1, item.getName()); - pstmt.setString(2, item.getArtist()); - pstmt.setString(3, item.getDate()); - pstmt.addBatch(); - i++; - } - conn.setAutoCommit(false); - pstmt.executeBatch(); - conn.commit(); - conn.setAutoCommit(true); - pstmt.close(); - } catch (Exception e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error inserting data to combview"); - } - System.gc(); - } - - public boolean filterWords(String songName, String songType) { - // filtering user-selected keywords - for (String checkword : store.getFilterWords()) { - if (songType != null) { - if ((songType.toLowerCase()).contains(checkword.toLowerCase())) - return false; - } - if ((songName.toLowerCase()).contains(checkword.toLowerCase())) - return false; - } - return true; - } - } \ No newline at end of file diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperController.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperManager.java similarity index 90% rename from src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperController.java rename to src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperManager.java index 8a2289e..f5cf944 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperManager.java @@ -3,22 +3,26 @@ import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; import com.blck.MusicReleaseTracker.Core.ErrorLogging; +import com.blck.MusicReleaseTracker.DBqueries; import com.blck.MusicReleaseTracker.Scraping.Scrapers.*; +import org.sqlite.core.DB; import java.sql.*; import java.util.*; -public class ScraperController { +public class ScraperManager { private final ValueStore store; private final ErrorLogging log; + private final DBqueries DB; private final int initSize; private final LinkedList scrapers = new LinkedList<>(); private final HashMap sourceTimes = new HashMap<>(); // middleware abstraction for scraping with exception handling - public ScraperController(ValueStore store, ErrorLogging log) { + public ScraperManager(ValueStore store, ErrorLogging log, DBqueries DB) { this.store = store; this.log = log; + this.DB = DB; // creating a list of scraper objects: one scraper holds one URL try (Connection conn = DriverManager.getConnection(store.getDBpath())) { String sql = "SELECT artist FROM artists LIMIT 500"; @@ -37,10 +41,10 @@ public ScraperController(ValueStore store, ErrorLogging log) { if (url == null) continue; switch (webSource) { - case musicbrainz -> scrapers.add(new ScraperMusicbrainz(store, log, artist, url)); - case beatport -> scrapers.add(new ScraperBeatport(store, log, artist, url)); - case junodownload -> scrapers.add(new ScraperJunodownload(store, log, artist, url)); - case youtube -> scrapers.add(new ScraperYoutube(store, log, artist, url)); + case musicbrainz -> scrapers.add(new ScraperMusicbrainz(log, DB, artist, url)); + case beatport -> scrapers.add(new ScraperBeatport(log, DB, artist, url)); + case junodownload -> scrapers.add(new ScraperJunodownload(log, DB, artist, url)); + case youtube -> scrapers.add(new ScraperYoutube(log, DB, artist, url)); } } } @@ -66,7 +70,7 @@ public int scrapeNext() { Scraper scraper = scrapers.get(0); for (int i = 0; i <= 2; i++) { try { - scraper.scrape(); + scraper.scrape(store.getTimeout()); break; // exception = will not break } catch (ScraperTimeoutException e) { diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java index 32424f9..d36aebb 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java @@ -2,16 +2,10 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; -import com.blck.MusicReleaseTracker.Core.ValueStore; +import com.blck.MusicReleaseTracker.DBqueries; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; import com.blck.MusicReleaseTracker.DataObjects.Song; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.SQLException; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; @@ -20,21 +14,19 @@ import java.util.HashSet; import java.util.Set; -@Component public class Scraper { - protected final ValueStore store; protected final ErrorLogging log; + private final DBqueries DB; public ArrayList songList = new ArrayList<>(); public SourcesEnum source; - @Autowired - public Scraper(ValueStore valueStore, ErrorLogging errorLogging) { - this.store = valueStore; + public Scraper(ErrorLogging errorLogging, DBqueries DB) { this.log = errorLogging; + this.DB = DB; } - public void scrape() throws ScraperTimeoutException { + public void scrape(int timeout) throws ScraperTimeoutException { System.out.println("The method scrape() is to be overriden."); } @@ -95,36 +87,6 @@ public void sortByDateDescending() { } public void insertSet() { - PreparedStatement pstmt = null; - // insert a set of songs to a source table - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - int i = 0; - for (Song songObject : songList) { - if (i == 15) - break; - if (songObject.getType() != null) { - String sql = "insert into " + source + "(song, artist, date, type) values(?, ?, ?, ?)"; - pstmt = conn.prepareStatement(sql); - pstmt.setString(1, songObject.getName()); - pstmt.setString(2, songObject.getArtist()); - pstmt.setString(3, songObject.getDate()); - pstmt.setString(4, songObject.getType()); - } else { - String sql = "insert into " + source + "(song, artist, date) values(?, ?, ?)"; - pstmt = conn.prepareStatement(sql); - pstmt.setString(1, songObject.getName()); - pstmt.setString(2, songObject.getArtist()); - pstmt.setString(3, songObject.getDate()); - } - pstmt.executeUpdate(); - i++; - } - conn.setAutoCommit(false); - conn.commit(); - conn.setAutoCommit(true); - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error inserting a set of songs"); - } + DB.batchInsertSongs(songList, source, 15); } - } diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java index 9391422..b2cae16 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java @@ -3,6 +3,7 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; +import com.blck.MusicReleaseTracker.DBqueries; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; import com.blck.MusicReleaseTracker.DataObjects.Song; import org.jsoup.Jsoup; @@ -20,8 +21,8 @@ public final class ScraperBeatport extends Scraper implements ScraperInterface { private final String songArtist; private String id; private final boolean isIDnull; - public ScraperBeatport(ValueStore store, ErrorLogging log, String songArtist, String id) { - super(store, log); + public ScraperBeatport(ErrorLogging log, DBqueries DB, String songArtist, String id) { + super(log, DB); this.songArtist = songArtist; this.id = id; @@ -29,7 +30,7 @@ public ScraperBeatport(ValueStore store, ErrorLogging log, String songArtist, St reduceToID(); } @Override - public void scrape() throws ScraperTimeoutException { + public void scrape(int timeout) throws ScraperTimeoutException { if (isIDnull) return; @@ -38,7 +39,7 @@ public void scrape() throws ScraperTimeoutException { Document doc = null; try { doc = Jsoup.connect(url).userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/") - .timeout(store.getTimeout()).get(); + .timeout(timeout).get(); } catch (SocketTimeoutException e) { throw new ScraperTimeoutException(url); diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperInterface.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperInterface.java index def503e..65552f3 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperInterface.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperInterface.java @@ -4,7 +4,7 @@ public interface ScraperInterface { - void scrape() throws ScraperTimeoutException; + void scrape(int timeout) throws ScraperTimeoutException; private void reduceToID() {} diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java index d295cc7..82f9cf3 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java @@ -2,6 +2,7 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; +import com.blck.MusicReleaseTracker.DBqueries; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; import com.blck.MusicReleaseTracker.DataObjects.Song; import com.blck.MusicReleaseTracker.Core.ValueStore; @@ -30,8 +31,8 @@ private enum MonthNumbers { private final String songArtist; private String id; private final boolean isIDnull; - public ScraperJunodownload(ValueStore store, ErrorLogging log, String songArtist, String id) { - super(store, log); + public ScraperJunodownload(ErrorLogging log, DBqueries DB, String songArtist, String id) { + super(log, DB); this.songArtist = songArtist; this.id = id; @@ -39,7 +40,7 @@ public ScraperJunodownload(ValueStore store, ErrorLogging log, String songArtist reduceToID(); } @Override - public void scrape() throws ScraperTimeoutException { + public void scrape(int timeout) throws ScraperTimeoutException { if (isIDnull) return; @@ -48,7 +49,7 @@ public void scrape() throws ScraperTimeoutException { Document doc = null; try { doc = Jsoup.connect(url).userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/") - .timeout(store.getTimeout()).get(); + .timeout(timeout).get(); } catch (SocketTimeoutException e) { throw new ScraperTimeoutException(url); diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java index 9d573b8..cd52340 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java @@ -2,6 +2,7 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; +import com.blck.MusicReleaseTracker.DBqueries; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; import com.blck.MusicReleaseTracker.DataObjects.Song; import com.blck.MusicReleaseTracker.Core.ValueStore; @@ -18,8 +19,8 @@ public final class ScraperMusicbrainz extends Scraper implements ScraperInterfac private String id; private final boolean isIDnull; - public ScraperMusicbrainz(ValueStore store, ErrorLogging log, String songArtist, String id) { - super(store, log); + public ScraperMusicbrainz(ErrorLogging log, DBqueries DB, String songArtist, String id) { + super(log, DB); this.songArtist = songArtist; this.id = id; @@ -27,7 +28,7 @@ public ScraperMusicbrainz(ValueStore store, ErrorLogging log, String songArtist, reduceToID(); } @Override - public void scrape() throws ScraperTimeoutException { + public void scrape(int timeout) throws ScraperTimeoutException { if (isIDnull) return; @@ -36,7 +37,7 @@ public void scrape() throws ScraperTimeoutException { Document doc = null; try { doc = Jsoup.connect(url).userAgent("MusicReleaseTracker ( https://github.com/BLCK-B/MusicReleaseTracker )") - .timeout(store.getTimeout()).get(); + .timeout(timeout).get(); } catch (SocketTimeoutException e) { throw new ScraperTimeoutException(url); diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperYoutube.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperYoutube.java index 04ecc14..09989ac 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperYoutube.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperYoutube.java @@ -2,6 +2,7 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; +import com.blck.MusicReleaseTracker.DBqueries; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; import com.blck.MusicReleaseTracker.DataObjects.Song; import com.blck.MusicReleaseTracker.Core.ValueStore; @@ -19,8 +20,8 @@ public final class ScraperYoutube extends Scraper implements ScraperInterface { private final String songArtist; private String id; private final boolean isIDnull; - public ScraperYoutube(ValueStore store, ErrorLogging log, String songArtist, String id) { - super(store, log); + public ScraperYoutube(ErrorLogging log, DBqueries DB, String songArtist, String id) { + super(log, DB); this.songArtist = songArtist; this.id = id; @@ -28,7 +29,7 @@ public ScraperYoutube(ValueStore store, ErrorLogging log, String songArtist, Str reduceToID(); } @Override - public void scrape() throws ScraperTimeoutException { + public void scrape(int timeout) throws ScraperTimeoutException { if (isIDnull) return; @@ -37,7 +38,7 @@ public void scrape() throws ScraperTimeoutException { Document doc = null; try { doc = Jsoup.connect(url).userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/") - .timeout(store.getTimeout()).get(); + .timeout(timeout).get(); } catch (SocketTimeoutException e) { throw new ScraperTimeoutException(url); diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 366d43b..2d53778 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -8,6 +8,7 @@ requires spring.boot.autoconfigure; requires spring.boot; requires spring.webmvc; + requires org.xerial.sqlitejdbc; opens com.blck.MusicReleaseTracker; diff --git a/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest.java b/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest.java index 2ef7f88..be69c02 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/DBToolsTest.java @@ -8,7 +8,7 @@ public class DBToolsTest { private String testDBpath; private ValueStore store; - private DBtools dBtools; + private DBqueries dBqueries; @BeforeTestClass public void setUp() { @@ -16,7 +16,7 @@ public void setUp() { testDBpath = "jdbc:sqlite:" + Paths.get("src", "test", "testresources", "testdb.db"); store = new ValueStore(); store.setDBpath(testDBpath); - dBtools = new DBtools(store, null, null); + dBqueries = new DBqueries(store, null, null); } diff --git a/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java b/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java index 79629cd..2135156 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/GUIControllerTest.java @@ -3,12 +3,9 @@ import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; import org.junit.jupiter.api.*; -import org.springframework.test.context.event.annotation.BeforeTestClass; import java.nio.file.Paths; -import static org.junit.jupiter.api.Assertions.*; - /* MusicReleaseTracker Copyright (C) 2023 BLCK This program is free software: you can redistribute it and/or modify @@ -26,7 +23,7 @@ public class GUIControllerTest { private String DBpath; private ValueStore store; - private DBtools DB; + private DBqueries DB; private GUIController guiController; @BeforeEach @@ -34,7 +31,7 @@ void setUp() { DBpath = "jdbc:sqlite:" + Paths.get("src", "test", "testresources", "testdb.db"); store = new ValueStore(); store.setDBpath(DBpath); - DB = new DBtools(store, null, null); + DB = new DBqueries(store, null, null); guiController = new GUIController(store, null, null, null, DB, null); guiController.setTestData("Joe", SourcesEnum.beatport); } diff --git a/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java b/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java index 1437222..072c507 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java +++ b/src/test/java/com/blck/MusicReleaseTracker/HelperDB.java @@ -5,7 +5,7 @@ public class HelperDB { - private static DBtools dBtools; + private static DBqueries dBqueries; private static ManageMigrateDB manageDB; public static void redoTestDB() { diff --git a/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java b/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java index e73fcde..c562b68 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java @@ -30,7 +30,7 @@ public class ScrapeProcessTest { private ValueStore store = new ValueStore(); - private DBtools DB = new DBtools(store, null, null); + private DBqueries DB = new DBqueries(store, null, null); private ScrapeProcess scrapeProcess; private ArrayList expectedList; From 5064c32adfc76a45bda25ad5a7df368bc8bd9ea8 Mon Sep 17 00:00:00 2001 From: BLCK <123077751+BLCK-B@users.noreply.github.com> Date: Wed, 15 May 2024 16:44:46 +0200 Subject: [PATCH 08/22] separated DB from scrapemanager, fixed sortduplicate test --- .../blck/MusicReleaseTracker/DBqueries.java | 36 +++++++++++++++ .../Scraping/ScrapeProcess.java | 2 +- .../Scraping/ScraperManager.java | 46 +++---------------- .../Scraping/Scrapers/Scraper.java | 27 +++++------ .../Scrapers/ScraperJunodownload.java | 1 - .../Scraping/Scrapers/ScraperMusicbrainz.java | 1 - .../{ => Scraping}/ScrapeProcessTest.java | 4 +- .../Scraping/Scrapers/ScraperManagerTest.java | 8 ++++ .../{ => Scraping}/Scrapers/ScraperTest.java | 42 ++++++----------- 9 files changed, 80 insertions(+), 87 deletions(-) rename src/test/java/com/blck/MusicReleaseTracker/{ => Scraping}/ScrapeProcessTest.java (97%) create mode 100644 src/test/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperManagerTest.java rename src/test/java/com/blck/MusicReleaseTracker/{ => Scraping}/Scrapers/ScraperTest.java (71%) diff --git a/src/main/java/com/blck/MusicReleaseTracker/DBqueries.java b/src/main/java/com/blck/MusicReleaseTracker/DBqueries.java index 003b529..0d3058c 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/DBqueries.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DBqueries.java @@ -5,10 +5,12 @@ import com.blck.MusicReleaseTracker.Core.ValueStore; import com.blck.MusicReleaseTracker.DataObjects.Song; import com.blck.MusicReleaseTracker.DataObjects.TableModel; +import com.blck.MusicReleaseTracker.Scraping.Scrapers.*; import org.springframework.beans.factory.annotation.Autowired; import java.sql.*; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; /* MusicReleaseTracker @@ -206,6 +208,40 @@ public ArrayList getAllSourceTableData() { return songObjectList; } + public LinkedList getAllScrapers() { + // creating a list of scraper objects: one scraper holds one URL + LinkedList scrapers = new LinkedList<>(); + try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + String sql = "SELECT artist FROM artists LIMIT 500"; + PreparedStatement pstmt = conn.prepareStatement(sql); + ResultSet artistResults = pstmt.executeQuery(); + // cycling artists + while (artistResults.next()) { + String artist = artistResults.getString("artist"); + // cycling sources + for (SourcesEnum webSource : SourcesEnum.values()) { + sql = "SELECT * FROM artists WHERE artist = ? LIMIT 100"; + pstmt = conn.prepareStatement(sql); + pstmt.setString(1, artist); + ResultSet rs = pstmt.executeQuery(); + String url = rs.getString("url" + webSource); + if (url == null) + continue; + switch (webSource) { + case musicbrainz -> scrapers.add(new ScraperMusicbrainz(log, this, artist, url)); + case beatport -> scrapers.add(new ScraperBeatport(log, this, artist, url)); + case junodownload -> scrapers.add(new ScraperJunodownload(log, this, artist, url)); + case youtube -> scrapers.add(new ScraperYoutube(log, this, artist, url)); + } + } + } + pstmt.close(); + } catch (SQLException e) { + log.error(e, ErrorLogging.Severity.SEVERE, "error creating scrapers list"); + } + return scrapers; + } + private boolean filterWords(String songName, String songType) { // filtering user-selected keywords for (String checkword : store.getFilterWords()) { diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java index 88d1242..c103d0b 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java @@ -56,7 +56,7 @@ public void scrapeData() { scrapeCancel = false; DB.truncateScrapeData(true); ScraperManager scrapers = new ScraperManager(store, log, DB); - final int initSize = scrapers.getInitSize(); + final int initSize = scrapers.loadWithScrapers(); int remaining = 0; double progress = 0.0; while (remaining != -1) { diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperManager.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperManager.java index f5cf944..a99f93b 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperManager.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperManager.java @@ -5,17 +5,14 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.DBqueries; import com.blck.MusicReleaseTracker.Scraping.Scrapers.*; -import org.sqlite.core.DB; -import java.sql.*; import java.util.*; public class ScraperManager { private final ValueStore store; private final ErrorLogging log; private final DBqueries DB; - private final int initSize; - private final LinkedList scrapers = new LinkedList<>(); + private LinkedList scrapers; private final HashMap sourceTimes = new HashMap<>(); // middleware abstraction for scraping with exception handling @@ -23,43 +20,14 @@ public ScraperManager(ValueStore store, ErrorLogging log, DBqueries DB) { this.store = store; this.log = log; this.DB = DB; - // creating a list of scraper objects: one scraper holds one URL - try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "SELECT artist FROM artists LIMIT 500"; - PreparedStatement pstmt = conn.prepareStatement(sql); - ResultSet artistResults = pstmt.executeQuery(); - // cycling artists - while (artistResults.next()) { - String artist = artistResults.getString("artist"); - // cycling sources - for (SourcesEnum webSource : SourcesEnum.values()) { - sql = "SELECT * FROM artists WHERE artist = ? LIMIT 100"; - pstmt = conn.prepareStatement(sql); - pstmt.setString(1, artist); - ResultSet rs = pstmt.executeQuery(); - String url = rs.getString("url" + webSource); - if (url == null) - continue; - switch (webSource) { - case musicbrainz -> scrapers.add(new ScraperMusicbrainz(log, DB, artist, url)); - case beatport -> scrapers.add(new ScraperBeatport(log, DB, artist, url)); - case junodownload -> scrapers.add(new ScraperJunodownload(log, DB, artist, url)); - case youtube -> scrapers.add(new ScraperYoutube(log, DB, artist, url)); - } - } - } - pstmt.close(); - } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error creating scrapers list"); - } - initSize = scrapers.size(); for (SourcesEnum source : SourcesEnum.values()) { sourceTimes.put(source.toString(), 0.0); } } - public int getInitSize() { - return initSize; + public int loadWithScrapers() { + scrapers = DB.getAllScrapers(); + return scrapers.size(); } public int scrapeNext() { @@ -67,7 +35,7 @@ public int scrapeNext() { return -1; double startTime = System.currentTimeMillis(); - Scraper scraper = scrapers.get(0); + Scraper scraper = scrapers.getFirst(); for (int i = 0; i <= 2; i++) { try { scraper.scrape(store.getTimeout()); @@ -94,8 +62,8 @@ public int scrapeNext() { sourceTimes.replaceAll((key, value) -> value + elapsedTime); delays(scraper.toString()); - if (scraper.equals(scrapers.get(0))) - scrapers.remove(0); + if (scraper.equals(scrapers.getFirst())) + scrapers.removeFirst(); return scrapers.size(); } diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java index d36aebb..38943ba 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java @@ -37,11 +37,7 @@ public String getID() { public void processInfo() { unifyApostrophes(); enforceDateFormat(); - sortByDateDescending(); - removeNameDuplicates(); - - // reverse to newest-oldest - Collections.reverse(songList); + sortAndRemoveNameDuplicates(); } public void unifyApostrophes() { @@ -63,8 +59,14 @@ public void enforceDateFormat() { }); } - // TODO: discard duplicates from oldest, in any way - public void removeNameDuplicates() { + public void sortAndRemoveNameDuplicates() { + // oldest to newest + songList.sort((obj1, obj2) -> { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + LocalDate date1 = LocalDate.parse(obj1.getDate(), formatter); + LocalDate date2 = LocalDate.parse(obj2.getDate(), formatter); + return date1.compareTo(date2); + }); Set recordedNames = new HashSet<>(); songList.removeIf(obj -> { String name = obj.getName().toLowerCase(); @@ -75,15 +77,8 @@ public void removeNameDuplicates() { return false; } }); - } - - public void sortByDateDescending() { - songList.sort((obj1, obj2) -> { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - LocalDate date1 = LocalDate.parse(obj1.getDate(), formatter); - LocalDate date2 = LocalDate.parse(obj2.getDate(), formatter); - return date2.compareTo(date1); - }); + // newest to oldest + Collections.reverse(songList); } public void insertSet() { diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java index 82f9cf3..c684880 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperJunodownload.java @@ -5,7 +5,6 @@ import com.blck.MusicReleaseTracker.DBqueries; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; import com.blck.MusicReleaseTracker.DataObjects.Song; -import com.blck.MusicReleaseTracker.Core.ValueStore; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java index cd52340..e8cdb7f 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperMusicbrainz.java @@ -5,7 +5,6 @@ import com.blck.MusicReleaseTracker.DBqueries; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; import com.blck.MusicReleaseTracker.DataObjects.Song; -import com.blck.MusicReleaseTracker.Core.ValueStore; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; diff --git a/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java b/src/test/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcessTest.java similarity index 97% rename from src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java rename to src/test/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcessTest.java index c562b68..5c87377 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/ScrapeProcessTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcessTest.java @@ -1,8 +1,8 @@ -package com.blck.MusicReleaseTracker; +package com.blck.MusicReleaseTracker.Scraping; import com.blck.MusicReleaseTracker.Core.ValueStore; +import com.blck.MusicReleaseTracker.DBqueries; import com.blck.MusicReleaseTracker.DataObjects.Song; -import com.blck.MusicReleaseTracker.Scraping.ScrapeProcess; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperManagerTest.java b/src/test/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperManagerTest.java new file mode 100644 index 0000000..90d4d94 --- /dev/null +++ b/src/test/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperManagerTest.java @@ -0,0 +1,8 @@ +package com.blck.MusicReleaseTracker.Scraping.Scrapers; + +import org.junit.jupiter.api.Test; + +public class ScraperManagerTest { + + +} diff --git a/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java b/src/test/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperTest.java similarity index 71% rename from src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java rename to src/test/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperTest.java index cfef32c..c6ba7c1 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/Scrapers/ScraperTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperTest.java @@ -1,9 +1,7 @@ -package com.blck.MusicReleaseTracker.Scrapers; +package com.blck.MusicReleaseTracker.Scraping.Scrapers; -import com.blck.MusicReleaseTracker.Scraping.Scrapers.*; import com.blck.MusicReleaseTracker.DataObjects.Song; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.util.ArrayList; @@ -39,7 +37,8 @@ void unifyApostrophesBackticksAndAccents() { scraper.unifyApostrophes(); - assertEquals(scraper.songList.get(0).toString(), new Song("S'o'n'g", "artistName", "2023-01-01").toString()); + assertEquals(scraper.songList.getFirst().toString(), + new Song("S'o'n'g", "artistName", "2023-01-01").toString()); } @Test @@ -55,33 +54,22 @@ void incorrectDatesAreDiscarded() { } @Test - void songListSortedByDateDescending() { + void leaveOldestDuplicatesOnlyAndSortByNewest() { + scraper.songList.add(new Song("Song1", "", "2023-01-01")); + scraper.songList.add(new Song("SONG1", "", "2005-05-05")); + scraper.songList.add(new Song("song1", "", "2005-05-06")); + scraper.songList.add(new Song("Song3", "", "2021-01-01")); + scraper.songList.add(new Song("Song3", "", "2019-01-01")); + scraper.songList.add(new Song("song2", "", "2017-01-01")); ArrayList expectedList = new ArrayList<>(); - scraper.songList.add(new Song("Song3", "artistName", "2015-01-07")); - scraper.songList.add(new Song("Song2", "artistName", "2021-06-08")); - scraper.songList.add(new Song("Song4", "artistName", "2000-03-01")); - scraper.songList.add(new Song("Song1", "artistName", "2024-12-05")); - expectedList.add(new Song("Song1", "artistName", "2024-12-05")); - expectedList.add(new Song("Song2", "artistName", "2021-06-08")); - expectedList.add(new Song("Song3", "artistName", "2015-01-07")); - expectedList.add(new Song("Song4", "artistName", "2000-03-01")); + expectedList.add(new Song("Song3", "", "2019-01-01")); + expectedList.add(new Song("song2", "", "2017-01-01")); + expectedList.add(new Song("SONG1", "", "2005-05-05")); - scraper.sortByDateDescending(); + scraper.sortAndRemoveNameDuplicates(); for (int i = 0; i < scraper.songList.size(); i++) - assertEquals(scraper.songList.get(i).toString(), expectedList.get(i).toString()); - } - - @Disabled("do not forget") - @Test - void removeNameDuplicatesLeaveOldest() { - scraper.songList.add(new Song("Song1", "artistName", "2023-01-01")); - scraper.songList.add(new Song("SONG1", "artistName", "2005-05-05")); - scraper.songList.add(new Song("song1", "artistName", "2019-19-19")); - - scraper.removeNameDuplicates(); - // TODO: mind hash - assertEquals(scraper.songList.get(0), new Song("SONG1", "artistName", "2005-05-05")); + assertEquals(expectedList.get(i).toString(), scraper.songList.get(i).toString()); } @Test From 2ce92b55d5705bd370cae7259046149d71c4794d Mon Sep 17 00:00:00 2001 From: BLCK <123077751+BLCK-B@users.noreply.github.com> Date: Sat, 18 May 2024 12:57:06 +0200 Subject: [PATCH 09/22] scraperManager tests fixed error after removing last source fixed HttpStatusException handling --- build.gradle | 9 +- .../MusicReleaseTracker/Core/BeanConfig.java | 15 +-- .../MusicReleaseTracker/DB/DBqueries.java | 38 +++++++ .../DBqueriesClass.java} | 19 +++- .../{ => DB}/ManageMigrateDB.java | 2 +- .../MusicReleaseTracker/GUIController.java | 2 + .../com/blck/MusicReleaseTracker/Main.java | 1 + .../Scraping/ScrapeProcess.java | 4 +- .../Scraping/ScraperGenericException.java | 9 ++ .../Scraping/ScraperManager.java | 54 +++++++--- .../Scraping/Scrapers/Scraper.java | 9 +- .../Scraping/Scrapers/ScraperBeatport.java | 11 +-- .../Scraping/Scrapers/ScraperInterface.java | 3 +- .../Scrapers/ScraperJunodownload.java | 11 ++- .../Scraping/Scrapers/ScraperMusicbrainz.java | 11 ++- .../Scraping/Scrapers/ScraperYoutube.java | 11 +-- src/main/java/module-info.java | 2 + .../blck/MusicReleaseTracker/DBToolsTest.java | 4 +- .../GUIControllerTest.java | 4 +- .../blck/MusicReleaseTracker/HelperDB.java | 3 + .../Scraping/ScrapeProcessTest.java | 5 +- .../Scraping/ScraperManagerTest.java | 98 +++++++++++++++++++ .../Scraping/Scrapers/ScraperManagerTest.java | 8 -- .../Scraping/Scrapers/ScraperTest.java | 10 +- 24 files changed, 271 insertions(+), 72 deletions(-) create mode 100644 src/main/java/com/blck/MusicReleaseTracker/DB/DBqueries.java rename src/main/java/com/blck/MusicReleaseTracker/{DBqueries.java => DB/DBqueriesClass.java} (97%) rename src/main/java/com/blck/MusicReleaseTracker/{ => DB}/ManageMigrateDB.java (99%) create mode 100644 src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperGenericException.java create mode 100644 src/test/java/com/blck/MusicReleaseTracker/Scraping/ScraperManagerTest.java delete mode 100644 src/test/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperManagerTest.java diff --git a/build.gradle b/build.gradle index 13b7189..ecd3985 100644 --- a/build.gradle +++ b/build.gradle @@ -53,16 +53,18 @@ application { dependencies { - implementation 'org.xerial:sqlite-jdbc:3.45.2.0' + implementation 'org.xerial:sqlite-jdbc:3.45.3.0' implementation 'org.jsoup:jsoup:1.17.2' implementation 'com.typesafe:config:1.4.3' testImplementation(platform('org.junit:junit-bom:5.10.2')) testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2' testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.10.2' + testImplementation 'org.mockito:mockito-core:5.12.0' + testImplementation 'org.mockito:mockito-junit-jupiter:5.12.0' - implementation 'org.springframework.boot:spring-boot-starter-web:3.2.4' - testImplementation 'org.springframework.boot:spring-boot-starter-test:3.2.4' + implementation 'org.springframework.boot:spring-boot-starter-web:3.2.5' + testImplementation 'org.springframework.boot:spring-boot-starter-test:3.2.5' } bootJar { @@ -98,5 +100,6 @@ tasks.jar { test { useJUnitPlatform() + jvmArgs("-XX:+EnableDynamicAgentLoading") } diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java b/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java index 5d5d903..fea9664 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java @@ -1,7 +1,8 @@ package com.blck.MusicReleaseTracker.Core; import com.blck.MusicReleaseTracker.*; -import com.blck.MusicReleaseTracker.Scraping.Scrapers.Scraper; +import com.blck.MusicReleaseTracker.DB.DBqueriesClass; +import com.blck.MusicReleaseTracker.DB.ManageMigrateDB; import com.blck.MusicReleaseTracker.Scraping.ScrapeProcess; import com.blck.MusicReleaseTracker.FrontendAPI.SSEController; import org.springframework.context.annotation.Bean; @@ -23,15 +24,15 @@ public ErrorLogging errorLogging(ValueStore store) { } @Bean - public ScrapeProcess scrapeProcess(ValueStore valueStore, ErrorLogging errorLogging, ConfigTools configTools, DBqueries dBqueries, SSEController sseController) { - return new ScrapeProcess(valueStore, errorLogging, configTools, dBqueries, sseController); + public ScrapeProcess scrapeProcess(ValueStore valueStore, ErrorLogging errorLogging, ConfigTools configTools, DBqueriesClass dBqueriesClass, SSEController sseController) { + return new ScrapeProcess(valueStore, errorLogging, configTools, dBqueriesClass, sseController); } @Bean public GUIController guiController(ValueStore valueStore, ErrorLogging errorLogging, ScrapeProcess scrapeProcess, ConfigTools config, - ManageMigrateDB manageMigrateDB, DBqueries dBqueries) { - return new GUIController(valueStore, errorLogging, scrapeProcess, config, dBqueries, manageMigrateDB); + ManageMigrateDB manageMigrateDB, DBqueriesClass dBqueriesClass) { + return new GUIController(valueStore, errorLogging, scrapeProcess, config, dBqueriesClass, manageMigrateDB); } @Bean @@ -45,8 +46,8 @@ public ManageMigrateDB manageMigrateDB(ValueStore valueStore, ErrorLogging error } @Bean - public DBqueries dBqueries(ValueStore valueStore, ErrorLogging errorLogging, ManageMigrateDB manageMigrateDB) { - return new DBqueries(valueStore, errorLogging, manageMigrateDB); + public DBqueriesClass dBqueriesClass(ValueStore valueStore, ErrorLogging errorLogging, ManageMigrateDB manageMigrateDB) { + return new DBqueriesClass(valueStore, errorLogging, manageMigrateDB); } @Bean diff --git a/src/main/java/com/blck/MusicReleaseTracker/DB/DBqueries.java b/src/main/java/com/blck/MusicReleaseTracker/DB/DBqueries.java new file mode 100644 index 0000000..36719dc --- /dev/null +++ b/src/main/java/com/blck/MusicReleaseTracker/DB/DBqueries.java @@ -0,0 +1,38 @@ +package com.blck.MusicReleaseTracker.DB; + +import com.blck.MusicReleaseTracker.Core.SourcesEnum; +import com.blck.MusicReleaseTracker.DataObjects.Song; +import com.blck.MusicReleaseTracker.DataObjects.TableModel; +import com.blck.MusicReleaseTracker.Scraping.Scrapers.Scraper; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +public interface DBqueries { + + List getArtistList(); + + void insertIntoArtistList(String name); + + List loadTable(SourcesEnum source, String name); + + List loadCombviewTable(); + + String getArtistSourceID(String name, SourcesEnum source); + + void updateArtistSourceID(String name, SourcesEnum source, String ID); + + void clearArtistDataFrom(String name, String table); + + void removeArtist(String name); + + void truncateScrapeData(boolean all); + + ArrayList getAllSourceTableData(); + + LinkedList getAllScrapers(); + + void batchInsertSongs(ArrayList songList, SourcesEnum source, int limit); + + void vacuum(); +} diff --git a/src/main/java/com/blck/MusicReleaseTracker/DBqueries.java b/src/main/java/com/blck/MusicReleaseTracker/DB/DBqueriesClass.java similarity index 97% rename from src/main/java/com/blck/MusicReleaseTracker/DBqueries.java rename to src/main/java/com/blck/MusicReleaseTracker/DB/DBqueriesClass.java index 0d3058c..feeb05b 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/DBqueries.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DB/DBqueriesClass.java @@ -1,4 +1,4 @@ -package com.blck.MusicReleaseTracker; +package com.blck.MusicReleaseTracker.DB; import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; @@ -26,19 +26,20 @@ You should have received a copy of the GNU General Public License along with this program. If not, see .*/ -public class DBqueries { +public class DBqueriesClass implements DBqueries { private final ValueStore store; private final ErrorLogging log; private final ManageMigrateDB manageDB; @Autowired - public DBqueries(ValueStore valueStore, ErrorLogging errorLogging, ManageMigrateDB manageDB) { + public DBqueriesClass(ValueStore valueStore, ErrorLogging errorLogging, ManageMigrateDB manageDB) { this.store = valueStore; this.log = errorLogging; this.manageDB = manageDB; } + @Override public List getArtistList() { List dataList = new ArrayList<>(); try (Connection conn = DriverManager.getConnection(store.getDBpath())) { @@ -55,6 +56,7 @@ public List getArtistList() { return dataList; } + @Override public List loadTable(SourcesEnum source, String name) { // adding data to tableContent List tableContent = new ArrayList<>(); @@ -76,6 +78,7 @@ public List loadTable(SourcesEnum source, String name) { return tableContent; } + @Override public List loadCombviewTable() { List tableContent = new ArrayList<>(); try (Connection conn = DriverManager.getConnection(store.getDBpath())) { @@ -96,6 +99,7 @@ public List loadCombviewTable() { return tableContent; } + @Override public void insertIntoArtistList(String name) { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { String sql = "INSERT INTO artists (artist) values(?)"; @@ -108,6 +112,7 @@ public void insertIntoArtistList(String name) { } } + @Override public void updateArtistSourceID(String name, SourcesEnum source, String ID) { String sql; if (ID == null) @@ -129,6 +134,7 @@ public void updateArtistSourceID(String name, SourcesEnum source, String ID) { } } + @Override public String getArtistSourceID(String name, SourcesEnum source) { String ID = null; String sql = "SELECT url" + source + " FROM artists WHERE artist = ?"; @@ -143,6 +149,7 @@ public String getArtistSourceID(String name, SourcesEnum source) { return ID; } + @Override public void clearArtistDataFrom(String name, String table) { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { String sql = "DELETE FROM " + table + " WHERE artist = ?"; @@ -154,11 +161,13 @@ public void clearArtistDataFrom(String name, String table) { } } + @Override public void removeArtist(String name) { for (String tableName : manageDB.getDBStructure(store.getDBpath()).keySet()) clearArtistDataFrom(name, tableName); } + @Override public void truncateScrapeData(boolean all) { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { if (all) { @@ -176,6 +185,7 @@ public void truncateScrapeData(boolean all) { } } + @Override public ArrayList getAllSourceTableData() { // song object list with data from all sources ArrayList songObjectList = new ArrayList<>(); @@ -208,6 +218,7 @@ public ArrayList getAllSourceTableData() { return songObjectList; } + @Override public LinkedList getAllScrapers() { // creating a list of scraper objects: one scraper holds one URL LinkedList scrapers = new LinkedList<>(); @@ -255,6 +266,7 @@ private boolean filterWords(String songName, String songType) { return true; } + @Override public void batchInsertSongs(ArrayList songList, SourcesEnum source, int limit) { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { int i = 0; @@ -291,6 +303,7 @@ public void batchInsertSongs(ArrayList songList, SourcesEnum source, int l } } + @Override public void vacuum() { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { String sql = "VACUUM;"; diff --git a/src/main/java/com/blck/MusicReleaseTracker/ManageMigrateDB.java b/src/main/java/com/blck/MusicReleaseTracker/DB/ManageMigrateDB.java similarity index 99% rename from src/main/java/com/blck/MusicReleaseTracker/ManageMigrateDB.java rename to src/main/java/com/blck/MusicReleaseTracker/DB/ManageMigrateDB.java index ad8c4ee..c4350d7 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/ManageMigrateDB.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DB/ManageMigrateDB.java @@ -1,4 +1,4 @@ -package com.blck.MusicReleaseTracker; +package com.blck.MusicReleaseTracker.DB; import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.ValueStore; diff --git a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java index fa8bf5a..bbcf09d 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java @@ -3,6 +3,8 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; +import com.blck.MusicReleaseTracker.DB.DBqueries; +import com.blck.MusicReleaseTracker.DB.ManageMigrateDB; import com.blck.MusicReleaseTracker.DataObjects.TableModel; import com.blck.MusicReleaseTracker.Scraping.ScrapeProcess; import com.blck.MusicReleaseTracker.Scraping.Scrapers.*; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Main.java b/src/main/java/com/blck/MusicReleaseTracker/Main.java index 6e326cc..65cba3a 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Main.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Main.java @@ -1,6 +1,7 @@ package com.blck.MusicReleaseTracker; import com.blck.MusicReleaseTracker.Core.ErrorLogging; +import com.blck.MusicReleaseTracker.DB.ManageMigrateDB; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java index c103d0b..d65290d 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java @@ -3,7 +3,7 @@ import com.blck.MusicReleaseTracker.ConfigTools; import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.DBqueries; +import com.blck.MusicReleaseTracker.DB.DBqueries; import com.blck.MusicReleaseTracker.FrontendAPI.SSEController; import com.blck.MusicReleaseTracker.DataObjects.Song; import org.springframework.beans.factory.annotation.Autowired; @@ -55,7 +55,7 @@ public void scrapeData() { config.readConfig(ConfigTools.configOptions.longTimeout); scrapeCancel = false; DB.truncateScrapeData(true); - ScraperManager scrapers = new ScraperManager(store, log, DB); + ScraperManager scrapers = new ScraperManager(log, DB); final int initSize = scrapers.loadWithScrapers(); int remaining = 0; double progress = 0.0; diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperGenericException.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperGenericException.java new file mode 100644 index 0000000..e84e680 --- /dev/null +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperGenericException.java @@ -0,0 +1,9 @@ +package com.blck.MusicReleaseTracker.Scraping; + +public class ScraperGenericException extends Exception { + + public ScraperGenericException(String url) { + super(url); + } + +} diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperManager.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperManager.java index a99f93b..21b3e1e 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperManager.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScraperManager.java @@ -1,25 +1,31 @@ package com.blck.MusicReleaseTracker.Scraping; import com.blck.MusicReleaseTracker.Core.SourcesEnum; -import com.blck.MusicReleaseTracker.Core.ValueStore; import com.blck.MusicReleaseTracker.Core.ErrorLogging; -import com.blck.MusicReleaseTracker.DBqueries; +import com.blck.MusicReleaseTracker.DB.DBqueries; import com.blck.MusicReleaseTracker.Scraping.Scrapers.*; import java.util.*; public class ScraperManager { - private final ValueStore store; + private final ErrorLogging log; private final DBqueries DB; private LinkedList scrapers; + private int sleepTime = 2800; private final HashMap sourceTimes = new HashMap<>(); - // middleware abstraction for scraping with exception handling - public ScraperManager(ValueStore store, ErrorLogging log, DBqueries DB) { - this.store = store; + public ScraperManager(ErrorLogging log, DBqueries DB) { + this.log = log; + this.DB = DB; + for (SourcesEnum source : SourcesEnum.values()) { + sourceTimes.put(source.toString(), 0.0); + } + } + public ScraperManager(ErrorLogging log, DBqueries DB, int customSleepTime) { this.log = log; this.DB = DB; + sleepTime = customSleepTime; for (SourcesEnum source : SourcesEnum.values()) { sourceTimes.put(source.toString(), 0.0); } @@ -31,19 +37,16 @@ public int loadWithScrapers() { } public int scrapeNext() { - if (scrapers.isEmpty()) - return -1; - double startTime = System.currentTimeMillis(); Scraper scraper = scrapers.getFirst(); for (int i = 0; i <= 2; i++) { try { - scraper.scrape(store.getTimeout()); + scraper.scrape(sleepTime); break; // exception = will not break } catch (ScraperTimeoutException e) { switch (i) { - case 0 -> log.error(e, ErrorLogging.Severity.INFO, scraper + " timed out"); + case 0 -> log.error(e, ErrorLogging.Severity.INFO, scraper + " time out"); case 1 -> log.error(e, ErrorLogging.Severity.INFO, scraper + " second time out"); default -> { log.error(e, ErrorLogging.Severity.INFO, "final time out, disabling source " + scraper); @@ -52,27 +55,46 @@ public int scrapeNext() { } } try { - Thread.sleep(2200); + Thread.sleep(sleepTime); + } catch (InterruptedException ex) { + throw new RuntimeException(ex); + } + } + catch (Exception e) { + switch (i) { + case 0 -> log.error(e, ErrorLogging.Severity.WARNING, scraper + " error of scraper"); + case 1 -> log.error(e, ErrorLogging.Severity.WARNING, scraper + " second error of scraper"); + default -> { + log.error(e, ErrorLogging.Severity.WARNING, "final error of scraper, disabling source " + scraper); + // remove all scrapers of a faulty source + scrapers.removeIf(s -> s.getClass().equals(scraper.getClass())); + } + } + try { + Thread.sleep(sleepTime); } catch (InterruptedException ex) { throw new RuntimeException(ex); } } + if (scrapers.isEmpty()) + return -1; } double elapsedTime = System.currentTimeMillis() - startTime; sourceTimes.replaceAll((key, value) -> value + elapsedTime); - delays(scraper.toString()); + if (sleepTime != 0) + delays(scraper.toString()); if (scraper.equals(scrapers.getFirst())) scrapers.removeFirst(); - return scrapers.size(); + return scrapers.isEmpty() ? -1 : scrapers.size(); } public void delays(String source) { // every source has an enforced min delay double timeLastScrape = sourceTimes.get(source); - if (timeLastScrape < 2800) { - long waitTime = (long) (2800 - timeLastScrape); + if (timeLastScrape < sleepTime) { + long waitTime = (long) (sleepTime - timeLastScrape); try { Thread.sleep(waitTime); sourceTimes.replaceAll((key, value) -> value + waitTime); diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java index 38943ba..d683d5f 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/Scraper.java @@ -2,7 +2,8 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; -import com.blck.MusicReleaseTracker.DBqueries; +import com.blck.MusicReleaseTracker.DB.DBqueries; +import com.blck.MusicReleaseTracker.Scraping.ScraperGenericException; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; import com.blck.MusicReleaseTracker.DataObjects.Song; @@ -26,7 +27,7 @@ public Scraper(ErrorLogging errorLogging, DBqueries DB) { this.DB = DB; } - public void scrape(int timeout) throws ScraperTimeoutException { + public void scrape(int timeout) throws ScraperTimeoutException, ScraperGenericException { System.out.println("The method scrape() is to be overriden."); } @@ -35,6 +36,10 @@ public String getID() { } public void processInfo() { + if (songList.isEmpty()) { + log.error(new Exception(), ErrorLogging.Severity.WARNING, "song list produced by scraper is empty"); + return; + } unifyApostrophes(); enforceDateFormat(); sortAndRemoveNameDuplicates(); diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java index b2cae16..ff74ccf 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/Scrapers/ScraperBeatport.java @@ -2,15 +2,14 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; -import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.DBqueries; +import com.blck.MusicReleaseTracker.DB.DBqueries; +import com.blck.MusicReleaseTracker.Scraping.ScraperGenericException; import com.blck.MusicReleaseTracker.Scraping.ScraperTimeoutException; import com.blck.MusicReleaseTracker.DataObjects.Song; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; -import java.io.IOException; import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.regex.Matcher; @@ -30,7 +29,7 @@ public ScraperBeatport(ErrorLogging log, DBqueries DB, String songArtist, String reduceToID(); } @Override - public void scrape(int timeout) throws ScraperTimeoutException { + public void scrape(int timeout) throws ScraperTimeoutException, ScraperGenericException { if (isIDnull) return; @@ -44,8 +43,8 @@ public void scrape(int timeout) throws ScraperTimeoutException { catch (SocketTimeoutException e) { throw new ScraperTimeoutException(url); } - catch (IOException e) { - throw new RuntimeException(e); + catch (Exception e) { + throw new ScraperGenericException(url); } // pattern matching to make sense of the JSON extracted from - + +
diff --git a/src/test/java/com/blck/MusicReleaseTracker/DBqueriesTest.java b/src/test/java/com/blck/MusicReleaseTracker/DBqueriesTest.java index 6875372..f378028 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/DBqueriesTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/DBqueriesTest.java @@ -2,7 +2,7 @@ import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.SourcesEnum; import com.blck.MusicReleaseTracker.Core.ValueStore; -import com.blck.MusicReleaseTracker.DB.DBqueriesClass; +import com.blck.MusicReleaseTracker.DB.DBqueries; import com.blck.MusicReleaseTracker.DB.ManageMigrateDB; import com.blck.MusicReleaseTracker.DataObjects.Song; import org.junit.jupiter.api.*; @@ -43,7 +43,7 @@ public class DBqueriesTest { @Mock ConfigTools config; @InjectMocks - DBqueriesClass dBqueriesClass; + DBqueries dBqueriesClass; ArrayList songList; @@ -56,7 +56,7 @@ static void setUpDB() { void setUp() { helperDB.redoTestData(); when(store.getDBpath()).thenReturn(testDBpath); - dBqueriesClass = new DBqueriesClass(store, log, config, manageMigrateDB); + dBqueriesClass = new DBqueries(store, log, config, manageMigrateDB); songList = new ArrayList<>(); songList.add(new Song("song1", "artist1", "2022-01-01", "remix")); songList.add(new Song("song2", "artist1", "2022-01-01", "type")); diff --git a/src/test/java/com/blck/MusicReleaseTracker/Scraping/ScraperManagerTest.java b/src/test/java/com/blck/MusicReleaseTracker/Scraping/ScraperManagerTest.java index ebb8aef..320672b 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/Scraping/ScraperManagerTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/Scraping/ScraperManagerTest.java @@ -95,7 +95,7 @@ void removingLastSourceScraperOnTimeoutExceptionsReturnsEmpty() throws ScraperTi } @Test - void errorSourceCausesWarningLogAndIsRemoved() throws ScraperTimeoutException, ScraperGenericException { + void erroringSourceCausesWarningLogAndIsRemoved() throws ScraperTimeoutException, ScraperGenericException { doThrow(ScraperGenericException.class).when(scraperMB).scrape(anyInt()); doThrow(ScraperGenericException.class).when(scraperBP).scrape(anyInt()); insertScrapers(); diff --git a/vue/src/components/SettingsWindow.vue b/vue/src/components/SettingsWindow.vue index 071af38..2081ba3 100644 --- a/vue/src/components/SettingsWindow.vue +++ b/vue/src/components/SettingsWindow.vue @@ -78,10 +78,6 @@

Other

-
- - -
@@ -138,7 +134,6 @@ Dark: false, Light: false, }, - longTimeout: false, isoDates: false, autoTheme: false, } @@ -154,7 +149,6 @@ axios.get('/api/settingsOpened') .then(response => { this.filters = response.data; - this.longTimeout = response.data.longTimeout; this.isoDates = response.data.isoDates; this.autoTheme = response.data.autoTheme; }) From 4a3062ea9604d18a62b7f5305724179442e003fa Mon Sep 17 00:00:00 2001 From: BLCK <123077751+BLCK-B@users.noreply.github.com> Date: Fri, 24 May 2024 16:33:53 +0200 Subject: [PATCH 16/22] removed files --- .../static/assets/index-C3_hPEEi.css | 1 + .../resources/static/assets/index-CB9h-D7W.js | 26 ++++++++++++++++++ src/test/testresources/testdb.db | Bin 0 -> 32768 bytes 3 files changed, 27 insertions(+) create mode 100644 src/main/resources/static/assets/index-C3_hPEEi.css create mode 100644 src/main/resources/static/assets/index-CB9h-D7W.js create mode 100644 src/test/testresources/testdb.db diff --git a/src/main/resources/static/assets/index-C3_hPEEi.css b/src/main/resources/static/assets/index-C3_hPEEi.css new file mode 100644 index 0000000..852bf15 --- /dev/null +++ b/src/main/resources/static/assets/index-C3_hPEEi.css @@ -0,0 +1 @@ +*[data-v-18b2502f]::-webkit-scrollbar{width:8px;background:transparent}*[data-v-18b2502f]::-webkit-scrollbar-thumb{background-color:var(--dull-color)}.listbtn[data-v-18b2502f]{width:92%;height:28px;border-radius:0;margin:0;display:flex;align-items:center;white-space:nowrap;overflow:hidden;padding-left:7px}.artistlist[data-v-18b2502f]{height:calc(100vh - 40px);overflow-y:scroll}.artistlist li[data-v-18b2502f]{list-style-type:none}.buttonspace[data-v-18b2502f]{margin-bottom:5px}.addbtn[data-v-18b2502f],.morebtn[data-v-18b2502f]{font-size:12px;width:75px;height:28px;border:2px solid var(--dull-color);border-radius:6px;background-color:transparent;color:var(--contrast-color)}.addbtn[data-v-18b2502f]{margin-left:5px}.addbtn[data-v-18b2502f]:hover,.morebtn[data-v-18b2502f]:hover{background-color:var(--accent-color);border:2px solid var(--accent-color);color:var(--accent-contrast)}.addbtn[data-v-18b2502f]:active,.morebtn[data-v-18b2502f]:active{opacity:75%}.morebtn[data-v-18b2502f]{margin-left:5px}.dropdown[data-v-18b2502f]{position:relative;display:grid;grid-template-columns:repeat(1,1fr);background-color:var(--subtle-color);padding-right:10px;padding-left:6px}.dropdown .deletebtn[data-v-18b2502f]{font-size:12px;height:25px;margin-top:3px;border:2px solid var(--dull-color);border-radius:6px;background-color:transparent;color:var(--contrast-color)}.deletebtn[data-v-18b2502f]:hover{background-color:red;border:2px solid red}.listbtn[data-v-18b2502f]:hover{background-color:var(--duller-color)}.highlighted[data-v-18b2502f]{background-color:var(--accent-color);color:var(--accent-contrast)}.highlighted[data-v-18b2502f]:hover{background-color:var(--accent-color)}[data-v-18b2502f]:disabled{opacity:.5;pointer-events:none}.wrapper[data-v-671de189]{min-width:500px;width:100%;display:flex;align-items:center;height:38px}.tabs[data-v-671de189]{display:flex;text-align:center;font-weight:700;flex-grow:1;height:38px}.image[data-v-671de189]{height:32px;width:32px}.imgbutton1[data-v-671de189]:hover,.imgbutton2[data-v-671de189]:hover{opacity:70%}.imgbutton1[data-v-671de189]{padding:0;margin-left:8px;background-color:var(--accent-color);border:none;margin-top:2px;height:32px;width:32px}.imgbutton2[data-v-671de189]{padding:0;margin-left:8px;margin-right:20px;border:none;margin-top:2px;border-radius:50px;height:32px;width:32px}.cvtab[data-v-671de189]{width:80%;max-width:390px;padding:8px;border:solid 3px transparent;border-bottom:solid 3px var(--accent-color)}.stab[data-v-671de189]{width:20%;max-width:110px;padding:8px;border:solid 3px transparent;border-bottom:solid 3px var(--accent-color);white-space:nowrap;overflow:hidden}.tabs[data-v-671de189] :hover{border-bottom:solid 3px var(--dull-color)}.active[data-v-671de189]{transition:.15s;background-color:var(--accent-color);color:var(--accent-contrast);border-bottom:solid 3px var(--accent-color);border-radius:5px}.active[data-v-671de189]:hover{border-bottom:solid 3px var(--accent-color)}.scrapenotice[data-v-671de189]{position:absolute;z-index:50;background-color:var(--duller-color);border-radius:5px;padding-right:10px;padding-left:10px;right:14px;top:42px}.fade-enter-from[data-v-671de189],.fade-leave-to[data-v-671de189]{opacity:0}.fade-enter-active[data-v-671de189],.fade-leave-active[data-v-671de189]{transition:.15s}[data-v-671de189]:disabled{opacity:.5;pointer-events:none}.table-header[data-v-19adbfff]{flex-shrink:0;overflow:hidden;z-index:3;position:fixed;width:calc(100% - 170px)}.table-body[data-v-19adbfff]{flex-grow:1;overflow-y:auto;-webkit-user-select:text;user-select:text;margin-bottom:10vh}table[data-v-19adbfff]{width:100%;min-width:500px;border-collapse:collapse}th[data-v-19adbfff],td[data-v-19adbfff]{padding:4px}th[data-v-19adbfff]{background-color:var(--primary-color);border:none;position:sticky;top:0}.song[data-v-19adbfff],.tdsong[data-v-19adbfff],.artist[data-v-19adbfff],.tdartist[data-v-19adbfff]{width:50%;max-width:120px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.date[data-v-19adbfff],.tddate[data-v-19adbfff]{width:100px;min-width:100px}.future-date[data-v-19adbfff]{opacity:40%}.emptynotice[data-v-19adbfff]{position:absolute;left:40%;top:40%;color:var(--dull-color)}.quickstart[data-v-19adbfff]{position:relative;font-size:15px;line-height:22px;left:5%;top:5%}.quickstart .title[data-v-19adbfff]{font-weight:700}.tddate[data-v-19adbfff]{display:flex;justify-content:flex-end;margin-right:30px}p[data-v-0fe96286]{line-height:1.4}.dialog[data-v-0fe96286]{width:375px;height:280px;background-color:var(--primary-color);border:2px solid var(--contrast-color);border-radius:3px;color:var(--contrast-color);padding:8px}input[data-v-0fe96286]{background-color:var(--duller-color);color:var(--contrast-color);border:none;width:345px;position:absolute;bottom:5px;left:5px;font-size:13px;height:18px}input[data-v-0fe96286]:focus{outline:none}button[data-v-0fe96286]{color:#000;border:none;position:absolute;right:5px;bottom:5px}button[data-v-0fe96286]:hover{opacity:70%}a[data-v-0fe96286]{color:var(--accent-color);font-weight:700;text-decoration:none}a[data-v-0fe96286]:hover{text-decoration:underline}h1[data-v-0fe96286]{font-size:17px;font-weight:400}.variabletext[data-v-0fe96286]{color:var(--accent-color)}.artist[data-v-0fe96286]{-webkit-user-select:text;user-select:text}.imgbutton[data-v-0fe96286],.image[data-v-0fe96286]{height:23px;width:23px;padding:0;float:right;margin-right:2px;background-color:transparent}.imgbutton[data-v-0fe96286]:hover{opacity:50%}[data-v-0fe96286]:disabled{opacity:.5;pointer-events:none}.wrapper[data-v-cb695d37]{top:25%;left:35%;width:325px;height:240px;position:absolute;z-index:3;background-color:var(--primary-color);border:2px solid var(--contrast-color);border-radius:3px;padding:8px}.diag-actions[data-v-cb695d37]{position:absolute;bottom:3px;left:5px}button[data-v-cb695d37]{border:none}input[data-v-cb695d37]{background-color:var(--duller-color);color:var(--contrast-color);width:200px;margin-right:58px;margin-left:10px;border:none}input[data-v-cb695d37]:focus{outline:none}.imgbutton[data-v-cb695d37],.image[data-v-cb695d37]{height:23px;width:23px;padding:0;float:right;margin-left:5px;margin-right:2px;background-color:transparent}.imgbutton[data-v-cb695d37]{position:relative}.imgbutton[data-v-cb695d37]:hover{opacity:50%}[data-v-cb695d37]:disabled{opacity:.3;pointer-events:none}*[data-v-d29e2d3a]{transition:.2s}.progress-container[data-v-d29e2d3a]{background-color:transparent}.progressbar[data-v-d29e2d3a]{height:5px;line-height:5px;text-align:center;background-color:var(--accent-color)}*[data-v-6b545924]{transition:.1s}.title[data-v-6b545924]{font-weight:700}.settings[data-v-6b545924]{font-family:arial,sans-serif;font-size:14px;-webkit-user-select:none;user-select:none;background-color:var(--primary-color);color:var(--contrast-color);overflow-y:scroll;overflow-x:hidden;display:grid;align-content:start;width:100%;justify-content:center;accent-color:var(--contrast-color)}@media screen and (min-width: 950px){.settings[data-v-6b545924]{display:grid;grid-template-columns:repeat(2,0fr)}section[data-v-6b545924]{margin-right:90px}}.filters-buttons[data-v-6b545924]{margin-top:10px;display:grid;grid-template-columns:repeat(2,1fr);grid-gap:10px;max-height:80px}.flex-items[data-v-6b545924]{display:flex;flex-direction:column}.flex-padding[data-v-6b545924]{padding:5px}.appearancecont[data-v-6b545924]{display:flex;accent-color:var(--dull-color)}.theme-buttons[data-v-6b545924]{display:grid;grid-template-columns:repeat(2,1fr);width:30%;padding-right:20px;line-height:18px}.accent-buttons[data-v-6b545924]{display:grid;grid-template-columns:repeat(4,1fr)}.belowAppearance[data-v-6b545924]{margin-left:15px;margin-top:6px}.imgbutton[data-v-6b545924]{position:absolute;right:0;top:0;padding:0;margin:10px;background-color:transparent;border:none;transition:0s}.imgbutton[data-v-6b545924]:hover{opacity:60%}.image[data-v-6b545924]{height:33px}input[data-v-6b545924]{margin-right:5px}section[data-v-6b545924]{position:relative;margin-top:20px;left:40px;padding:1px 15px 10px;background-color:var(--duller-color);border-radius:5px;transition:.15s;width:345px}.self[data-v-6b545924]{justify-self:center;width:280px;background-color:transparent}.blckimg[data-v-6b545924]{height:48px;background-color:#000;border-radius:5px;padding:12px;margin-right:22px}.mrtimg[data-v-6b545924]{height:72px;border-radius:10px}.colorindicator[data-v-6b545924]{position:absolute;right:0;top:0;height:100%;width:8px;background-color:var(--accent-color);border-top-right-radius:5px;border-bottom-right-radius:5px}.dangercont[data-v-6b545924]{display:flex;justify-content:space-evenly}.danger button[data-v-6b545924]{border-radius:5px;background-color:transparent;color:var(--contrast-color);border:2px solid red;padding:4px;width:120px}.danger button[data-v-6b545924]:hover{background-color:red}.disabled[data-v-6b545924]{opacity:.3}.preview[data-v-85018fb6]{width:100%;height:100%;background-color:var(--subtle-color);font-size:15px}h1[data-v-85018fb6]{font-size:18px;color:var(--accent-color)}p[data-v-85018fb6],h1[data-v-85018fb6]{position:relative;left:6px}button[data-v-85018fb6]{margin-left:8px;border:none;border-radius:5px;width:60px}.imgbutton[data-v-85018fb6],.image[data-v-85018fb6]{margin-left:22px;height:26px;width:26px;padding:0;background-color:transparent}.imgbutton[data-v-85018fb6]:hover{opacity:50%}[data-v-85018fb6]:disabled{opacity:.5;pointer-events:none}*[data-v-e34fd722]{scrollbar-color:var(--dull-color) transparent}*[data-v-e34fd722]::-webkit-scrollbar-thumb{background-color:var(--dull-color)}*[data-v-e34fd722]::-webkit-scrollbar{width:8px;background:transparent}.app[data-v-e34fd722]{font-family:arial,sans-serif;font-size:14px;-webkit-user-select:none;user-select:none;display:flex;position:fixed;top:0;left:0;padding-left:5px;padding-top:3px;width:100%;height:100%;background-color:var(--primary-color);color:var(--contrast-color);transition:.15s}.list[data-v-e34fd722]{width:170px;min-width:170px;padding-top:5px;padding-left:2px;top:-3px;left:-5px;position:relative;background-color:var(--subtle-color)}.maincontent[data-v-e34fd722]{flex-grow:1;height:100vh}.topbar[data-v-e34fd722]{left:5px;position:relative}.dialogsurl[data-v-e34fd722]{top:25%;left:35%;position:absolute}.sourcetable[data-v-e34fd722]{position:relative;top:6px;height:100%;overflow-y:scroll;margin-right:4px}.progressbar[data-v-e34fd722]{position:absolute;bottom:3px;left:0;z-index:5;width:100%} diff --git a/src/main/resources/static/assets/index-CB9h-D7W.js b/src/main/resources/static/assets/index-CB9h-D7W.js new file mode 100644 index 0000000..64f54dd --- /dev/null +++ b/src/main/resources/static/assets/index-CB9h-D7W.js @@ -0,0 +1,26 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&s(i)}).observe(document,{childList:!0,subtree:!0});function n(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function s(r){if(r.ep)return;r.ep=!0;const o=n(r);fetch(r.href,o)}})();/** +* @vue/shared v3.4.21 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function Zs(e,t){const n=new Set(e.split(","));return t?s=>n.has(s.toLowerCase()):s=>n.has(s)}const Z={},Ft=[],Le=()=>{},vl=()=>!1,Hn=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),er=e=>e.startsWith("onUpdate:"),he=Object.assign,tr=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Cl=Object.prototype.hasOwnProperty,W=(e,t)=>Cl.call(e,t),k=Array.isArray,Ut=e=>hn(e)==="[object Map]",Kn=e=>hn(e)==="[object Set]",kr=e=>hn(e)==="[object Date]",M=e=>typeof e=="function",ce=e=>typeof e=="string",pt=e=>typeof e=="symbol",Y=e=>e!==null&&typeof e=="object",No=e=>(Y(e)||M(e))&&M(e.then)&&M(e.catch),Fo=Object.prototype.toString,hn=e=>Fo.call(e),El=e=>hn(e).slice(8,-1),Uo=e=>hn(e)==="[object Object]",nr=e=>ce(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,tn=Zs(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),qn=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},wl=/-(\w)/g,Ke=qn(e=>e.replace(wl,(t,n)=>n?n.toUpperCase():"")),Al=/\B([A-Z])/g,jt=qn(e=>e.replace(Al,"-$1").toLowerCase()),Wn=qn(e=>e.charAt(0).toUpperCase()+e.slice(1)),hs=qn(e=>e?`on${Wn(e)}`:""),Ot=(e,t)=>!Object.is(e,t),Rn=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},Rs=e=>{const t=parseFloat(e);return isNaN(t)?e:t},Tl=e=>{const t=ce(e)?Number(e):NaN;return isNaN(t)?e:t};let Nr;const Do=()=>Nr||(Nr=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function pn(e){if(k(e)){const t={};for(let n=0;n{if(n){const s=n.split(Rl);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function Ee(e){let t="";if(ce(e))t=e;else if(k(e))for(let n=0;nBt(n,t))}const ze=e=>ce(e)?e:e==null?"":k(e)||Y(e)&&(e.toString===Fo||!M(e.toString))?JSON.stringify(e,Mo,2):String(e),Mo=(e,t)=>t&&t.__v_isRef?Mo(e,t.value):Ut(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],o)=>(n[ps(s,o)+" =>"]=r,n),{})}:Kn(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>ps(n))}:pt(t)?ps(t):Y(t)&&!k(t)&&!Uo(t)?String(t):t,ps=(e,t="")=>{var n;return pt(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.4.21 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Ne;class $o{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Ne,!t&&Ne&&(this.index=(Ne.scopes||(Ne.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=Ne;try{return Ne=this,t()}finally{Ne=n}}}on(){Ne=this}off(){Ne=this.parent}stop(t){if(this._active){let n,s;for(n=0,s=this.effects.length;n=4))break}this._dirtyLevel===1&&(this._dirtyLevel=0),xt()}return this._dirtyLevel>=4}set dirty(t){this._dirtyLevel=t?4:0}run(){if(this._dirtyLevel=0,!this.active)return this.fn();let t=dt,n=At;try{return dt=!0,At=this,this._runnings++,Fr(this),this.fn()}finally{Ur(this),this._runnings--,At=n,dt=t}}stop(){var t;this.active&&(Fr(this),Ur(this),(t=this.onStop)==null||t.call(this),this.active=!1)}}function Dl(e){return e.value}function Fr(e){e._trackId++,e._depsLength=0}function Ur(e){if(e.deps.length>e._depsLength){for(let t=e._depsLength;t{const n=new Map;return n.cleanup=e,n.computed=t,n},Is=new WeakMap,Tt=Symbol(""),Ps=Symbol("");function we(e,t,n){if(dt&&At){let s=Is.get(e);s||Is.set(e,s=new Map);let r=s.get(n);r||s.set(n,r=Wo(()=>s.delete(n))),Ko(At,r)}}function Je(e,t,n,s,r,o){const i=Is.get(e);if(!i)return;let l=[];if(t==="clear")l=[...i.values()];else if(n==="length"&&k(e)){const c=Number(s);i.forEach((f,u)=>{(u==="length"||!pt(u)&&u>=c)&&l.push(f)})}else switch(n!==void 0&&l.push(i.get(n)),t){case"add":k(e)?nr(n)&&l.push(i.get("length")):(l.push(i.get(Tt)),Ut(e)&&l.push(i.get(Ps)));break;case"delete":k(e)||(l.push(i.get(Tt)),Ut(e)&&l.push(i.get(Ps)));break;case"set":Ut(e)&&l.push(i.get(Tt));break}rr();for(const c of l)c&&qo(c,4);or()}const Vl=Zs("__proto__,__v_isRef,__isVue"),Go=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(pt)),Dr=Bl();function Bl(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const s=G(this);for(let o=0,i=this.length;o{e[t]=function(...n){Rt(),rr();const s=G(this)[t].apply(this,n);return or(),xt(),s}}),e}function Ml(e){const t=G(this);return we(t,"has",e),t.hasOwnProperty(e)}class zo{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){const r=this._isReadonly,o=this._isShallow;if(n==="__v_isReactive")return!r;if(n==="__v_isReadonly")return r;if(n==="__v_isShallow")return o;if(n==="__v_raw")return s===(r?o?Zl:Qo:o?Xo:Yo).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const i=k(t);if(!r){if(i&&W(Dr,n))return Reflect.get(Dr,n,s);if(n==="hasOwnProperty")return Ml}const l=Reflect.get(t,n,s);return(pt(n)?Go.has(n):Vl(n))||(r||we(t,"get",n),o)?l:Re(l)?i&&nr(n)?l:l.value:Y(l)?r?Zo(l):zn(l):l}}class Jo extends zo{constructor(t=!1){super(!1,t)}set(t,n,s,r){let o=t[n];if(!this._isShallow){const c=ln(o);if(!ks(s)&&!ln(s)&&(o=G(o),s=G(s)),!k(t)&&Re(o)&&!Re(s))return c?!1:(o.value=s,!0)}const i=k(t)&&nr(n)?Number(n)e,Gn=e=>Reflect.getPrototypeOf(e);function vn(e,t,n=!1,s=!1){e=e.__v_raw;const r=G(e),o=G(t);n||(Ot(t,o)&&we(r,"get",t),we(r,"get",o));const{has:i}=Gn(r),l=s?ir:n?ur:ar;if(i.call(r,t))return l(e.get(t));if(i.call(r,o))return l(e.get(o));e!==r&&e.get(t)}function Cn(e,t=!1){const n=this.__v_raw,s=G(n),r=G(e);return t||(Ot(e,r)&&we(s,"has",e),we(s,"has",r)),e===r?n.has(e):n.has(e)||n.has(r)}function En(e,t=!1){return e=e.__v_raw,!t&&we(G(e),"iterate",Tt),Reflect.get(e,"size",e)}function Vr(e){e=G(e);const t=G(this);return Gn(t).has.call(t,e)||(t.add(e),Je(t,"add",e,e)),this}function Br(e,t){t=G(t);const n=G(this),{has:s,get:r}=Gn(n);let o=s.call(n,e);o||(e=G(e),o=s.call(n,e));const i=r.call(n,e);return n.set(e,t),o?Ot(t,i)&&Je(n,"set",e,t):Je(n,"add",e,t),this}function Mr(e){const t=G(this),{has:n,get:s}=Gn(t);let r=n.call(t,e);r||(e=G(e),r=n.call(t,e)),s&&s.call(t,e);const o=t.delete(e);return r&&Je(t,"delete",e,void 0),o}function $r(){const e=G(this),t=e.size!==0,n=e.clear();return t&&Je(e,"clear",void 0,void 0),n}function wn(e,t){return function(s,r){const o=this,i=o.__v_raw,l=G(i),c=t?ir:e?ur:ar;return!e&&we(l,"iterate",Tt),i.forEach((f,u)=>s.call(r,c(f),c(u),o))}}function An(e,t,n){return function(...s){const r=this.__v_raw,o=G(r),i=Ut(o),l=e==="entries"||e===Symbol.iterator&&i,c=e==="keys"&&i,f=r[e](...s),u=n?ir:t?ur:ar;return!t&&we(o,"iterate",c?Ps:Tt),{next(){const{value:d,done:g}=f.next();return g?{value:d,done:g}:{value:l?[u(d[0]),u(d[1])]:u(d),done:g}},[Symbol.iterator](){return this}}}}function tt(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function ql(){const e={get(o){return vn(this,o)},get size(){return En(this)},has:Cn,add:Vr,set:Br,delete:Mr,clear:$r,forEach:wn(!1,!1)},t={get(o){return vn(this,o,!1,!0)},get size(){return En(this)},has:Cn,add:Vr,set:Br,delete:Mr,clear:$r,forEach:wn(!1,!0)},n={get(o){return vn(this,o,!0)},get size(){return En(this,!0)},has(o){return Cn.call(this,o,!0)},add:tt("add"),set:tt("set"),delete:tt("delete"),clear:tt("clear"),forEach:wn(!0,!1)},s={get(o){return vn(this,o,!0,!0)},get size(){return En(this,!0)},has(o){return Cn.call(this,o,!0)},add:tt("add"),set:tt("set"),delete:tt("delete"),clear:tt("clear"),forEach:wn(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=An(o,!1,!1),n[o]=An(o,!0,!1),t[o]=An(o,!1,!0),s[o]=An(o,!0,!0)}),[e,n,t,s]}const[Wl,Gl,zl,Jl]=ql();function lr(e,t){const n=t?e?Jl:zl:e?Gl:Wl;return(s,r,o)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(W(n,r)&&r in s?n:s,r,o)}const Yl={get:lr(!1,!1)},Xl={get:lr(!1,!0)},Ql={get:lr(!0,!1)},Yo=new WeakMap,Xo=new WeakMap,Qo=new WeakMap,Zl=new WeakMap;function ec(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function tc(e){return e.__v_skip||!Object.isExtensible(e)?0:ec(El(e))}function zn(e){return ln(e)?e:cr(e,!1,jl,Yl,Yo)}function nc(e){return cr(e,!1,Kl,Xl,Xo)}function Zo(e){return cr(e,!0,Hl,Ql,Qo)}function cr(e,t,n,s,r){if(!Y(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const o=r.get(e);if(o)return o;const i=tc(e);if(i===0)return e;const l=new Proxy(e,i===2?s:n);return r.set(e,l),l}function Dt(e){return ln(e)?Dt(e.__v_raw):!!(e&&e.__v_isReactive)}function ln(e){return!!(e&&e.__v_isReadonly)}function ks(e){return!!(e&&e.__v_isShallow)}function ei(e){return Dt(e)||ln(e)}function G(e){const t=e&&e.__v_raw;return t?G(t):e}function ti(e){return Object.isExtensible(e)&&Dn(e,"__v_skip",!0),e}const ar=e=>Y(e)?zn(e):e,ur=e=>Y(e)?Zo(e):e;class ni{constructor(t,n,s,r){this.getter=t,this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this.effect=new sr(()=>t(this._value),()=>ms(this,this.effect._dirtyLevel===2?2:3)),this.effect.computed=this,this.effect.active=this._cacheable=!r,this.__v_isReadonly=s}get value(){const t=G(this);return(!t._cacheable||t.effect.dirty)&&Ot(t._value,t._value=t.effect.run())&&ms(t,4),rc(t),t.effect._dirtyLevel>=2&&ms(t,2),t._value}set value(t){this._setter(t)}get _dirty(){return this.effect.dirty}set _dirty(t){this.effect.dirty=t}}function sc(e,t,n=!1){let s,r;const o=M(e);return o?(s=e,r=Le):(s=e.get,r=e.set),new ni(s,r,o||!r,n)}function rc(e){var t;dt&&At&&(e=G(e),Ko(At,(t=e.dep)!=null?t:e.dep=Wo(()=>e.dep=void 0,e instanceof ni?e:void 0)))}function ms(e,t=4,n){e=G(e);const s=e.dep;s&&qo(s,t)}function Re(e){return!!(e&&e.__v_isRef===!0)}function oc(e){return Re(e)?e.value:e}const ic={get:(e,t,n)=>oc(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return Re(r)&&!Re(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function si(e){return Dt(e)?e:new Proxy(e,ic)}/** +* @vue/runtime-core v3.4.21 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function ht(e,t,n,s){try{return s?e(...s):e()}catch(r){Jn(r,t,n)}}function Ie(e,t,n,s){if(M(e)){const o=ht(e,t,n,s);return o&&No(o)&&o.catch(i=>{Jn(i,t,n)}),o}const r=[];for(let o=0;o>>1,r=be[s],o=an(r);oje&&be.splice(t,1)}function fc(e){k(e)?Vt.push(...e):(!lt||!lt.includes(e,e.allowRecurse?Ct+1:Ct))&&Vt.push(e),oi()}function jr(e,t,n=cn?je+1:0){for(;nan(n)-an(s));if(Vt.length=0,lt){lt.push(...t);return}for(lt=t,Ct=0;Cte.id==null?1/0:e.id,dc=(e,t)=>{const n=an(e)-an(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function li(e){Ns=!1,cn=!0,be.sort(dc);try{for(je=0;jece(C)?C.trim():C)),d&&(r=n.map(Rs))}let l,c=s[l=hs(t)]||s[l=hs(Ke(t))];!c&&o&&(c=s[l=hs(jt(t))]),c&&Ie(c,e,6,r);const f=s[l+"Once"];if(f){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Ie(f,e,6,r)}}function ci(e,t,n=!1){const s=t.emitsCache,r=s.get(e);if(r!==void 0)return r;const o=e.emits;let i={},l=!1;if(!M(e)){const c=f=>{const u=ci(f,t,!0);u&&(l=!0,he(i,u))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!o&&!l?(Y(e)&&s.set(e,null),null):(k(o)?o.forEach(c=>i[c]=null):he(i,o),Y(e)&&s.set(e,i),i)}function Yn(e,t){return!e||!Hn(t)?!1:(t=t.slice(2).replace(/Once$/,""),W(e,t[0].toLowerCase()+t.slice(1))||W(e,jt(t))||W(e,t))}let ve=null,Xn=null;function Vn(e){const t=ve;return ve=e,Xn=e&&e.type.__scopeId||null,t}function Ht(e){Xn=e}function Kt(){Xn=null}function ai(e,t=ve,n){if(!t||e._n)return e;const s=(...r)=>{s._d&&eo(-1);const o=Vn(t);let i;try{i=e(...r)}finally{Vn(o),s._d&&eo(1)}return i};return s._n=!0,s._c=!0,s._d=!0,s}function gs(e){const{type:t,vnode:n,proxy:s,withProxy:r,props:o,propsOptions:[i],slots:l,attrs:c,emit:f,render:u,renderCache:d,data:g,setupState:C,ctx:A,inheritAttrs:E}=e;let D,$;const ee=Vn(e);try{if(n.shapeFlag&4){const z=r||s,re=z;D=$e(u.call(re,z,d,o,C,g,A)),$=c}else{const z=t;D=$e(z.length>1?z(o,{attrs:c,slots:l,emit:f}):z(o,null)),$=t.props?c:pc(c)}}catch(z){on.length=0,Jn(z,e,1),D=le(Ue)}let j=D;if($&&E!==!1){const z=Object.keys($),{shapeFlag:re}=j;z.length&&re&7&&(i&&z.some(er)&&($=mc($,i)),j=mt(j,$))}return n.dirs&&(j=mt(j),j.dirs=j.dirs?j.dirs.concat(n.dirs):n.dirs),n.transition&&(j.transition=n.transition),D=j,Vn(ee),D}const pc=e=>{let t;for(const n in e)(n==="class"||n==="style"||Hn(n))&&((t||(t={}))[n]=e[n]);return t},mc=(e,t)=>{const n={};for(const s in e)(!er(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function gc(e,t,n){const{props:s,children:r,component:o}=e,{props:i,children:l,patchFlag:c}=t,f=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return s?Hr(s,i,f):!!i;if(c&8){const u=t.dynamicProps;for(let d=0;de.__isSuspense;function vc(e,t){t&&t.pendingBranch?k(e)?t.effects.push(...e):t.effects.push(e):fc(e)}const Cc=Symbol.for("v-scx"),Ec=()=>Ln(Cc),Tn={};function nn(e,t,n){return fi(e,t,n)}function fi(e,t,{immediate:n,deep:s,flush:r,once:o,onTrack:i,onTrigger:l}=Z){if(t&&o){const H=t;t=(...ye)=>{H(...ye),re()}}const c=me,f=H=>s===!0?H:wt(H,s===!1?1:void 0);let u,d=!1,g=!1;if(Re(e)?(u=()=>e.value,d=ks(e)):Dt(e)?(u=()=>f(e),d=!0):k(e)?(g=!0,d=e.some(H=>Dt(H)||ks(H)),u=()=>e.map(H=>{if(Re(H))return H.value;if(Dt(H))return f(H);if(M(H))return ht(H,c,2)})):M(e)?t?u=()=>ht(e,c,2):u=()=>(C&&C(),Ie(e,c,3,[A])):u=Le,t&&s){const H=u;u=()=>wt(H())}let C,A=H=>{C=j.onStop=()=>{ht(H,c,4),C=j.onStop=void 0}},E;if(ns)if(A=Le,t?n&&Ie(t,c,3,[u(),g?[]:void 0,A]):u(),r==="sync"){const H=Ec();E=H.__watcherHandles||(H.__watcherHandles=[])}else return Le;let D=g?new Array(e.length).fill(Tn):Tn;const $=()=>{if(!(!j.active||!j.dirty))if(t){const H=j.run();(s||d||(g?H.some((ye,V)=>Ot(ye,D[V])):Ot(H,D)))&&(C&&C(),Ie(t,c,3,[H,D===Tn?void 0:g&&D[0]===Tn?[]:D,A]),D=H)}else j.run()};$.allowRecurse=!!t;let ee;r==="sync"?ee=$:r==="post"?ee=()=>Ce($,c&&c.suspense):($.pre=!0,c&&($.id=c.uid),ee=()=>dr($));const j=new sr(u,Le,ee),z=Ul(),re=()=>{j.stop(),z&&tr(z.effects,j)};return t?n?$():D=j.run():r==="post"?Ce(j.run.bind(j),c&&c.suspense):j.run(),E&&E.push(re),re}function wc(e,t,n){const s=this.proxy,r=ce(e)?e.includes(".")?di(s,e):()=>s[e]:e.bind(s,s);let o;M(t)?o=t:(o=t.handler,n=t);const i=mn(this),l=fi(r,o.bind(s),n);return i(),l}function di(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;r0){if(n>=t)return e;n++}if(s=s||new Set,s.has(e))return e;if(s.add(e),Re(e))wt(e.value,t,n,s);else if(k(e))for(let r=0;r{wt(r,t,n,s)});else if(Uo(e))for(const r in e)wt(e[r],t,n,s);return e}function ie(e,t){if(ve===null)return e;const n=ss(ve)||ve.proxy,s=e.dirs||(e.dirs=[]);for(let r=0;r{e.isMounted=!0}),bi(()=>{e.isUnmounting=!0}),e}const xe=[Function,Array],hi={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:xe,onEnter:xe,onAfterEnter:xe,onEnterCancelled:xe,onBeforeLeave:xe,onLeave:xe,onAfterLeave:xe,onLeaveCancelled:xe,onBeforeAppear:xe,onAppear:xe,onAfterAppear:xe,onAppearCancelled:xe},Tc={name:"BaseTransition",props:hi,setup(e,{slots:t}){const n=fa(),s=Ac();return()=>{const r=t.default&&mi(t.default(),!0);if(!r||!r.length)return;let o=r[0];if(r.length>1){for(const g of r)if(g.type!==Ue){o=g;break}}const i=G(e),{mode:l}=i;if(s.isLeaving)return _s(o);const c=qr(o);if(!c)return _s(o);const f=Fs(c,i,s,n);Us(c,f);const u=n.subTree,d=u&&qr(u);if(d&&d.type!==Ue&&!Et(c,d)){const g=Fs(d,i,s,n);if(Us(d,g),l==="out-in")return s.isLeaving=!0,g.afterLeave=()=>{s.isLeaving=!1,n.update.active!==!1&&(n.effect.dirty=!0,n.update())},_s(o);l==="in-out"&&c.type!==Ue&&(g.delayLeave=(C,A,E)=>{const D=pi(s,d);D[String(d.key)]=d,C[ct]=()=>{A(),C[ct]=void 0,delete f.delayedLeave},f.delayedLeave=E})}return o}}},Oc=Tc;function pi(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function Fs(e,t,n,s){const{appear:r,mode:o,persisted:i=!1,onBeforeEnter:l,onEnter:c,onAfterEnter:f,onEnterCancelled:u,onBeforeLeave:d,onLeave:g,onAfterLeave:C,onLeaveCancelled:A,onBeforeAppear:E,onAppear:D,onAfterAppear:$,onAppearCancelled:ee}=t,j=String(e.key),z=pi(n,e),re=(V,oe)=>{V&&Ie(V,s,9,oe)},H=(V,oe)=>{const Q=oe[1];re(V,oe),k(V)?V.every(ge=>ge.length<=1)&&Q():V.length<=1&&Q()},ye={mode:o,persisted:i,beforeEnter(V){let oe=l;if(!n.isMounted)if(r)oe=E||l;else return;V[ct]&&V[ct](!0);const Q=z[j];Q&&Et(e,Q)&&Q.el[ct]&&Q.el[ct](),re(oe,[V])},enter(V){let oe=c,Q=f,ge=u;if(!n.isMounted)if(r)oe=D||c,Q=$||f,ge=ee||u;else return;let I=!1;const ne=V[On]=Te=>{I||(I=!0,Te?re(ge,[V]):re(Q,[V]),ye.delayedLeave&&ye.delayedLeave(),V[On]=void 0)};oe?H(oe,[V,ne]):ne()},leave(V,oe){const Q=String(e.key);if(V[On]&&V[On](!0),n.isUnmounting)return oe();re(d,[V]);let ge=!1;const I=V[ct]=ne=>{ge||(ge=!0,oe(),ne?re(A,[V]):re(C,[V]),V[ct]=void 0,z[Q]===e&&delete z[Q])};z[Q]=e,g?H(g,[V,I]):I()},clone(V){return Fs(V,t,n,s)}};return ye}function _s(e){if(Qn(e))return e=mt(e),e.children=null,e}function qr(e){return Qn(e)?e.children?e.children[0]:void 0:e}function Us(e,t){e.shapeFlag&6&&e.component?Us(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function mi(e,t=!1,n){let s=[],r=0;for(let o=0;o1)for(let o=0;o!!e.type.__asyncLoader,Qn=e=>e.type.__isKeepAlive;function Rc(e,t){gi(e,"a",t)}function xc(e,t){gi(e,"da",t)}function gi(e,t,n=me){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(Zn(t,s,n),n){let r=n.parent;for(;r&&r.parent;)Qn(r.parent.vnode)&&Lc(s,t,n,r),r=r.parent}}function Lc(e,t,n,s){const r=Zn(t,e,s,!0);yi(()=>{tr(s[t],r)},n)}function Zn(e,t,n=me,s=!1){if(n){const r=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...i)=>{if(n.isUnmounted)return;Rt();const l=mn(n),c=Ie(t,n,e,i);return l(),xt(),c});return s?r.unshift(o):r.push(o),o}}const Qe=e=>(t,n=me)=>(!ns||e==="sp")&&Zn(e,(...s)=>t(...s),n),Ic=Qe("bm"),_i=Qe("m"),Pc=Qe("bu"),kc=Qe("u"),bi=Qe("bum"),yi=Qe("um"),Nc=Qe("sp"),Fc=Qe("rtg"),Uc=Qe("rtc");function Dc(e,t=me){Zn("ec",e,t)}function Ds(e,t,n,s){let r;const o=n&&n[s];if(k(e)||ce(e)){r=new Array(e.length);for(let i=0,l=e.length;it(i,l,void 0,o&&o[l]));else{const i=Object.keys(e);r=new Array(i.length);for(let l=0,c=i.length;le?Ii(e)?ss(e)||e.proxy:Vs(e.parent):null,sn=he(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Vs(e.parent),$root:e=>Vs(e.root),$emit:e=>e.emit,$options:e=>hr(e),$forceUpdate:e=>e.f||(e.f=()=>{e.effect.dirty=!0,dr(e.update)}),$nextTick:e=>e.n||(e.n=cc.bind(e.proxy)),$watch:e=>wc.bind(e)}),bs=(e,t)=>e!==Z&&!e.__isScriptSetup&&W(e,t),Vc={get({_:e},t){const{ctx:n,setupState:s,data:r,props:o,accessCache:i,type:l,appContext:c}=e;let f;if(t[0]!=="$"){const C=i[t];if(C!==void 0)switch(C){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return o[t]}else{if(bs(s,t))return i[t]=1,s[t];if(r!==Z&&W(r,t))return i[t]=2,r[t];if((f=e.propsOptions[0])&&W(f,t))return i[t]=3,o[t];if(n!==Z&&W(n,t))return i[t]=4,n[t];Bs&&(i[t]=0)}}const u=sn[t];let d,g;if(u)return t==="$attrs"&&we(e,"get",t),u(e);if((d=l.__cssModules)&&(d=d[t]))return d;if(n!==Z&&W(n,t))return i[t]=4,n[t];if(g=c.config.globalProperties,W(g,t))return g[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:o}=e;return bs(r,t)?(r[t]=n,!0):s!==Z&&W(s,t)?(s[t]=n,!0):W(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,propsOptions:o}},i){let l;return!!n[i]||e!==Z&&W(e,i)||bs(t,i)||(l=o[0])&&W(l,i)||W(s,i)||W(sn,i)||W(r.config.globalProperties,i)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:W(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function Wr(e){return k(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Bs=!0;function Bc(e){const t=hr(e),n=e.proxy,s=e.ctx;Bs=!1,t.beforeCreate&&Gr(t.beforeCreate,e,"bc");const{data:r,computed:o,methods:i,watch:l,provide:c,inject:f,created:u,beforeMount:d,mounted:g,beforeUpdate:C,updated:A,activated:E,deactivated:D,beforeDestroy:$,beforeUnmount:ee,destroyed:j,unmounted:z,render:re,renderTracked:H,renderTriggered:ye,errorCaptured:V,serverPrefetch:oe,expose:Q,inheritAttrs:ge,components:I,directives:ne,filters:Te}=t;if(f&&Mc(f,s,null),i)for(const se in i){const X=i[se];M(X)&&(s[se]=X.bind(n))}if(r){const se=r.call(n,n);Y(se)&&(e.data=zn(se))}if(Bs=!0,o)for(const se in o){const X=o[se],gt=M(X)?X.bind(n,n):M(X.get)?X.get.bind(n,n):Le,yn=!M(X)&&M(X.set)?X.set.bind(n):Le,_t=ki({get:gt,set:yn});Object.defineProperty(s,se,{enumerable:!0,configurable:!0,get:()=>_t.value,set:Ve=>_t.value=Ve})}if(l)for(const se in l)Si(l[se],s,n,se);if(c){const se=M(c)?c.call(n):c;Reflect.ownKeys(se).forEach(X=>{Wc(X,se[X])})}u&&Gr(u,e,"c");function fe(se,X){k(X)?X.forEach(gt=>se(gt.bind(n))):X&&se(X.bind(n))}if(fe(Ic,d),fe(_i,g),fe(Pc,C),fe(kc,A),fe(Rc,E),fe(xc,D),fe(Dc,V),fe(Uc,H),fe(Fc,ye),fe(bi,ee),fe(yi,z),fe(Nc,oe),k(Q))if(Q.length){const se=e.exposed||(e.exposed={});Q.forEach(X=>{Object.defineProperty(se,X,{get:()=>n[X],set:gt=>n[X]=gt})})}else e.exposed||(e.exposed={});re&&e.render===Le&&(e.render=re),ge!=null&&(e.inheritAttrs=ge),I&&(e.components=I),ne&&(e.directives=ne)}function Mc(e,t,n=Le){k(e)&&(e=Ms(e));for(const s in e){const r=e[s];let o;Y(r)?"default"in r?o=Ln(r.from||s,r.default,!0):o=Ln(r.from||s):o=Ln(r),Re(o)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>o.value,set:i=>o.value=i}):t[s]=o}}function Gr(e,t,n){Ie(k(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function Si(e,t,n,s){const r=s.includes(".")?di(n,s):()=>n[s];if(ce(e)){const o=t[e];M(o)&&nn(r,o)}else if(M(e))nn(r,e.bind(n));else if(Y(e))if(k(e))e.forEach(o=>Si(o,t,n,s));else{const o=M(e.handler)?e.handler.bind(n):t[e.handler];M(o)&&nn(r,o,e)}}function hr(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:o,config:{optionMergeStrategies:i}}=e.appContext,l=o.get(t);let c;return l?c=l:!r.length&&!n&&!s?c=t:(c={},r.length&&r.forEach(f=>Bn(c,f,i,!0)),Bn(c,t,i)),Y(t)&&o.set(t,c),c}function Bn(e,t,n,s=!1){const{mixins:r,extends:o}=t;o&&Bn(e,o,n,!0),r&&r.forEach(i=>Bn(e,i,n,!0));for(const i in t)if(!(s&&i==="expose")){const l=$c[i]||n&&n[i];e[i]=l?l(e[i],t[i]):t[i]}return e}const $c={data:zr,props:Jr,emits:Jr,methods:Zt,computed:Zt,beforeCreate:Se,created:Se,beforeMount:Se,mounted:Se,beforeUpdate:Se,updated:Se,beforeDestroy:Se,beforeUnmount:Se,destroyed:Se,unmounted:Se,activated:Se,deactivated:Se,errorCaptured:Se,serverPrefetch:Se,components:Zt,directives:Zt,watch:Hc,provide:zr,inject:jc};function zr(e,t){return t?e?function(){return he(M(e)?e.call(this,this):e,M(t)?t.call(this,this):t)}:t:e}function jc(e,t){return Zt(Ms(e),Ms(t))}function Ms(e){if(k(e)){const t={};for(let n=0;n1)return n&&M(t)?t.call(s&&s.proxy):t}}function Gc(e,t,n,s=!1){const r={},o={};Dn(o,ts,1),e.propsDefaults=Object.create(null),Ci(e,t,r,o);for(const i in e.propsOptions[0])i in r||(r[i]=void 0);n?e.props=s?r:nc(r):e.type.props?e.props=r:e.props=o,e.attrs=o}function zc(e,t,n,s){const{props:r,attrs:o,vnode:{patchFlag:i}}=e,l=G(r),[c]=e.propsOptions;let f=!1;if((s||i>0)&&!(i&16)){if(i&8){const u=e.vnode.dynamicProps;for(let d=0;d{c=!0;const[g,C]=Ei(d,t,!0);he(i,g),C&&l.push(...C)};!n&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}if(!o&&!c)return Y(e)&&s.set(e,Ft),Ft;if(k(o))for(let u=0;u-1,C[1]=E<0||A-1||W(C,"default"))&&l.push(d)}}}const f=[i,l];return Y(e)&&s.set(e,f),f}function Yr(e){return e[0]!=="$"&&!tn(e)}function Xr(e){return e===null?"null":typeof e=="function"?e.name||"":typeof e=="object"&&e.constructor&&e.constructor.name||""}function Qr(e,t){return Xr(e)===Xr(t)}function Zr(e,t){return k(t)?t.findIndex(n=>Qr(n,e)):M(t)&&Qr(t,e)?0:-1}const wi=e=>e[0]==="_"||e==="$stable",pr=e=>k(e)?e.map($e):[$e(e)],Jc=(e,t,n)=>{if(t._n)return t;const s=ai((...r)=>pr(t(...r)),n);return s._c=!1,s},Ai=(e,t,n)=>{const s=e._ctx;for(const r in e){if(wi(r))continue;const o=e[r];if(M(o))t[r]=Jc(r,o,s);else if(o!=null){const i=pr(o);t[r]=()=>i}}},Ti=(e,t)=>{const n=pr(t);e.slots.default=()=>n},Yc=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=G(t),Dn(t,"_",n)):Ai(t,e.slots={})}else e.slots={},t&&Ti(e,t);Dn(e.slots,ts,1)},Xc=(e,t,n)=>{const{vnode:s,slots:r}=e;let o=!0,i=Z;if(s.shapeFlag&32){const l=t._;l?n&&l===1?o=!1:(he(r,t),!n&&l===1&&delete r._):(o=!t.$stable,Ai(t,r)),i=t}else t&&(Ti(e,t),i={default:1});if(o)for(const l in r)!wi(l)&&i[l]==null&&delete r[l]};function js(e,t,n,s,r=!1){if(k(e)){e.forEach((g,C)=>js(g,t&&(k(t)?t[C]:t),n,s,r));return}if(xn(s)&&!r)return;const o=s.shapeFlag&4?ss(s.component)||s.component.proxy:s.el,i=r?null:o,{i:l,r:c}=e,f=t&&t.r,u=l.refs===Z?l.refs={}:l.refs,d=l.setupState;if(f!=null&&f!==c&&(ce(f)?(u[f]=null,W(d,f)&&(d[f]=null)):Re(f)&&(f.value=null)),M(c))ht(c,l,12,[i,u]);else{const g=ce(c),C=Re(c);if(g||C){const A=()=>{if(e.f){const E=g?W(d,c)?d[c]:u[c]:c.value;r?k(E)&&tr(E,o):k(E)?E.includes(o)||E.push(o):g?(u[c]=[o],W(d,c)&&(d[c]=u[c])):(c.value=[o],e.k&&(u[e.k]=c.value))}else g?(u[c]=i,W(d,c)&&(d[c]=i)):C&&(c.value=i,e.k&&(u[e.k]=i))};i?(A.id=-1,Ce(A,n)):A()}}}const Ce=vc;function Qc(e){return Zc(e)}function Zc(e,t){const n=Do();n.__VUE__=!0;const{insert:s,remove:r,patchProp:o,createElement:i,createText:l,createComment:c,setText:f,setElementText:u,parentNode:d,nextSibling:g,setScopeId:C=Le,insertStaticContent:A}=e,E=(a,h,m,b=null,y=null,w=null,O=void 0,v=null,T=!!h.dynamicChildren)=>{if(a===h)return;a&&!Et(a,h)&&(b=Sn(a),Ve(a,y,w,!0),a=null),h.patchFlag===-2&&(T=!1,h.dynamicChildren=null);const{type:S,ref:R,shapeFlag:N}=h;switch(S){case es:D(a,h,m,b);break;case Ue:$(a,h,m,b);break;case In:a==null&&ee(h,m,b,O);break;case _e:I(a,h,m,b,y,w,O,v,T);break;default:N&1?re(a,h,m,b,y,w,O,v,T):N&6?ne(a,h,m,b,y,w,O,v,T):(N&64||N&128)&&S.process(a,h,m,b,y,w,O,v,T,It)}R!=null&&y&&js(R,a&&a.ref,w,h||a,!h)},D=(a,h,m,b)=>{if(a==null)s(h.el=l(h.children),m,b);else{const y=h.el=a.el;h.children!==a.children&&f(y,h.children)}},$=(a,h,m,b)=>{a==null?s(h.el=c(h.children||""),m,b):h.el=a.el},ee=(a,h,m,b)=>{[a.el,a.anchor]=A(a.children,h,m,b,a.el,a.anchor)},j=({el:a,anchor:h},m,b)=>{let y;for(;a&&a!==h;)y=g(a),s(a,m,b),a=y;s(h,m,b)},z=({el:a,anchor:h})=>{let m;for(;a&&a!==h;)m=g(a),r(a),a=m;r(h)},re=(a,h,m,b,y,w,O,v,T)=>{h.type==="svg"?O="svg":h.type==="math"&&(O="mathml"),a==null?H(h,m,b,y,w,O,v,T):oe(a,h,y,w,O,v,T)},H=(a,h,m,b,y,w,O,v)=>{let T,S;const{props:R,shapeFlag:N,transition:P,dirs:F}=a;if(T=a.el=i(a.type,w,R&&R.is,R),N&8?u(T,a.children):N&16&&V(a.children,T,null,b,y,ys(a,w),O,v),F&&bt(a,null,b,"created"),ye(T,a,a.scopeId,O,b),R){for(const J in R)J!=="value"&&!tn(J)&&o(T,J,null,R[J],w,a.children,b,y,We);"value"in R&&o(T,"value",null,R.value,w),(S=R.onVnodeBeforeMount)&&Me(S,b,a)}F&&bt(a,null,b,"beforeMount");const K=ea(y,P);K&&P.beforeEnter(T),s(T,h,m),((S=R&&R.onVnodeMounted)||K||F)&&Ce(()=>{S&&Me(S,b,a),K&&P.enter(T),F&&bt(a,null,b,"mounted")},y)},ye=(a,h,m,b,y)=>{if(m&&C(a,m),b)for(let w=0;w{for(let S=T;S{const v=h.el=a.el;let{patchFlag:T,dynamicChildren:S,dirs:R}=h;T|=a.patchFlag&16;const N=a.props||Z,P=h.props||Z;let F;if(m&&yt(m,!1),(F=P.onVnodeBeforeUpdate)&&Me(F,m,h,a),R&&bt(h,a,m,"beforeUpdate"),m&&yt(m,!0),S?Q(a.dynamicChildren,S,v,m,b,ys(h,y),w):O||X(a,h,v,null,m,b,ys(h,y),w,!1),T>0){if(T&16)ge(v,h,N,P,m,b,y);else if(T&2&&N.class!==P.class&&o(v,"class",null,P.class,y),T&4&&o(v,"style",N.style,P.style,y),T&8){const K=h.dynamicProps;for(let J=0;J{F&&Me(F,m,h,a),R&&bt(h,a,m,"updated")},b)},Q=(a,h,m,b,y,w,O)=>{for(let v=0;v{if(m!==b){if(m!==Z)for(const v in m)!tn(v)&&!(v in b)&&o(a,v,m[v],null,O,h.children,y,w,We);for(const v in b){if(tn(v))continue;const T=b[v],S=m[v];T!==S&&v!=="value"&&o(a,v,S,T,O,h.children,y,w,We)}"value"in b&&o(a,"value",m.value,b.value,O)}},I=(a,h,m,b,y,w,O,v,T)=>{const S=h.el=a?a.el:l(""),R=h.anchor=a?a.anchor:l("");let{patchFlag:N,dynamicChildren:P,slotScopeIds:F}=h;F&&(v=v?v.concat(F):F),a==null?(s(S,m,b),s(R,m,b),V(h.children||[],m,R,y,w,O,v,T)):N>0&&N&64&&P&&a.dynamicChildren?(Q(a.dynamicChildren,P,m,y,w,O,v),(h.key!=null||y&&h===y.subTree)&&Oi(a,h,!0)):X(a,h,m,R,y,w,O,v,T)},ne=(a,h,m,b,y,w,O,v,T)=>{h.slotScopeIds=v,a==null?h.shapeFlag&512?y.ctx.activate(h,m,b,O,T):Te(h,m,b,y,w,O,T):Jt(a,h,T)},Te=(a,h,m,b,y,w,O)=>{const v=a.component=ua(a,b,y);if(Qn(a)&&(v.ctx.renderer=It),da(v),v.asyncDep){if(y&&y.registerDep(v,fe),!a.el){const T=v.subTree=le(Ue);$(null,T,h,m)}}else fe(v,a,h,m,y,w,O)},Jt=(a,h,m)=>{const b=h.component=a.component;if(gc(a,h,m))if(b.asyncDep&&!b.asyncResolved){se(b,h,m);return}else b.next=h,uc(b.update),b.effect.dirty=!0,b.update();else h.el=a.el,b.vnode=h},fe=(a,h,m,b,y,w,O)=>{const v=()=>{if(a.isMounted){let{next:R,bu:N,u:P,parent:F,vnode:K}=a;{const Pt=Ri(a);if(Pt){R&&(R.el=K.el,se(a,R,O)),Pt.asyncDep.then(()=>{a.isUnmounted||v()});return}}let J=R,te;yt(a,!1),R?(R.el=K.el,se(a,R,O)):R=K,N&&Rn(N),(te=R.props&&R.props.onVnodeBeforeUpdate)&&Me(te,F,R,K),yt(a,!0);const de=gs(a),ke=a.subTree;a.subTree=de,E(ke,de,d(ke.el),Sn(ke),a,y,w),R.el=de.el,J===null&&_c(a,de.el),P&&Ce(P,y),(te=R.props&&R.props.onVnodeUpdated)&&Ce(()=>Me(te,F,R,K),y)}else{let R;const{el:N,props:P}=h,{bm:F,m:K,parent:J}=a,te=xn(h);if(yt(a,!1),F&&Rn(F),!te&&(R=P&&P.onVnodeBeforeMount)&&Me(R,J,h),yt(a,!0),N&&ds){const de=()=>{a.subTree=gs(a),ds(N,a.subTree,a,y,null)};te?h.type.__asyncLoader().then(()=>!a.isUnmounted&&de()):de()}else{const de=a.subTree=gs(a);E(null,de,m,b,a,y,w),h.el=de.el}if(K&&Ce(K,y),!te&&(R=P&&P.onVnodeMounted)){const de=h;Ce(()=>Me(R,J,de),y)}(h.shapeFlag&256||J&&xn(J.vnode)&&J.vnode.shapeFlag&256)&&a.a&&Ce(a.a,y),a.isMounted=!0,h=m=b=null}},T=a.effect=new sr(v,Le,()=>dr(S),a.scope),S=a.update=()=>{T.dirty&&T.run()};S.id=a.uid,yt(a,!0),S()},se=(a,h,m)=>{h.component=a;const b=a.vnode.props;a.vnode=h,a.next=null,zc(a,h.props,b,m),Xc(a,h.children,m),Rt(),jr(a),xt()},X=(a,h,m,b,y,w,O,v,T=!1)=>{const S=a&&a.children,R=a?a.shapeFlag:0,N=h.children,{patchFlag:P,shapeFlag:F}=h;if(P>0){if(P&128){yn(S,N,m,b,y,w,O,v,T);return}else if(P&256){gt(S,N,m,b,y,w,O,v,T);return}}F&8?(R&16&&We(S,y,w),N!==S&&u(m,N)):R&16?F&16?yn(S,N,m,b,y,w,O,v,T):We(S,y,w,!0):(R&8&&u(m,""),F&16&&V(N,m,b,y,w,O,v,T))},gt=(a,h,m,b,y,w,O,v,T)=>{a=a||Ft,h=h||Ft;const S=a.length,R=h.length,N=Math.min(S,R);let P;for(P=0;PR?We(a,y,w,!0,!1,N):V(h,m,b,y,w,O,v,T,N)},yn=(a,h,m,b,y,w,O,v,T)=>{let S=0;const R=h.length;let N=a.length-1,P=R-1;for(;S<=N&&S<=P;){const F=a[S],K=h[S]=T?at(h[S]):$e(h[S]);if(Et(F,K))E(F,K,m,null,y,w,O,v,T);else break;S++}for(;S<=N&&S<=P;){const F=a[N],K=h[P]=T?at(h[P]):$e(h[P]);if(Et(F,K))E(F,K,m,null,y,w,O,v,T);else break;N--,P--}if(S>N){if(S<=P){const F=P+1,K=FP)for(;S<=N;)Ve(a[S],y,w,!0),S++;else{const F=S,K=S,J=new Map;for(S=K;S<=P;S++){const Oe=h[S]=T?at(h[S]):$e(h[S]);Oe.key!=null&&J.set(Oe.key,S)}let te,de=0;const ke=P-K+1;let Pt=!1,Lr=0;const Yt=new Array(ke);for(S=0;S=ke){Ve(Oe,y,w,!0);continue}let Be;if(Oe.key!=null)Be=J.get(Oe.key);else for(te=K;te<=P;te++)if(Yt[te-K]===0&&Et(Oe,h[te])){Be=te;break}Be===void 0?Ve(Oe,y,w,!0):(Yt[Be-K]=S+1,Be>=Lr?Lr=Be:Pt=!0,E(Oe,h[Be],m,null,y,w,O,v,T),de++)}const Ir=Pt?ta(Yt):Ft;for(te=Ir.length-1,S=ke-1;S>=0;S--){const Oe=K+S,Be=h[Oe],Pr=Oe+1{const{el:w,type:O,transition:v,children:T,shapeFlag:S}=a;if(S&6){_t(a.component.subTree,h,m,b);return}if(S&128){a.suspense.move(h,m,b);return}if(S&64){O.move(a,h,m,It);return}if(O===_e){s(w,h,m);for(let N=0;Nv.enter(w),y);else{const{leave:N,delayLeave:P,afterLeave:F}=v,K=()=>s(w,h,m),J=()=>{N(w,()=>{K(),F&&F()})};P?P(w,K,J):J()}else s(w,h,m)},Ve=(a,h,m,b=!1,y=!1)=>{const{type:w,props:O,ref:v,children:T,dynamicChildren:S,shapeFlag:R,patchFlag:N,dirs:P}=a;if(v!=null&&js(v,null,m,a,!0),R&256){h.ctx.deactivate(a);return}const F=R&1&&P,K=!xn(a);let J;if(K&&(J=O&&O.onVnodeBeforeUnmount)&&Me(J,h,a),R&6)Sl(a.component,m,b);else{if(R&128){a.suspense.unmount(m,b);return}F&&bt(a,null,h,"beforeUnmount"),R&64?a.type.remove(a,h,m,y,It,b):S&&(w!==_e||N>0&&N&64)?We(S,h,m,!1,!0):(w===_e&&N&384||!y&&R&16)&&We(T,h,m),b&&Rr(a)}(K&&(J=O&&O.onVnodeUnmounted)||F)&&Ce(()=>{J&&Me(J,h,a),F&&bt(a,null,h,"unmounted")},m)},Rr=a=>{const{type:h,el:m,anchor:b,transition:y}=a;if(h===_e){yl(m,b);return}if(h===In){z(a);return}const w=()=>{r(m),y&&!y.persisted&&y.afterLeave&&y.afterLeave()};if(a.shapeFlag&1&&y&&!y.persisted){const{leave:O,delayLeave:v}=y,T=()=>O(m,w);v?v(a.el,w,T):T()}else w()},yl=(a,h)=>{let m;for(;a!==h;)m=g(a),r(a),a=m;r(h)},Sl=(a,h,m)=>{const{bum:b,scope:y,update:w,subTree:O,um:v}=a;b&&Rn(b),y.stop(),w&&(w.active=!1,Ve(O,a,h,m)),v&&Ce(v,h),Ce(()=>{a.isUnmounted=!0},h),h&&h.pendingBranch&&!h.isUnmounted&&a.asyncDep&&!a.asyncResolved&&a.suspenseId===h.pendingId&&(h.deps--,h.deps===0&&h.resolve())},We=(a,h,m,b=!1,y=!1,w=0)=>{for(let O=w;Oa.shapeFlag&6?Sn(a.component.subTree):a.shapeFlag&128?a.suspense.next():g(a.anchor||a.el);let us=!1;const xr=(a,h,m)=>{a==null?h._vnode&&Ve(h._vnode,null,null,!0):E(h._vnode||null,a,h,null,null,null,m),us||(us=!0,jr(),ii(),us=!1),h._vnode=a},It={p:E,um:Ve,m:_t,r:Rr,mt:Te,mc:V,pc:X,pbc:Q,n:Sn,o:e};let fs,ds;return t&&([fs,ds]=t(It)),{render:xr,hydrate:fs,createApp:qc(xr,fs)}}function ys({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function yt({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function ea(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Oi(e,t,n=!1){const s=e.children,r=t.children;if(k(s)&&k(r))for(let o=0;o>1,e[n[l]]0&&(t[s]=n[o-1]),n[o]=s)}}for(o=n.length,i=n[o-1];o-- >0;)n[o]=i,i=t[i];return n}function Ri(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:Ri(t)}const na=e=>e.__isTeleport,_e=Symbol.for("v-fgt"),es=Symbol.for("v-txt"),Ue=Symbol.for("v-cmt"),In=Symbol.for("v-stc"),on=[];let Fe=null;function x(e=!1){on.push(Fe=e?null:[])}function sa(){on.pop(),Fe=on[on.length-1]||null}let un=1;function eo(e){un+=e}function xi(e){return e.dynamicChildren=un>0?Fe||Ft:null,sa(),un>0&&Fe&&Fe.push(e),e}function L(e,t,n,s,r,o){return xi(p(e,t,n,s,r,o,!0))}function Hs(e,t,n,s,r){return xi(le(e,t,n,s,r,!0))}function Ks(e){return e?e.__v_isVNode===!0:!1}function Et(e,t){return e.type===t.type&&e.key===t.key}const ts="__vInternal",Li=({key:e})=>e??null,Pn=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?ce(e)||Re(e)||M(e)?{i:ve,r:e,k:t,f:!!n}:e:null);function p(e,t=null,n=null,s=0,r=null,o=e===_e?0:1,i=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Li(t),ref:t&&Pn(t),scopeId:Xn,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:ve};return l?(mr(c,n),o&128&&e.normalize(c)):n&&(c.shapeFlag|=ce(n)?8:16),un>0&&!i&&Fe&&(c.patchFlag>0||o&6)&&c.patchFlag!==32&&Fe.push(c),c}const le=ra;function ra(e,t=null,n=null,s=0,r=null,o=!1){if((!e||e===bc)&&(e=Ue),Ks(e)){const l=mt(e,t,!0);return n&&mr(l,n),un>0&&!o&&Fe&&(l.shapeFlag&6?Fe[Fe.indexOf(e)]=l:Fe.push(l)),l.patchFlag|=-2,l}if(_a(e)&&(e=e.__vccOpts),t){t=oa(t);let{class:l,style:c}=t;l&&!ce(l)&&(t.class=Ee(l)),Y(c)&&(ei(c)&&!k(c)&&(c=he({},c)),t.style=pn(c))}const i=ce(e)?1:Sc(e)?128:na(e)?64:Y(e)?4:M(e)?2:0;return p(e,t,n,s,r,i,o,!0)}function oa(e){return e?ei(e)||ts in e?he({},e):e:null}function mt(e,t,n=!1){const{props:s,ref:r,patchFlag:o,children:i}=e,l=t?la(s||{},t):s;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&Li(l),ref:t&&t.ref?n&&r?k(r)?r.concat(Pn(t)):[r,Pn(t)]:Pn(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==_e?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&mt(e.ssContent),ssFallback:e.ssFallback&&mt(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function pe(e=" ",t=0){return le(es,null,e,t)}function ia(e,t){const n=le(In,null,e);return n.staticCount=t,n}function B(e="",t=!1){return t?(x(),Hs(Ue,null,e)):le(Ue,null,e)}function $e(e){return e==null||typeof e=="boolean"?le(Ue):k(e)?le(_e,null,e.slice()):typeof e=="object"?at(e):le(es,null,String(e))}function at(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:mt(e)}function mr(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(k(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),mr(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!(ts in t)?t._ctx=ve:r===3&&ve&&(ve.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else M(t)?(t={default:t,_ctx:ve},n=32):(t=String(t),s&64?(n=16,t=[pe(t)]):n=8);e.children=t,e.shapeFlag|=n}function la(...e){const t={};for(let n=0;nme||ve;let Mn,qs;{const e=Do(),t=(n,s)=>{let r;return(r=e[n])||(r=e[n]=[]),r.push(s),o=>{r.length>1?r.forEach(i=>i(o)):r[0](o)}};Mn=t("__VUE_INSTANCE_SETTERS__",n=>me=n),qs=t("__VUE_SSR_SETTERS__",n=>ns=n)}const mn=e=>{const t=me;return Mn(e),e.scope.on(),()=>{e.scope.off(),Mn(t)}},to=()=>{me&&me.scope.off(),Mn(null)};function Ii(e){return e.vnode.shapeFlag&4}let ns=!1;function da(e,t=!1){t&&qs(t);const{props:n,children:s}=e.vnode,r=Ii(e);Gc(e,n,r,t),Yc(e,s);const o=r?ha(e,t):void 0;return t&&qs(!1),o}function ha(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=ti(new Proxy(e.ctx,Vc));const{setup:s}=n;if(s){const r=e.setupContext=s.length>1?ma(e):null,o=mn(e);Rt();const i=ht(s,e,0,[e.props,r]);if(xt(),o(),No(i)){if(i.then(to,to),t)return i.then(l=>{no(e,l,t)}).catch(l=>{Jn(l,e,0)});e.asyncDep=i}else no(e,i,t)}else Pi(e,t)}function no(e,t,n){M(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Y(t)&&(e.setupState=si(t)),Pi(e,n)}let so;function Pi(e,t,n){const s=e.type;if(!e.render){if(!t&&so&&!s.render){const r=s.template||hr(e).template;if(r){const{isCustomElement:o,compilerOptions:i}=e.appContext.config,{delimiters:l,compilerOptions:c}=s,f=he(he({isCustomElement:o,delimiters:l},i),c);s.render=so(r,f)}}e.render=s.render||Le}{const r=mn(e);Rt();try{Bc(e)}finally{xt(),r()}}}function pa(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return we(e,"get","$attrs"),t[n]}}))}function ma(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return pa(e)},slots:e.slots,emit:e.emit,expose:t}}function ss(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(si(ti(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in sn)return sn[n](e)},has(t,n){return n in t||n in sn}}))}function ga(e,t=!0){return M(e)?e.displayName||e.name:e.name||t&&e.__name}function _a(e){return M(e)&&"__vccOpts"in e}const ki=(e,t)=>sc(e,t,ns);function ba(e,t,n){const s=arguments.length;return s===2?Y(t)&&!k(t)?Ks(t)?le(e,null,[t]):le(e,t):le(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&Ks(n)&&(n=[n]),le(e,t,n))}const ya="3.4.21";/** +* @vue/runtime-dom v3.4.21 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/const Sa="http://www.w3.org/2000/svg",va="http://www.w3.org/1998/Math/MathML",ut=typeof document<"u"?document:null,ro=ut&&ut.createElement("template"),Ca={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?ut.createElementNS(Sa,e):t==="mathml"?ut.createElementNS(va,e):ut.createElement(e,n?{is:n}:void 0);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>ut.createTextNode(e),createComment:e=>ut.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>ut.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,o){const i=n?n.previousSibling:t.lastChild;if(r&&(r===o||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===o||!(r=r.nextSibling)););else{ro.innerHTML=s==="svg"?`${e}`:s==="mathml"?`${e}`:e;const l=ro.content;if(s==="svg"||s==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},st="transition",Xt="animation",fn=Symbol("_vtc"),gr=(e,{slots:t})=>ba(Oc,Ea(e),t);gr.displayName="Transition";const Ni={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};gr.props=he({},hi,Ni);const St=(e,t=[])=>{k(e)?e.forEach(n=>n(...t)):e&&e(...t)},oo=e=>e?k(e)?e.some(t=>t.length>1):e.length>1:!1;function Ea(e){const t={};for(const I in e)I in Ni||(t[I]=e[I]);if(e.css===!1)return t;const{name:n="v",type:s,duration:r,enterFromClass:o=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=o,appearActiveClass:f=i,appearToClass:u=l,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:g=`${n}-leave-active`,leaveToClass:C=`${n}-leave-to`}=e,A=wa(r),E=A&&A[0],D=A&&A[1],{onBeforeEnter:$,onEnter:ee,onEnterCancelled:j,onLeave:z,onLeaveCancelled:re,onBeforeAppear:H=$,onAppear:ye=ee,onAppearCancelled:V=j}=t,oe=(I,ne,Te)=>{vt(I,ne?u:l),vt(I,ne?f:i),Te&&Te()},Q=(I,ne)=>{I._isLeaving=!1,vt(I,d),vt(I,C),vt(I,g),ne&&ne()},ge=I=>(ne,Te)=>{const Jt=I?ye:ee,fe=()=>oe(ne,I,Te);St(Jt,[ne,fe]),io(()=>{vt(ne,I?c:o),rt(ne,I?u:l),oo(Jt)||lo(ne,s,E,fe)})};return he(t,{onBeforeEnter(I){St($,[I]),rt(I,o),rt(I,i)},onBeforeAppear(I){St(H,[I]),rt(I,c),rt(I,f)},onEnter:ge(!1),onAppear:ge(!0),onLeave(I,ne){I._isLeaving=!0;const Te=()=>Q(I,ne);rt(I,d),Oa(),rt(I,g),io(()=>{I._isLeaving&&(vt(I,d),rt(I,C),oo(z)||lo(I,s,D,Te))}),St(z,[I,Te])},onEnterCancelled(I){oe(I,!1),St(j,[I])},onAppearCancelled(I){oe(I,!0),St(V,[I])},onLeaveCancelled(I){Q(I),St(re,[I])}})}function wa(e){if(e==null)return null;if(Y(e))return[Ss(e.enter),Ss(e.leave)];{const t=Ss(e);return[t,t]}}function Ss(e){return Tl(e)}function rt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[fn]||(e[fn]=new Set)).add(t)}function vt(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[fn];n&&(n.delete(t),n.size||(e[fn]=void 0))}function io(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Aa=0;function lo(e,t,n,s){const r=e._endId=++Aa,o=()=>{r===e._endId&&s()};if(n)return setTimeout(o,n);const{type:i,timeout:l,propCount:c}=Ta(e,t);if(!i)return s();const f=i+"end";let u=0;const d=()=>{e.removeEventListener(f,g),o()},g=C=>{C.target===e&&++u>=c&&d()};setTimeout(()=>{u(n[A]||"").split(", "),r=s(`${st}Delay`),o=s(`${st}Duration`),i=co(r,o),l=s(`${Xt}Delay`),c=s(`${Xt}Duration`),f=co(l,c);let u=null,d=0,g=0;t===st?i>0&&(u=st,d=i,g=o.length):t===Xt?f>0&&(u=Xt,d=f,g=c.length):(d=Math.max(i,f),u=d>0?i>f?st:Xt:null,g=u?u===st?o.length:c.length:0);const C=u===st&&/\b(transform|all)(,|$)/.test(s(`${st}Property`).toString());return{type:u,timeout:d,propCount:g,hasTransform:C}}function co(e,t){for(;e.lengthao(n)+ao(e[s])))}function ao(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Oa(){return document.body.offsetHeight}function Ra(e,t,n){const s=e[fn];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const uo=Symbol("_vod"),xa=Symbol("_vsh"),La=Symbol(""),Ia=/(^|;)\s*display\s*:/;function Pa(e,t,n){const s=e.style,r=ce(n);let o=!1;if(n&&!r){if(t)if(ce(t))for(const i of t.split(";")){const l=i.slice(0,i.indexOf(":")).trim();n[l]==null&&kn(s,l,"")}else for(const i in t)n[i]==null&&kn(s,i,"");for(const i in n)i==="display"&&(o=!0),kn(s,i,n[i])}else if(r){if(t!==n){const i=s[La];i&&(n+=";"+i),s.cssText=n,o=Ia.test(n)}}else t&&e.removeAttribute("style");uo in e&&(e[uo]=o?s.display:"",e[xa]&&(s.display="none"))}const fo=/\s*!important$/;function kn(e,t,n){if(k(n))n.forEach(s=>kn(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=ka(e,t);fo.test(n)?e.setProperty(jt(s),n.replace(fo,""),"important"):e[s]=n}}const ho=["Webkit","Moz","ms"],vs={};function ka(e,t){const n=vs[t];if(n)return n;let s=Ke(t);if(s!=="filter"&&s in e)return vs[t]=s;s=Wn(s);for(let r=0;rCs||(Ba.then(()=>Cs=0),Cs=Date.now());function $a(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;Ie(ja(s,n.value),t,5,[s])};return n.value=e,n.attached=Ma(),n}function ja(e,t){if(k(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>r=>!r._stopped&&s&&s(r))}else return t}const _o=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Ha=(e,t,n,s,r,o,i,l,c)=>{const f=r==="svg";t==="class"?Ra(e,s,f):t==="style"?Pa(e,n,s):Hn(t)?er(t)||Da(e,t,n,s,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Ka(e,t,s,f))?Fa(e,t,s,o,i,l,c):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),Na(e,t,s,f))};function Ka(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&_o(t)&&M(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const r=e.tagName;if(r==="IMG"||r==="VIDEO"||r==="CANVAS"||r==="SOURCE")return!1}return _o(t)&&ce(n)?!1:t in e}const Mt=e=>{const t=e.props["onUpdate:modelValue"]||!1;return k(t)?n=>Rn(t,n):t};function qa(e){e.target.composing=!0}function bo(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Ye=Symbol("_assign"),en={created(e,{modifiers:{lazy:t,trim:n,number:s}},r){e[Ye]=Mt(r);const o=s||r.props&&r.props.type==="number";ft(e,t?"change":"input",i=>{if(i.target.composing)return;let l=e.value;n&&(l=l.trim()),o&&(l=Rs(l)),e[Ye](l)}),n&&ft(e,"change",()=>{e.value=e.value.trim()}),t||(ft(e,"compositionstart",qa),ft(e,"compositionend",bo),ft(e,"change",bo))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,modifiers:{lazy:n,trim:s,number:r}},o){if(e[Ye]=Mt(o),e.composing)return;const i=r||e.type==="number"?Rs(e.value):e.value,l=t??"";i!==l&&(document.activeElement===e&&e.type!=="range"&&(n||s&&e.value.trim()===l)||(e.value=l))}},ot={deep:!0,created(e,t,n){e[Ye]=Mt(n),ft(e,"change",()=>{const s=e._modelValue,r=Fi(e),o=e.checked,i=e[Ye];if(k(s)){const l=Bo(s,r),c=l!==-1;if(o&&!c)i(s.concat(r));else if(!o&&c){const f=[...s];f.splice(l,1),i(f)}}else if(Kn(s)){const l=new Set(s);o?l.add(r):l.delete(r),i(l)}else i(Ui(e,o))})},mounted:yo,beforeUpdate(e,t,n){e[Ye]=Mt(n),yo(e,t,n)}};function yo(e,{value:t,oldValue:n},s){e._modelValue=t,k(t)?e.checked=Bo(t,s.props.value)>-1:Kn(t)?e.checked=t.has(s.props.value):t!==n&&(e.checked=Bt(t,Ui(e,!0)))}const Ge={created(e,{value:t},n){e.checked=Bt(t,n.props.value),e[Ye]=Mt(n),ft(e,"change",()=>{e[Ye](Fi(e))})},beforeUpdate(e,{value:t,oldValue:n},s){e[Ye]=Mt(s),t!==n&&(e.checked=Bt(t,s.props.value))}};function Fi(e){return"_value"in e?e._value:e.value}function Ui(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const Wa=he({patchProp:Ha},Ca);let So;function Ga(){return So||(So=Qc(Wa))}const za=(...e)=>{const t=Ga().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=Ya(s);if(!r)return;const o=t._component;!M(o)&&!o.render&&!o.template&&(o.template=r.innerHTML),r.innerHTML="";const i=n(r,!1,Ja(r));return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),i},t};function Ja(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Ya(e){return ce(e)?document.querySelector(e):e}function Di(e,t){return function(){return e.apply(t,arguments)}}const{toString:Xa}=Object.prototype,{getPrototypeOf:_r}=Object,rs=(e=>t=>{const n=Xa.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),qe=e=>(e=e.toLowerCase(),t=>rs(t)===e),os=e=>t=>typeof t===e,{isArray:qt}=Array,dn=os("undefined");function Qa(e){return e!==null&&!dn(e)&&e.constructor!==null&&!dn(e.constructor)&&Pe(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const Vi=qe("ArrayBuffer");function Za(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&Vi(e.buffer),t}const eu=os("string"),Pe=os("function"),Bi=os("number"),is=e=>e!==null&&typeof e=="object",tu=e=>e===!0||e===!1,Nn=e=>{if(rs(e)!=="object")return!1;const t=_r(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Symbol.toStringTag in e)&&!(Symbol.iterator in e)},nu=qe("Date"),su=qe("File"),ru=qe("Blob"),ou=qe("FileList"),iu=e=>is(e)&&Pe(e.pipe),lu=e=>{let t;return e&&(typeof FormData=="function"&&e instanceof FormData||Pe(e.append)&&((t=rs(e))==="formdata"||t==="object"&&Pe(e.toString)&&e.toString()==="[object FormData]"))},cu=qe("URLSearchParams"),au=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function gn(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;let s,r;if(typeof e!="object"&&(e=[e]),qt(e))for(s=0,r=e.length;s0;)if(r=n[s],t===r.toLowerCase())return r;return null}const $i=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,ji=e=>!dn(e)&&e!==$i;function Ws(){const{caseless:e}=ji(this)&&this||{},t={},n=(s,r)=>{const o=e&&Mi(t,r)||r;Nn(t[o])&&Nn(s)?t[o]=Ws(t[o],s):Nn(s)?t[o]=Ws({},s):qt(s)?t[o]=s.slice():t[o]=s};for(let s=0,r=arguments.length;s(gn(t,(r,o)=>{n&&Pe(r)?e[o]=Di(r,n):e[o]=r},{allOwnKeys:s}),e),fu=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),du=(e,t,n,s)=>{e.prototype=Object.create(t.prototype,s),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},hu=(e,t,n,s)=>{let r,o,i;const l={};if(t=t||{},e==null)return t;do{for(r=Object.getOwnPropertyNames(e),o=r.length;o-- >0;)i=r[o],(!s||s(i,e,t))&&!l[i]&&(t[i]=e[i],l[i]=!0);e=n!==!1&&_r(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},pu=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const s=e.indexOf(t,n);return s!==-1&&s===n},mu=e=>{if(!e)return null;if(qt(e))return e;let t=e.length;if(!Bi(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},gu=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&_r(Uint8Array)),_u=(e,t)=>{const s=(e&&e[Symbol.iterator]).call(e);let r;for(;(r=s.next())&&!r.done;){const o=r.value;t.call(e,o[0],o[1])}},bu=(e,t)=>{let n;const s=[];for(;(n=e.exec(t))!==null;)s.push(n);return s},yu=qe("HTMLFormElement"),Su=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,s,r){return s.toUpperCase()+r}),vo=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),vu=qe("RegExp"),Hi=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),s={};gn(n,(r,o)=>{let i;(i=t(r,o,e))!==!1&&(s[o]=i||r)}),Object.defineProperties(e,s)},Cu=e=>{Hi(e,(t,n)=>{if(Pe(e)&&["arguments","caller","callee"].indexOf(n)!==-1)return!1;const s=e[n];if(Pe(s)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},Eu=(e,t)=>{const n={},s=r=>{r.forEach(o=>{n[o]=!0})};return qt(e)?s(e):s(String(e).split(t)),n},wu=()=>{},Au=(e,t)=>(e=+e,Number.isFinite(e)?e:t),Es="abcdefghijklmnopqrstuvwxyz",Co="0123456789",Ki={DIGIT:Co,ALPHA:Es,ALPHA_DIGIT:Es+Es.toUpperCase()+Co},Tu=(e=16,t=Ki.ALPHA_DIGIT)=>{let n="";const{length:s}=t;for(;e--;)n+=t[Math.random()*s|0];return n};function Ou(e){return!!(e&&Pe(e.append)&&e[Symbol.toStringTag]==="FormData"&&e[Symbol.iterator])}const Ru=e=>{const t=new Array(10),n=(s,r)=>{if(is(s)){if(t.indexOf(s)>=0)return;if(!("toJSON"in s)){t[r]=s;const o=qt(s)?[]:{};return gn(s,(i,l)=>{const c=n(i,r+1);!dn(c)&&(o[l]=c)}),t[r]=void 0,o}}return s};return n(e,0)},xu=qe("AsyncFunction"),Lu=e=>e&&(is(e)||Pe(e))&&Pe(e.then)&&Pe(e.catch),_={isArray:qt,isArrayBuffer:Vi,isBuffer:Qa,isFormData:lu,isArrayBufferView:Za,isString:eu,isNumber:Bi,isBoolean:tu,isObject:is,isPlainObject:Nn,isUndefined:dn,isDate:nu,isFile:su,isBlob:ru,isRegExp:vu,isFunction:Pe,isStream:iu,isURLSearchParams:cu,isTypedArray:gu,isFileList:ou,forEach:gn,merge:Ws,extend:uu,trim:au,stripBOM:fu,inherits:du,toFlatObject:hu,kindOf:rs,kindOfTest:qe,endsWith:pu,toArray:mu,forEachEntry:_u,matchAll:bu,isHTMLForm:yu,hasOwnProperty:vo,hasOwnProp:vo,reduceDescriptors:Hi,freezeMethods:Cu,toObjectSet:Eu,toCamelCase:Su,noop:wu,toFiniteNumber:Au,findKey:Mi,global:$i,isContextDefined:ji,ALPHABET:Ki,generateString:Tu,isSpecCompliantForm:Ou,toJSONObject:Ru,isAsyncFn:xu,isThenable:Lu};function q(e,t,n,s,r){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),s&&(this.request=s),r&&(this.response=r)}_.inherits(q,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:_.toJSONObject(this.config),code:this.code,status:this.response&&this.response.status?this.response.status:null}}});const qi=q.prototype,Wi={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(e=>{Wi[e]={value:e}});Object.defineProperties(q,Wi);Object.defineProperty(qi,"isAxiosError",{value:!0});q.from=(e,t,n,s,r,o)=>{const i=Object.create(qi);return _.toFlatObject(e,i,function(c){return c!==Error.prototype},l=>l!=="isAxiosError"),q.call(i,e.message,t,n,s,r),i.cause=e,i.name=e.name,o&&Object.assign(i,o),i};const Iu=null;function Gs(e){return _.isPlainObject(e)||_.isArray(e)}function Gi(e){return _.endsWith(e,"[]")?e.slice(0,-2):e}function Eo(e,t,n){return e?e.concat(t).map(function(r,o){return r=Gi(r),!n&&o?"["+r+"]":r}).join(n?".":""):t}function Pu(e){return _.isArray(e)&&!e.some(Gs)}const ku=_.toFlatObject(_,{},null,function(t){return/^is[A-Z]/.test(t)});function ls(e,t,n){if(!_.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,n=_.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(E,D){return!_.isUndefined(D[E])});const s=n.metaTokens,r=n.visitor||u,o=n.dots,i=n.indexes,c=(n.Blob||typeof Blob<"u"&&Blob)&&_.isSpecCompliantForm(t);if(!_.isFunction(r))throw new TypeError("visitor must be a function");function f(A){if(A===null)return"";if(_.isDate(A))return A.toISOString();if(!c&&_.isBlob(A))throw new q("Blob is not supported. Use a Buffer instead.");return _.isArrayBuffer(A)||_.isTypedArray(A)?c&&typeof Blob=="function"?new Blob([A]):Buffer.from(A):A}function u(A,E,D){let $=A;if(A&&!D&&typeof A=="object"){if(_.endsWith(E,"{}"))E=s?E:E.slice(0,-2),A=JSON.stringify(A);else if(_.isArray(A)&&Pu(A)||(_.isFileList(A)||_.endsWith(E,"[]"))&&($=_.toArray(A)))return E=Gi(E),$.forEach(function(j,z){!(_.isUndefined(j)||j===null)&&t.append(i===!0?Eo([E],z,o):i===null?E:E+"[]",f(j))}),!1}return Gs(A)?!0:(t.append(Eo(D,E,o),f(A)),!1)}const d=[],g=Object.assign(ku,{defaultVisitor:u,convertValue:f,isVisitable:Gs});function C(A,E){if(!_.isUndefined(A)){if(d.indexOf(A)!==-1)throw Error("Circular reference detected in "+E.join("."));d.push(A),_.forEach(A,function($,ee){(!(_.isUndefined($)||$===null)&&r.call(t,$,_.isString(ee)?ee.trim():ee,E,g))===!0&&C($,E?E.concat(ee):[ee])}),d.pop()}}if(!_.isObject(e))throw new TypeError("data must be an object");return C(e),t}function wo(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(s){return t[s]})}function br(e,t){this._pairs=[],e&&ls(e,this,t)}const zi=br.prototype;zi.append=function(t,n){this._pairs.push([t,n])};zi.toString=function(t){const n=t?function(s){return t.call(this,s,wo)}:wo;return this._pairs.map(function(r){return n(r[0])+"="+n(r[1])},"").join("&")};function Nu(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function Ji(e,t,n){if(!t)return e;const s=n&&n.encode||Nu,r=n&&n.serialize;let o;if(r?o=r(t,n):o=_.isURLSearchParams(t)?t.toString():new br(t,n).toString(s),o){const i=e.indexOf("#");i!==-1&&(e=e.slice(0,i)),e+=(e.indexOf("?")===-1?"?":"&")+o}return e}class Ao{constructor(){this.handlers=[]}use(t,n,s){return this.handlers.push({fulfilled:t,rejected:n,synchronous:s?s.synchronous:!1,runWhen:s?s.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){_.forEach(this.handlers,function(s){s!==null&&t(s)})}}const Yi={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},Fu=typeof URLSearchParams<"u"?URLSearchParams:br,Uu=typeof FormData<"u"?FormData:null,Du=typeof Blob<"u"?Blob:null,Vu={isBrowser:!0,classes:{URLSearchParams:Fu,FormData:Uu,Blob:Du},protocols:["http","https","file","blob","url","data"]},Xi=typeof window<"u"&&typeof document<"u",Bu=(e=>Xi&&["ReactNative","NativeScript","NS"].indexOf(e)<0)(typeof navigator<"u"&&navigator.product),Mu=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",$u=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:Xi,hasStandardBrowserEnv:Bu,hasStandardBrowserWebWorkerEnv:Mu},Symbol.toStringTag,{value:"Module"})),He={...$u,...Vu};function ju(e,t){return ls(e,new He.classes.URLSearchParams,Object.assign({visitor:function(n,s,r,o){return He.isNode&&_.isBuffer(n)?(this.append(s,n.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)}},t))}function Hu(e){return _.matchAll(/\w+|\[(\w*)]/g,e).map(t=>t[0]==="[]"?"":t[1]||t[0])}function Ku(e){const t={},n=Object.keys(e);let s;const r=n.length;let o;for(s=0;s=n.length;return i=!i&&_.isArray(r)?r.length:i,c?(_.hasOwnProp(r,i)?r[i]=[r[i],s]:r[i]=s,!l):((!r[i]||!_.isObject(r[i]))&&(r[i]=[]),t(n,s,r[i],o)&&_.isArray(r[i])&&(r[i]=Ku(r[i])),!l)}if(_.isFormData(e)&&_.isFunction(e.entries)){const n={};return _.forEachEntry(e,(s,r)=>{t(Hu(s),r,n,0)}),n}return null}function qu(e,t,n){if(_.isString(e))try{return(t||JSON.parse)(e),_.trim(e)}catch(s){if(s.name!=="SyntaxError")throw s}return(n||JSON.stringify)(e)}const yr={transitional:Yi,adapter:["xhr","http"],transformRequest:[function(t,n){const s=n.getContentType()||"",r=s.indexOf("application/json")>-1,o=_.isObject(t);if(o&&_.isHTMLForm(t)&&(t=new FormData(t)),_.isFormData(t))return r?JSON.stringify(Qi(t)):t;if(_.isArrayBuffer(t)||_.isBuffer(t)||_.isStream(t)||_.isFile(t)||_.isBlob(t))return t;if(_.isArrayBufferView(t))return t.buffer;if(_.isURLSearchParams(t))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let l;if(o){if(s.indexOf("application/x-www-form-urlencoded")>-1)return ju(t,this.formSerializer).toString();if((l=_.isFileList(t))||s.indexOf("multipart/form-data")>-1){const c=this.env&&this.env.FormData;return ls(l?{"files[]":t}:t,c&&new c,this.formSerializer)}}return o||r?(n.setContentType("application/json",!1),qu(t)):t}],transformResponse:[function(t){const n=this.transitional||yr.transitional,s=n&&n.forcedJSONParsing,r=this.responseType==="json";if(t&&_.isString(t)&&(s&&!this.responseType||r)){const i=!(n&&n.silentJSONParsing)&&r;try{return JSON.parse(t)}catch(l){if(i)throw l.name==="SyntaxError"?q.from(l,q.ERR_BAD_RESPONSE,this,null,this.response):l}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:He.classes.FormData,Blob:He.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};_.forEach(["delete","get","head","post","put","patch"],e=>{yr.headers[e]={}});const Sr=yr,Wu=_.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Gu=e=>{const t={};let n,s,r;return e&&e.split(` +`).forEach(function(i){r=i.indexOf(":"),n=i.substring(0,r).trim().toLowerCase(),s=i.substring(r+1).trim(),!(!n||t[n]&&Wu[n])&&(n==="set-cookie"?t[n]?t[n].push(s):t[n]=[s]:t[n]=t[n]?t[n]+", "+s:s)}),t},To=Symbol("internals");function Qt(e){return e&&String(e).trim().toLowerCase()}function Fn(e){return e===!1||e==null?e:_.isArray(e)?e.map(Fn):String(e)}function zu(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let s;for(;s=n.exec(e);)t[s[1]]=s[2];return t}const Ju=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function ws(e,t,n,s,r){if(_.isFunction(s))return s.call(this,t,n);if(r&&(t=n),!!_.isString(t)){if(_.isString(s))return t.indexOf(s)!==-1;if(_.isRegExp(s))return s.test(t)}}function Yu(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,s)=>n.toUpperCase()+s)}function Xu(e,t){const n=_.toCamelCase(" "+t);["get","set","has"].forEach(s=>{Object.defineProperty(e,s+n,{value:function(r,o,i){return this[s].call(this,t,r,o,i)},configurable:!0})})}class cs{constructor(t){t&&this.set(t)}set(t,n,s){const r=this;function o(l,c,f){const u=Qt(c);if(!u)throw new Error("header name must be a non-empty string");const d=_.findKey(r,u);(!d||r[d]===void 0||f===!0||f===void 0&&r[d]!==!1)&&(r[d||c]=Fn(l))}const i=(l,c)=>_.forEach(l,(f,u)=>o(f,u,c));return _.isPlainObject(t)||t instanceof this.constructor?i(t,n):_.isString(t)&&(t=t.trim())&&!Ju(t)?i(Gu(t),n):t!=null&&o(n,t,s),this}get(t,n){if(t=Qt(t),t){const s=_.findKey(this,t);if(s){const r=this[s];if(!n)return r;if(n===!0)return zu(r);if(_.isFunction(n))return n.call(this,r,s);if(_.isRegExp(n))return n.exec(r);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=Qt(t),t){const s=_.findKey(this,t);return!!(s&&this[s]!==void 0&&(!n||ws(this,this[s],s,n)))}return!1}delete(t,n){const s=this;let r=!1;function o(i){if(i=Qt(i),i){const l=_.findKey(s,i);l&&(!n||ws(s,s[l],l,n))&&(delete s[l],r=!0)}}return _.isArray(t)?t.forEach(o):o(t),r}clear(t){const n=Object.keys(this);let s=n.length,r=!1;for(;s--;){const o=n[s];(!t||ws(this,this[o],o,t,!0))&&(delete this[o],r=!0)}return r}normalize(t){const n=this,s={};return _.forEach(this,(r,o)=>{const i=_.findKey(s,o);if(i){n[i]=Fn(r),delete n[o];return}const l=t?Yu(o):String(o).trim();l!==o&&delete n[o],n[l]=Fn(r),s[l]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return _.forEach(this,(s,r)=>{s!=null&&s!==!1&&(n[r]=t&&_.isArray(s)?s.join(", "):s)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(` +`)}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const s=new this(t);return n.forEach(r=>s.set(r)),s}static accessor(t){const s=(this[To]=this[To]={accessors:{}}).accessors,r=this.prototype;function o(i){const l=Qt(i);s[l]||(Xu(r,i),s[l]=!0)}return _.isArray(t)?t.forEach(o):o(t),this}}cs.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);_.reduceDescriptors(cs.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(s){this[n]=s}}});_.freezeMethods(cs);const Xe=cs;function As(e,t){const n=this||Sr,s=t||n,r=Xe.from(s.headers);let o=s.data;return _.forEach(e,function(l){o=l.call(n,o,r.normalize(),t?t.status:void 0)}),r.normalize(),o}function Zi(e){return!!(e&&e.__CANCEL__)}function _n(e,t,n){q.call(this,e??"canceled",q.ERR_CANCELED,t,n),this.name="CanceledError"}_.inherits(_n,q,{__CANCEL__:!0});function Qu(e,t,n){const s=n.config.validateStatus;!n.status||!s||s(n.status)?e(n):t(new q("Request failed with status code "+n.status,[q.ERR_BAD_REQUEST,q.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}const Zu=He.hasStandardBrowserEnv?{write(e,t,n,s,r,o){const i=[e+"="+encodeURIComponent(t)];_.isNumber(n)&&i.push("expires="+new Date(n).toGMTString()),_.isString(s)&&i.push("path="+s),_.isString(r)&&i.push("domain="+r),o===!0&&i.push("secure"),document.cookie=i.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function ef(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function tf(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function el(e,t){return e&&!ef(t)?tf(e,t):t}const nf=He.hasStandardBrowserEnv?function(){const t=/(msie|trident)/i.test(navigator.userAgent),n=document.createElement("a");let s;function r(o){let i=o;return t&&(n.setAttribute("href",i),i=n.href),n.setAttribute("href",i),{href:n.href,protocol:n.protocol?n.protocol.replace(/:$/,""):"",host:n.host,search:n.search?n.search.replace(/^\?/,""):"",hash:n.hash?n.hash.replace(/^#/,""):"",hostname:n.hostname,port:n.port,pathname:n.pathname.charAt(0)==="/"?n.pathname:"/"+n.pathname}}return s=r(window.location.href),function(i){const l=_.isString(i)?r(i):i;return l.protocol===s.protocol&&l.host===s.host}}():function(){return function(){return!0}}();function sf(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function rf(e,t){e=e||10;const n=new Array(e),s=new Array(e);let r=0,o=0,i;return t=t!==void 0?t:1e3,function(c){const f=Date.now(),u=s[o];i||(i=f),n[r]=c,s[r]=f;let d=o,g=0;for(;d!==r;)g+=n[d++],d=d%e;if(r=(r+1)%e,r===o&&(o=(o+1)%e),f-i{const o=r.loaded,i=r.lengthComputable?r.total:void 0,l=o-n,c=s(l),f=o<=i;n=o;const u={loaded:o,total:i,progress:i?o/i:void 0,bytes:l,rate:c||void 0,estimated:c&&i&&f?(i-o)/c:void 0,event:r};u[t?"download":"upload"]=!0,e(u)}}const of=typeof XMLHttpRequest<"u",lf=of&&function(e){return new Promise(function(n,s){let r=e.data;const o=Xe.from(e.headers).normalize();let{responseType:i,withXSRFToken:l}=e,c;function f(){e.cancelToken&&e.cancelToken.unsubscribe(c),e.signal&&e.signal.removeEventListener("abort",c)}let u;if(_.isFormData(r)){if(He.hasStandardBrowserEnv||He.hasStandardBrowserWebWorkerEnv)o.setContentType(!1);else if((u=o.getContentType())!==!1){const[E,...D]=u?u.split(";").map($=>$.trim()).filter(Boolean):[];o.setContentType([E||"multipart/form-data",...D].join("; "))}}let d=new XMLHttpRequest;if(e.auth){const E=e.auth.username||"",D=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";o.set("Authorization","Basic "+btoa(E+":"+D))}const g=el(e.baseURL,e.url);d.open(e.method.toUpperCase(),Ji(g,e.params,e.paramsSerializer),!0),d.timeout=e.timeout;function C(){if(!d)return;const E=Xe.from("getAllResponseHeaders"in d&&d.getAllResponseHeaders()),$={data:!i||i==="text"||i==="json"?d.responseText:d.response,status:d.status,statusText:d.statusText,headers:E,config:e,request:d};Qu(function(j){n(j),f()},function(j){s(j),f()},$),d=null}if("onloadend"in d?d.onloadend=C:d.onreadystatechange=function(){!d||d.readyState!==4||d.status===0&&!(d.responseURL&&d.responseURL.indexOf("file:")===0)||setTimeout(C)},d.onabort=function(){d&&(s(new q("Request aborted",q.ECONNABORTED,e,d)),d=null)},d.onerror=function(){s(new q("Network Error",q.ERR_NETWORK,e,d)),d=null},d.ontimeout=function(){let D=e.timeout?"timeout of "+e.timeout+"ms exceeded":"timeout exceeded";const $=e.transitional||Yi;e.timeoutErrorMessage&&(D=e.timeoutErrorMessage),s(new q(D,$.clarifyTimeoutError?q.ETIMEDOUT:q.ECONNABORTED,e,d)),d=null},He.hasStandardBrowserEnv&&(l&&_.isFunction(l)&&(l=l(e)),l||l!==!1&&nf(g))){const E=e.xsrfHeaderName&&e.xsrfCookieName&&Zu.read(e.xsrfCookieName);E&&o.set(e.xsrfHeaderName,E)}r===void 0&&o.setContentType(null),"setRequestHeader"in d&&_.forEach(o.toJSON(),function(D,$){d.setRequestHeader($,D)}),_.isUndefined(e.withCredentials)||(d.withCredentials=!!e.withCredentials),i&&i!=="json"&&(d.responseType=e.responseType),typeof e.onDownloadProgress=="function"&&d.addEventListener("progress",Oo(e.onDownloadProgress,!0)),typeof e.onUploadProgress=="function"&&d.upload&&d.upload.addEventListener("progress",Oo(e.onUploadProgress)),(e.cancelToken||e.signal)&&(c=E=>{d&&(s(!E||E.type?new _n(null,e,d):E),d.abort(),d=null)},e.cancelToken&&e.cancelToken.subscribe(c),e.signal&&(e.signal.aborted?c():e.signal.addEventListener("abort",c)));const A=sf(g);if(A&&He.protocols.indexOf(A)===-1){s(new q("Unsupported protocol "+A+":",q.ERR_BAD_REQUEST,e));return}d.send(r||null)})},zs={http:Iu,xhr:lf};_.forEach(zs,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch{}Object.defineProperty(e,"adapterName",{value:t})}});const Ro=e=>`- ${e}`,cf=e=>_.isFunction(e)||e===null||e===!1,tl={getAdapter:e=>{e=_.isArray(e)?e:[e];const{length:t}=e;let n,s;const r={};for(let o=0;o`adapter ${l} `+(c===!1?"is not supported by the environment":"is not available in the build"));let i=t?o.length>1?`since : +`+o.map(Ro).join(` +`):" "+Ro(o[0]):"as no adapter specified";throw new q("There is no suitable adapter to dispatch the request "+i,"ERR_NOT_SUPPORT")}return s},adapters:zs};function Ts(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new _n(null,e)}function xo(e){return Ts(e),e.headers=Xe.from(e.headers),e.data=As.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),tl.getAdapter(e.adapter||Sr.adapter)(e).then(function(s){return Ts(e),s.data=As.call(e,e.transformResponse,s),s.headers=Xe.from(s.headers),s},function(s){return Zi(s)||(Ts(e),s&&s.response&&(s.response.data=As.call(e,e.transformResponse,s.response),s.response.headers=Xe.from(s.response.headers))),Promise.reject(s)})}const Lo=e=>e instanceof Xe?{...e}:e;function $t(e,t){t=t||{};const n={};function s(f,u,d){return _.isPlainObject(f)&&_.isPlainObject(u)?_.merge.call({caseless:d},f,u):_.isPlainObject(u)?_.merge({},u):_.isArray(u)?u.slice():u}function r(f,u,d){if(_.isUndefined(u)){if(!_.isUndefined(f))return s(void 0,f,d)}else return s(f,u,d)}function o(f,u){if(!_.isUndefined(u))return s(void 0,u)}function i(f,u){if(_.isUndefined(u)){if(!_.isUndefined(f))return s(void 0,f)}else return s(void 0,u)}function l(f,u,d){if(d in t)return s(f,u);if(d in e)return s(void 0,f)}const c={url:o,method:o,data:o,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:l,headers:(f,u)=>r(Lo(f),Lo(u),!0)};return _.forEach(Object.keys(Object.assign({},e,t)),function(u){const d=c[u]||r,g=d(e[u],t[u],u);_.isUndefined(g)&&d!==l||(n[u]=g)}),n}const nl="1.6.8",vr={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{vr[e]=function(s){return typeof s===e||"a"+(t<1?"n ":" ")+e}});const Io={};vr.transitional=function(t,n,s){function r(o,i){return"[Axios v"+nl+"] Transitional option '"+o+"'"+i+(s?". "+s:"")}return(o,i,l)=>{if(t===!1)throw new q(r(i," has been removed"+(n?" in "+n:"")),q.ERR_DEPRECATED);return n&&!Io[i]&&(Io[i]=!0,console.warn(r(i," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(o,i,l):!0}};function af(e,t,n){if(typeof e!="object")throw new q("options must be an object",q.ERR_BAD_OPTION_VALUE);const s=Object.keys(e);let r=s.length;for(;r-- >0;){const o=s[r],i=t[o];if(i){const l=e[o],c=l===void 0||i(l,o,e);if(c!==!0)throw new q("option "+o+" must be "+c,q.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new q("Unknown option "+o,q.ERR_BAD_OPTION)}}const Js={assertOptions:af,validators:vr},it=Js.validators;class $n{constructor(t){this.defaults=t,this.interceptors={request:new Ao,response:new Ao}}async request(t,n){try{return await this._request(t,n)}catch(s){if(s instanceof Error){let r;Error.captureStackTrace?Error.captureStackTrace(r={}):r=new Error;const o=r.stack?r.stack.replace(/^.+\n/,""):"";s.stack?o&&!String(s.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(s.stack+=` +`+o):s.stack=o}throw s}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=$t(this.defaults,n);const{transitional:s,paramsSerializer:r,headers:o}=n;s!==void 0&&Js.assertOptions(s,{silentJSONParsing:it.transitional(it.boolean),forcedJSONParsing:it.transitional(it.boolean),clarifyTimeoutError:it.transitional(it.boolean)},!1),r!=null&&(_.isFunction(r)?n.paramsSerializer={serialize:r}:Js.assertOptions(r,{encode:it.function,serialize:it.function},!0)),n.method=(n.method||this.defaults.method||"get").toLowerCase();let i=o&&_.merge(o.common,o[n.method]);o&&_.forEach(["delete","get","head","post","put","patch","common"],A=>{delete o[A]}),n.headers=Xe.concat(i,o);const l=[];let c=!0;this.interceptors.request.forEach(function(E){typeof E.runWhen=="function"&&E.runWhen(n)===!1||(c=c&&E.synchronous,l.unshift(E.fulfilled,E.rejected))});const f=[];this.interceptors.response.forEach(function(E){f.push(E.fulfilled,E.rejected)});let u,d=0,g;if(!c){const A=[xo.bind(this),void 0];for(A.unshift.apply(A,l),A.push.apply(A,f),g=A.length,u=Promise.resolve(n);d{if(!s._listeners)return;let o=s._listeners.length;for(;o-- >0;)s._listeners[o](r);s._listeners=null}),this.promise.then=r=>{let o;const i=new Promise(l=>{s.subscribe(l),o=l}).then(r);return i.cancel=function(){s.unsubscribe(o)},i},t(function(o,i,l){s.reason||(s.reason=new _n(o,i,l),n(s.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}static source(){let t;return{token:new Cr(function(r){t=r}),cancel:t}}}const uf=Cr;function ff(e){return function(n){return e.apply(null,n)}}function df(e){return _.isObject(e)&&e.isAxiosError===!0}const Ys={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Ys).forEach(([e,t])=>{Ys[t]=e});const hf=Ys;function sl(e){const t=new Un(e),n=Di(Un.prototype.request,t);return _.extend(n,Un.prototype,t,{allOwnKeys:!0}),_.extend(n,t,null,{allOwnKeys:!0}),n.create=function(r){return sl($t(e,r))},n}const U=sl(Sr);U.Axios=Un;U.CanceledError=_n;U.CancelToken=uf;U.isCancel=Zi;U.VERSION=nl;U.toFormData=ls;U.AxiosError=q;U.Cancel=U.CanceledError;U.all=function(t){return Promise.all(t)};U.spread=ff;U.isAxiosError=df;U.mergeConfig=$t;U.AxiosHeaders=Xe;U.formToJSON=e=>Qi(_.isHTMLForm(e)?new FormData(e):e);U.getAdapter=tl.getAdapter;U.HttpStatusCode=hf;U.default=U;function pf(){return rl().__VUE_DEVTOOLS_GLOBAL_HOOK__}function rl(){return typeof navigator<"u"&&typeof window<"u"?window:typeof globalThis<"u"?globalThis:{}}const mf=typeof Proxy=="function",gf="devtools-plugin:setup",_f="plugin:settings:set";let kt,Xs;function bf(){var e;return kt!==void 0||(typeof window<"u"&&window.performance?(kt=!0,Xs=window.performance):typeof globalThis<"u"&&(!((e=globalThis.perf_hooks)===null||e===void 0)&&e.performance)?(kt=!0,Xs=globalThis.perf_hooks.performance):kt=!1),kt}function yf(){return bf()?Xs.now():Date.now()}class Sf{constructor(t,n){this.target=null,this.targetQueue=[],this.onQueue=[],this.plugin=t,this.hook=n;const s={};if(t.settings)for(const i in t.settings){const l=t.settings[i];s[i]=l.defaultValue}const r=`__vue-devtools-plugin-settings__${t.id}`;let o=Object.assign({},s);try{const i=localStorage.getItem(r),l=JSON.parse(i);Object.assign(o,l)}catch{}this.fallbacks={getSettings(){return o},setSettings(i){try{localStorage.setItem(r,JSON.stringify(i))}catch{}o=i},now(){return yf()}},n&&n.on(_f,(i,l)=>{i===this.plugin.id&&this.fallbacks.setSettings(l)}),this.proxiedOn=new Proxy({},{get:(i,l)=>this.target?this.target.on[l]:(...c)=>{this.onQueue.push({method:l,args:c})}}),this.proxiedTarget=new Proxy({},{get:(i,l)=>this.target?this.target[l]:l==="on"?this.proxiedOn:Object.keys(this.fallbacks).includes(l)?(...c)=>(this.targetQueue.push({method:l,args:c,resolve:()=>{}}),this.fallbacks[l](...c)):(...c)=>new Promise(f=>{this.targetQueue.push({method:l,args:c,resolve:f})})})}async setRealTarget(t){this.target=t;for(const n of this.onQueue)this.target.on[n.method](...n.args);for(const n of this.targetQueue)n.resolve(await this.target[n.method](...n.args))}}function vf(e,t){const n=e,s=rl(),r=pf(),o=mf&&n.enableEarlyProxy;if(r&&(s.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__||!o))r.emit(gf,e,t);else{const i=o?new Sf(n,r):null;(s.__VUE_DEVTOOLS_PLUGINS__=s.__VUE_DEVTOOLS_PLUGINS__||[]).push({pluginDescriptor:n,setupFn:t,proxy:i}),i&&t(i.proxiedTarget)}}/*! + * vuex v4.1.0 + * (c) 2022 Evan You + * @license MIT + */var Cf="store";function Wt(e,t){Object.keys(e).forEach(function(n){return t(e[n],n)})}function ol(e){return e!==null&&typeof e=="object"}function Ef(e){return e&&typeof e.then=="function"}function wf(e,t){return function(){return e(t)}}function il(e,t,n){return t.indexOf(e)<0&&(n&&n.prepend?t.unshift(e):t.push(e)),function(){var s=t.indexOf(e);s>-1&&t.splice(s,1)}}function ll(e,t){e._actions=Object.create(null),e._mutations=Object.create(null),e._wrappedGetters=Object.create(null),e._modulesNamespaceMap=Object.create(null);var n=e.state;as(e,n,[],e._modules.root,!0),Er(e,n,t)}function Er(e,t,n){var s=e._state,r=e._scope;e.getters={},e._makeLocalGettersCache=Object.create(null);var o=e._wrappedGetters,i={},l={},c=Nl(!0);c.run(function(){Wt(o,function(f,u){i[u]=wf(f,e),l[u]=ki(function(){return i[u]()}),Object.defineProperty(e.getters,u,{get:function(){return l[u].value},enumerable:!0})})}),e._state=zn({data:t}),e._scope=c,e.strict&&xf(e),s&&n&&e._withCommit(function(){s.data=null}),r&&r.stop()}function as(e,t,n,s,r){var o=!n.length,i=e._modules.getNamespace(n);if(s.namespaced&&(e._modulesNamespaceMap[i],e._modulesNamespaceMap[i]=s),!o&&!r){var l=wr(t,n.slice(0,-1)),c=n[n.length-1];e._withCommit(function(){l[c]=s.state})}var f=s.context=Af(e,i,n);s.forEachMutation(function(u,d){var g=i+d;Tf(e,g,u,f)}),s.forEachAction(function(u,d){var g=u.root?d:i+d,C=u.handler||u;Of(e,g,C,f)}),s.forEachGetter(function(u,d){var g=i+d;Rf(e,g,u,f)}),s.forEachChild(function(u,d){as(e,t,n.concat(d),u,r)})}function Af(e,t,n){var s=t==="",r={dispatch:s?e.dispatch:function(o,i,l){var c=jn(o,i,l),f=c.payload,u=c.options,d=c.type;return(!u||!u.root)&&(d=t+d),e.dispatch(d,f)},commit:s?e.commit:function(o,i,l){var c=jn(o,i,l),f=c.payload,u=c.options,d=c.type;(!u||!u.root)&&(d=t+d),e.commit(d,f,u)}};return Object.defineProperties(r,{getters:{get:s?function(){return e.getters}:function(){return cl(e,t)}},state:{get:function(){return wr(e.state,n)}}}),r}function cl(e,t){if(!e._makeLocalGettersCache[t]){var n={},s=t.length;Object.keys(e.getters).forEach(function(r){if(r.slice(0,s)===t){var o=r.slice(s);Object.defineProperty(n,o,{get:function(){return e.getters[r]},enumerable:!0})}}),e._makeLocalGettersCache[t]=n}return e._makeLocalGettersCache[t]}function Tf(e,t,n,s){var r=e._mutations[t]||(e._mutations[t]=[]);r.push(function(i){n.call(e,s.state,i)})}function Of(e,t,n,s){var r=e._actions[t]||(e._actions[t]=[]);r.push(function(i){var l=n.call(e,{dispatch:s.dispatch,commit:s.commit,getters:s.getters,state:s.state,rootGetters:e.getters,rootState:e.state},i);return Ef(l)||(l=Promise.resolve(l)),e._devtoolHook?l.catch(function(c){throw e._devtoolHook.emit("vuex:error",c),c}):l})}function Rf(e,t,n,s){e._wrappedGetters[t]||(e._wrappedGetters[t]=function(o){return n(s.state,s.getters,o.state,o.getters)})}function xf(e){nn(function(){return e._state.data},function(){},{deep:!0,flush:"sync"})}function wr(e,t){return t.reduce(function(n,s){return n[s]},e)}function jn(e,t,n){return ol(e)&&e.type&&(n=t,t=e,e=e.type),{type:e,payload:t,options:n}}var Lf="vuex bindings",Po="vuex:mutations",Os="vuex:actions",Nt="vuex",If=0;function Pf(e,t){vf({id:"org.vuejs.vuex",app:e,label:"Vuex",homepage:"https://next.vuex.vuejs.org/",logo:"https://vuejs.org/images/icons/favicon-96x96.png",packageName:"vuex",componentStateTypes:[Lf]},function(n){n.addTimelineLayer({id:Po,label:"Vuex Mutations",color:ko}),n.addTimelineLayer({id:Os,label:"Vuex Actions",color:ko}),n.addInspector({id:Nt,label:"Vuex",icon:"storage",treeFilterPlaceholder:"Filter stores..."}),n.on.getInspectorTree(function(s){if(s.app===e&&s.inspectorId===Nt)if(s.filter){var r=[];dl(r,t._modules.root,s.filter,""),s.rootNodes=r}else s.rootNodes=[fl(t._modules.root,"")]}),n.on.getInspectorState(function(s){if(s.app===e&&s.inspectorId===Nt){var r=s.nodeId;cl(t,r),s.state=Ff(Df(t._modules,r),r==="root"?t.getters:t._makeLocalGettersCache,r)}}),n.on.editInspectorState(function(s){if(s.app===e&&s.inspectorId===Nt){var r=s.nodeId,o=s.path;r!=="root"&&(o=r.split("/").filter(Boolean).concat(o)),t._withCommit(function(){s.set(t._state.data,o,s.state.value)})}}),t.subscribe(function(s,r){var o={};s.payload&&(o.payload=s.payload),o.state=r,n.notifyComponentUpdate(),n.sendInspectorTree(Nt),n.sendInspectorState(Nt),n.addTimelineEvent({layerId:Po,event:{time:Date.now(),title:s.type,data:o}})}),t.subscribeAction({before:function(s,r){var o={};s.payload&&(o.payload=s.payload),s._id=If++,s._time=Date.now(),o.state=r,n.addTimelineEvent({layerId:Os,event:{time:s._time,title:s.type,groupId:s._id,subtitle:"start",data:o}})},after:function(s,r){var o={},i=Date.now()-s._time;o.duration={_custom:{type:"duration",display:i+"ms",tooltip:"Action duration",value:i}},s.payload&&(o.payload=s.payload),o.state=r,n.addTimelineEvent({layerId:Os,event:{time:Date.now(),title:s.type,groupId:s._id,subtitle:"end",data:o}})}})})}var ko=8702998,kf=6710886,Nf=16777215,al={label:"namespaced",textColor:Nf,backgroundColor:kf};function ul(e){return e&&e!=="root"?e.split("/").slice(-2,-1)[0]:"Root"}function fl(e,t){return{id:t||"root",label:ul(t),tags:e.namespaced?[al]:[],children:Object.keys(e._children).map(function(n){return fl(e._children[n],t+n+"/")})}}function dl(e,t,n,s){s.includes(n)&&e.push({id:s||"root",label:s.endsWith("/")?s.slice(0,s.length-1):s||"Root",tags:t.namespaced?[al]:[]}),Object.keys(t._children).forEach(function(r){dl(e,t._children[r],n,s+r+"/")})}function Ff(e,t,n){t=n==="root"?t:t[n];var s=Object.keys(t),r={state:Object.keys(e.state).map(function(i){return{key:i,editable:!0,value:e.state[i]}})};if(s.length){var o=Uf(t);r.getters=Object.keys(o).map(function(i){return{key:i.endsWith("/")?ul(i):i,editable:!1,value:Qs(function(){return o[i]})}})}return r}function Uf(e){var t={};return Object.keys(e).forEach(function(n){var s=n.split("/");if(s.length>1){var r=t,o=s.pop();s.forEach(function(i){r[i]||(r[i]={_custom:{value:{},display:i,tooltip:"Module",abstract:!0}}),r=r[i]._custom.value}),r[o]=Qs(function(){return e[n]})}else t[n]=Qs(function(){return e[n]})}),t}function Df(e,t){var n=t.split("/").filter(function(s){return s});return n.reduce(function(s,r,o){var i=s[r];if(!i)throw new Error('Missing module "'+r+'" for path "'+t+'".');return o===n.length-1?i:i._children},t==="root"?e:e.root._children)}function Qs(e){try{return e()}catch(t){return t}}var De=function(t,n){this.runtime=n,this._children=Object.create(null),this._rawModule=t;var s=t.state;this.state=(typeof s=="function"?s():s)||{}},hl={namespaced:{configurable:!0}};hl.namespaced.get=function(){return!!this._rawModule.namespaced};De.prototype.addChild=function(t,n){this._children[t]=n};De.prototype.removeChild=function(t){delete this._children[t]};De.prototype.getChild=function(t){return this._children[t]};De.prototype.hasChild=function(t){return t in this._children};De.prototype.update=function(t){this._rawModule.namespaced=t.namespaced,t.actions&&(this._rawModule.actions=t.actions),t.mutations&&(this._rawModule.mutations=t.mutations),t.getters&&(this._rawModule.getters=t.getters)};De.prototype.forEachChild=function(t){Wt(this._children,t)};De.prototype.forEachGetter=function(t){this._rawModule.getters&&Wt(this._rawModule.getters,t)};De.prototype.forEachAction=function(t){this._rawModule.actions&&Wt(this._rawModule.actions,t)};De.prototype.forEachMutation=function(t){this._rawModule.mutations&&Wt(this._rawModule.mutations,t)};Object.defineProperties(De.prototype,hl);var Lt=function(t){this.register([],t,!1)};Lt.prototype.get=function(t){return t.reduce(function(n,s){return n.getChild(s)},this.root)};Lt.prototype.getNamespace=function(t){var n=this.root;return t.reduce(function(s,r){return n=n.getChild(r),s+(n.namespaced?r+"/":"")},"")};Lt.prototype.update=function(t){pl([],this.root,t)};Lt.prototype.register=function(t,n,s){var r=this;s===void 0&&(s=!0);var o=new De(n,s);if(t.length===0)this.root=o;else{var i=this.get(t.slice(0,-1));i.addChild(t[t.length-1],o)}n.modules&&Wt(n.modules,function(l,c){r.register(t.concat(c),l,s)})};Lt.prototype.unregister=function(t){var n=this.get(t.slice(0,-1)),s=t[t.length-1],r=n.getChild(s);r&&r.runtime&&n.removeChild(s)};Lt.prototype.isRegistered=function(t){var n=this.get(t.slice(0,-1)),s=t[t.length-1];return n?n.hasChild(s):!1};function pl(e,t,n){if(t.update(n),n.modules)for(var s in n.modules){if(!t.getChild(s))return;pl(e.concat(s),t.getChild(s),n.modules[s])}}function Vf(e){return new Ae(e)}var Ae=function(t){var n=this;t===void 0&&(t={});var s=t.plugins;s===void 0&&(s=[]);var r=t.strict;r===void 0&&(r=!1);var o=t.devtools;this._committing=!1,this._actions=Object.create(null),this._actionSubscribers=[],this._mutations=Object.create(null),this._wrappedGetters=Object.create(null),this._modules=new Lt(t),this._modulesNamespaceMap=Object.create(null),this._subscribers=[],this._makeLocalGettersCache=Object.create(null),this._scope=null,this._devtools=o;var i=this,l=this,c=l.dispatch,f=l.commit;this.dispatch=function(g,C){return c.call(i,g,C)},this.commit=function(g,C,A){return f.call(i,g,C,A)},this.strict=r;var u=this._modules.root.state;as(this,u,[],this._modules.root),Er(this,u),s.forEach(function(d){return d(n)})},Ar={state:{configurable:!0}};Ae.prototype.install=function(t,n){t.provide(n||Cf,this),t.config.globalProperties.$store=this;var s=this._devtools!==void 0?this._devtools:!1;s&&Pf(t,this)};Ar.state.get=function(){return this._state.data};Ar.state.set=function(e){};Ae.prototype.commit=function(t,n,s){var r=this,o=jn(t,n,s),i=o.type,l=o.payload,c={type:i,payload:l},f=this._mutations[i];f&&(this._withCommit(function(){f.forEach(function(d){d(l)})}),this._subscribers.slice().forEach(function(u){return u(c,r.state)}))};Ae.prototype.dispatch=function(t,n){var s=this,r=jn(t,n),o=r.type,i=r.payload,l={type:o,payload:i},c=this._actions[o];if(c){try{this._actionSubscribers.slice().filter(function(u){return u.before}).forEach(function(u){return u.before(l,s.state)})}catch{}var f=c.length>1?Promise.all(c.map(function(u){return u(i)})):c[0](i);return new Promise(function(u,d){f.then(function(g){try{s._actionSubscribers.filter(function(C){return C.after}).forEach(function(C){return C.after(l,s.state)})}catch{}u(g)},function(g){try{s._actionSubscribers.filter(function(C){return C.error}).forEach(function(C){return C.error(l,s.state,g)})}catch{}d(g)})})}};Ae.prototype.subscribe=function(t,n){return il(t,this._subscribers,n)};Ae.prototype.subscribeAction=function(t,n){var s=typeof t=="function"?{before:t}:t;return il(s,this._actionSubscribers,n)};Ae.prototype.watch=function(t,n,s){var r=this;return nn(function(){return t(r.state,r.getters)},n,Object.assign({},s))};Ae.prototype.replaceState=function(t){var n=this;this._withCommit(function(){n._state.data=t})};Ae.prototype.registerModule=function(t,n,s){s===void 0&&(s={}),typeof t=="string"&&(t=[t]),this._modules.register(t,n),as(this,this.state,t,this._modules.get(t),s.preserveState),Er(this,this.state)};Ae.prototype.unregisterModule=function(t){var n=this;typeof t=="string"&&(t=[t]),this._modules.unregister(t),this._withCommit(function(){var s=wr(n.state,t.slice(0,-1));delete s[t[t.length-1]]}),ll(this)};Ae.prototype.hasModule=function(t){return typeof t=="string"&&(t=[t]),this._modules.isRegistered(t)};Ae.prototype.hotUpdate=function(t){this._modules.update(t),ll(this,!0)};Ae.prototype._withCommit=function(t){var n=this._committing;this._committing=!0,t(),this._committing=n};Object.defineProperties(Ae.prototype,Ar);var Ze=gl(function(e,t){var n={};return ml(t).forEach(function(s){var r=s.key,o=s.val;n[r]=function(){var l=this.$store.state,c=this.$store.getters;if(e){var f=_l(this.$store,"mapState",e);if(!f)return;l=f.context.state,c=f.context.getters}return typeof o=="function"?o.call(this,l,c):l[o]},n[r].vuex=!0}),n}),Bf=gl(function(e,t){var n={};return ml(t).forEach(function(s){var r=s.key,o=s.val;n[r]=function(){for(var l=[],c=arguments.length;c--;)l[c]=arguments[c];var f=this.$store.commit;if(e){var u=_l(this.$store,"mapMutations",e);if(!u)return;f=u.context.commit}return typeof o=="function"?o.apply(this,[f].concat(l)):f.apply(this.$store,[o].concat(l))}}),n});function ml(e){return Mf(e)?Array.isArray(e)?e.map(function(t){return{key:t,val:t}}):Object.keys(e).map(function(t){return{key:t,val:e[t]}}):[]}function Mf(e){return Array.isArray(e)||ol(e)}function gl(e){return function(t,n){return typeof t!="string"?(n=t,t=""):t.charAt(t.length-1)!=="/"&&(t+="/"),e(t,n)}}function _l(e,t,n){var s=e._modulesNamespaceMap[n];return s}const et=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},$f={data(){return{artistsArrayList:[],lastClickedItem:null,showDrop:!1}},created(){this.loadList(),U.get("/api/getLastArtist").then(e=>{e.data!==""&&(this.lastClickedItem=e.data)})},computed:{...Ze(["allowButtons","sourceTab","artist"])},watch:{"$store.state.loadListRequest"(e){e&&(this.$store.commit("SET_LOAD_REQUEST",!1),this.loadList())}},methods:{loadList(){U.get("/api/loadList").then(e=>{this.artistsArrayList=e.data}).catch(e=>{console.error(e)})},handleItemClick(e){this.lastClickedItem=e,U.post("/api/listOrTabClick",{item:e,origin:"list"}).then(t=>{this.$store.commit("SET_SELECTED_ARTIST",e),this.$store.commit("SET_TABLE_CONTENT",t.data)}).catch(t=>{console.error(t)})},clickAddArtist(){this.$store.commit("SET_ADD_VIS",!0)},clickDeleteArtist(){this.lastClickedItem!==""&&U.get("/api/clickArtistDelete").then(()=>{this.$store.commit("SET_SELECTED_ARTIST",""),this.$store.commit("SET_SOURCE_TAB","combview"),this.loadList()}).catch(e=>{console.error(e)})},showMore(){this.showDrop=!this.showDrop},deleteUrl(){U.post("/api/deleteUrl").then(()=>{this.handleItemClick(this.lastClickedItem)})}}},jf={class:"buttonspace"},Hf=["disabled"],Kf={key:0,class:"dropdown"},qf=["disabled"],Wf=["disabled"],Gf={class:"artistlist"},zf=["onMousedown"],Jf={class:"listitems"};function Yf(e,t,n,s,r,o){return x(),L(_e,null,[p("div",jf,[p("button",{onMousedown:t[0]||(t[0]=i=>o.clickAddArtist()),class:"addbtn",disabled:!e.allowButtons},"add",40,Hf),p("button",{onClick:t[1]||(t[1]=i=>o.showMore()),class:"morebtn"},"more"),r.showDrop?(x(),L("div",Kf,[p("button",{onClick:t[2]||(t[2]=i=>o.deleteUrl()),disabled:e.sourceTab==null||e.sourceTab=="combview"||e.artist==""||!e.allowButtons,class:"deletebtn"},"delete selected URL",8,qf),p("button",{onClick:t[3]||(t[3]=i=>o.clickDeleteArtist()),disabled:e.artist==""||!e.allowButtons,class:"deletebtn"},"delete artist",8,Wf)])):B("",!0)]),p("div",Gf,[(x(!0),L(_e,null,Ds(r.artistsArrayList,i=>(x(),L("li",{key:i,onMousedown:l=>o.handleItemClick(i),class:Ee([{highlighted:i===r.lastClickedItem},"listbtn"])},[p("div",Jf,ze(i),1)],42,zf))),128)),(x(!0),L(_e,null,Ds(r.artistsArrayList,i=>(x(),L("li",{key:i}))),128))])],64)}const Xf=et($f,[["render",Yf],["__scopeId","data-v-18b2502f"]]),Qf="/assets/optionsblack-vjTCXWXl.png",Zf="/assets/optionsdark-ymr6Vwzk.png",ed="/assets/optionslight-B8QchSUy.png",td="/assets/refreshuniversal-3TIkIW2C.png",nd={data(){return{activeTab:"",eventSource:null,scrapeColor:"var(--accent-color)",scrapeNotice:!1,scrapeLast:"-"}},computed:{...Ze(["sourceTab","allowButtons","primaryColor"])},created(){this.activeTab=this.sourceTab,U.post("/api/fillCombview").catch(e=>{console.error(e)}).then(()=>{this.sourceTab===""?this.setStoreTab("combview"):this.handleSourceClick(this.sourceTab)}),U.get("/api/getScrapeDate").then(e=>{this.scrapeLast=e.data})},watch:{sourceTab(e){this.activeTab=e,e&&this.handleSourceClick(e)}},methods:{setStoreTab(e){this.$store.commit("SET_SOURCE_TAB",e)},handleSourceClick(e){U.post("/api/listOrTabClick",{item:e,origin:"tab"}).then(t=>{this.$store.commit("SET_TABLE_CONTENT",t.data)}).catch(t=>{console.error(t)})},clickScrape(){this.allowButtons?(this.$store.commit("SET_ALLOW_BUTTONS",!1),this.scrapeColor="var(--dull-color)",this.eventSource=new EventSource("/progress"),this.eventSource.onmessage=t=>{const n=parseFloat(t.data);this.$store.commit("SET_PROGRESS",n)},U.post("/api/clickScrape").then(()=>{this.scrapeColor="var(--accent-color)",this.$store.commit("SET_ALLOW_BUTTONS",!0),this.eventSource.close();let t=new Date().toLocaleString("en-GB",{day:"2-digit",month:"2-digit",hour:"2-digit",minute:"2-digit"}).replace(/\//g,".").replace(",","").replace(/(\d{2})\.(\d{2})/,"$1.$2.");this.scrapeLast=t,this.scrapeNotice=!0,this.handleSourceClick("combview"),U.post("/api/setSetting",{name:"lastScrape",value:t}).catch(n=>{console.error(n)})})):U.post("/api/cancelScrape").then(()=>{this.$store.commit("SET_ALLOW_BUTTONS",!0),this.scrapeColor="var(--accent-color)"})},scrapeHover(){this.scrapeNotice=!0},scrapeMouseOff(){this.scrapeNotice=!1},openSettings(){this.$store.commit("SET_SETTINGS_OPEN",!0)}}},sd=e=>(Ht("data-v-671de189"),e=e(),Kt(),e),rd={class:"wrapper"},od={class:"tabs"},id=["disabled"],ld={key:0,class:"image",src:Qf,alt:"Settings"},cd={key:1,class:"image",src:Zf,alt:"Settings"},ad={key:2,class:"image",src:ed,alt:"Settings"},ud=sd(()=>p("img",{class:"image",src:td,alt:"Refresh"},null,-1)),fd=[ud];function dd(e,t,n,s,r,o){return x(),L("div",rd,[p("div",od,[p("div",{onMousedown:t[0]||(t[0]=i=>o.setStoreTab("combview")),class:Ee([{active:r.activeTab==="combview"},"cvtab"])},"Combined view",34),p("div",{onMousedown:t[1]||(t[1]=i=>o.setStoreTab("beatport")),class:Ee([{active:r.activeTab==="beatport"},"stab"])},"BP",34),p("div",{onMousedown:t[2]||(t[2]=i=>o.setStoreTab("musicbrainz")),class:Ee([{active:r.activeTab==="musicbrainz"},"stab"])},"MB",34),p("div",{onMousedown:t[3]||(t[3]=i=>o.setStoreTab("junodownload")),class:Ee([{active:r.activeTab==="junodownload"},"stab"])},"JD",34),p("div",{onMousedown:t[4]||(t[4]=i=>o.setStoreTab("youtube")),class:Ee([{active:r.activeTab==="youtube"},"stab"])},"YT",34)]),p("button",{onClick:t[5]||(t[5]=i=>o.openSettings()),class:"imgbutton1",disabled:!e.allowButtons},[e.primaryColor==="Black"?(x(),L("img",ld)):e.primaryColor==="Dark"?(x(),L("img",cd)):e.primaryColor==="Light"?(x(),L("img",ad)):B("",!0)],8,id),p("button",{onClick:t[6]||(t[6]=i=>o.clickScrape()),onMouseover:t[7]||(t[7]=i=>o.scrapeHover()),onMouseleave:t[8]||(t[8]=i=>o.scrapeMouseOff()),style:pn({"background-color":r.scrapeColor}),class:"imgbutton2"},fd,36),le(gr,{name:"fade"},{default:ai(()=>[r.scrapeNotice?(x(),L("div",{key:0,class:"scrapenotice",onMouseover:t[9]||(t[9]=i=>o.scrapeMouseOff())},[p("p",null,"Last scrape: "+ze(r.scrapeLast),1)],32)):B("",!0)]),_:1})])}const hd=et(nd,[["render",dd],["__scopeId","data-v-671de189"]]),pd={mounted(){this.isDateInFuture},computed:{...Ze(["tableData","previewVis","artist","isoDates","sourceTab","urlExists"]),hideArtistColumn(){return this.tableData.some(e=>e.artist===null)},hideTable(){return this.tableData.some(e=>e.song!==null)}},methods:{isDateInFuture(e){return new Date(e)>new Date},formatDate(e){if(this.isoDates)return e;{const t=new Date(e),n=t.getDate(),s=t.getMonth()+1,r=t.getFullYear();return`${n}. ${s}. ${r}`}}}},bn=e=>(Ht("data-v-19adbfff"),e=e(),Kt(),e),md={key:0,class:"table-container"},gd={class:"table-header"},_d=bn(()=>p("th",{class:"song"},"song",-1)),bd={key:0,class:"artist"},yd=bn(()=>p("th",{class:"date"},"date",-1)),Sd={class:"table-body"},vd=bn(()=>p("td",null,[p("br")],-1)),Cd={class:"tdsong"},Ed={key:0,class:"tdartist"},wd={class:"tddate"},Ad={key:1,class:"emptynotice"},Td=bn(()=>p("p",null,"table empty",-1)),Od=[Td],Rd={key:2,class:"quickstart"},xd=bn(()=>p("p",null,[p("span",{class:"title"},"Quickstart guide"),pe(),p("br"),pe(' 1. click "add" to add an artist, select the artist '),p("br"),pe(" 2. click on any BP / MB / JD / YT button at the top to select a source "),p("br"),pe(" 3. find the artist on the website, copy & paste the link or ID "),p("br"),pe(" 4. to scrape, click refresh button in the top right corner "),p("br")],-1)),Ld=[xd];function Id(e,t,n,s,r,o){return x(),L(_e,null,[o.hideTable?(x(),L("div",md,[p("div",gd,[p("table",null,[p("tr",null,[_d,o.hideArtistColumn?B("",!0):(x(),L("th",bd,"artist")),yd])])]),p("div",Sd,[p("table",null,[p("tbody",null,[vd,(x(!0),L(_e,null,Ds(e.tableData,(i,l)=>(x(),L("tr",{key:l,class:Ee({"future-date":o.isDateInFuture(i.date)})},[p("td",Cd,ze(i.song),1),o.hideArtistColumn?B("",!0):(x(),L("td",Ed,ze(i.artist),1)),p("td",wd,ze(o.formatDate(i.date)),1)],2))),128))])])])])):B("",!0),e.urlExists&&!o.hideTable&&!e.previewVis&&e.sourceTab!=="combview"?(x(),L("div",Ad,Od)):B("",!0),!e.urlExists&&!o.hideTable&&!e.previewVis&&e.sourceTab==="combview"?(x(),L("div",Rd,Ld)):B("",!0)],64)}const Pd=et(pd,[["render",Id],["__scopeId","data-v-19adbfff"]]),Gt="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAACXBIWXMAAAYCAAAGAgHyxpylAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAABwpJREFUeJzt3UmMFGUYh/FnlBiNGxITTbjoRQ+elBAFObpePLmgLAm7u8ywyQ7KIsuwGRdgALeIaDx4cDfRRGKMRr0YE2+Y6MEtosZoXGgP73ScNDD2VL1vfbX8fxcCTH1dyTz5uqq66uueVquFiLdTUu+A1JPCkhAKS0IoLAmhsCSEwpIQCktCKCwJobAkhMKSEApLQigsCaGwJITCkhAKS0IoLAmhsCSEwpIQCktCKCwJobAkhMKSEApLQigsCaGwJITCkhAKS0IoLAmhsCSEwpIQo1LvgCR1KTABuAD4CjgMfO0xsMJqpsuBXcCkjn8/BrwC9GKhZdajhdca5xbgGeD0YX7mR+Ba4LOsL6KwmuU24Dm6e6f6BrgM+DnLC+ngvTkm031UAGOBhVlfTDNWM0wGnmXkx9RHgIuzvKDCqr/bsahOzbj9GOCnkW6kt8J6u4N8UQGckWUjhVVfU7CzvzxR/QH8kGVDhVVPU4GnyRcVwHvAn1k2VFj1Mw14ivxRAfRn3VBh1ct04AA+UT0GvJN1Y50V1sd0YD8+UT0/ON4/WQdQWPWQ95LCUC9iB/5/5xlEb4XVNwO7ou4R1SEcogKFVXUzgAF8fo+HsLPJ3FGBwqqymfhF9QKOUYHCqqqZwF78opqGY1SgG/2qyDuqqeQ4+zsZzVjVMgu/qA4SFBUorCqZBezB53d2gMCoQGFVxWx8o5qN3d8eRmGV32xgNz6/q/0UEBUorLKbg29UcyggKlBYZTYHeJIKRgUKq6w8Z6p9FBwVKKwymotF1eMw1r7B8QqNChRW2czF3v48ohogUVSgsMpkHr5RzSNRVKCwymIe8AQ+Ue0lcVSgsMrgTnyjupPEUYHCSm0+8Dg1mqnaFFY684Ht+ES1B4uqNPeZK6w0erGoPOzB3v5KExUorBR6gW1OY+2mhFGBwipaH75R3UUJowKFVaQ+cjxZ3GEHJY4KFFZRFuAbVS8ljgoUVhEWAFudxtqORVV6CivWQnyj6nMaK5zCirMQ2OI01jYqFBUorCiL8I1qgdNYhVFY/hYBm53G6qeCUYHC8rYY36gyL4edmsLysxjY5DTWViocFSgsL0vwjWqR01jJKKz8lgCPOI21hRpEBcUvCjIKuBK4ZPDvXwIf4bzSSYG8o1rsNFZyRYV1GnZ20wec3/F/32MHqtuAvwraHw9rgNVOY23GIq2NItYgHQ28Ckz8n587DNxEhq/XSGANimpY0WH1AG8B13T5859g35NX5rjWAqucxtoEPOg0VqlEH7xPofuoAMYBbwPnxexOboqqS9Fh3Zthm3HYLDfaeV/yeghF1bXIt8KzgKNkXyb6Y+C6wTFSexhY4TTWGmzmq7XIGetC8q09Pp5yzFyKKoPIsH53GGM88CZwrsNYWazDL6rVNCQqiH0r7AG+4/jrVll8ip0EFHm2uA5Y7jTWauwYrTEiZ6wW8LLTWFcAr1PczLUev6hW0bCoIP461kXA58CZTuN9CFwP/OI03omsB5Y5jbUKO0ZrnOjLDUewZaS91hO4CngDOMdpvE4b8ItqJQ2NCoq5u+EQvksVTiAmrg3AUqexVmLHaI1V1G0z+/FdXa4d19lO423EL6oVNDwqKPZ+LO/1ML3i2ojfVfAV2DFa46X4hlXPBfEBPgBuAH4d4XY92LN6Dzjtx3Ls7VRIcwep9/qYE7FLESOZuRRVsFS3Jg/gu/zO1XQfVw+2/oFXVMtQVMdJec97e2nDIuNqR3W/02suw47RpEPqhyki4noNu7OiUw+wE7+olqKoTip1WPDfSr9ecU3CZq6hcbWjus/pNZbi9xBFLaU4KzwZz29lALuH/kbgN2AX2W467NTClhHa6TBWrZUpLPBdSB/gfeCLwXHzUlQjULawwM7WvJap9tLCls/elXpHqqIMx1iddlKutaAUVQZFPwndrR2Df3qthZ5VC5tBH028H5VTxhmrbQdpZy5FlUOZwwKbsVIsktHCziIVVUZlDwtsWZ8iF8toAfdgX54kGVUhLLCVWIpY36AF3I1d8pAcyni5YTiea6Z3amHf9rA7aPxGqcqM1daP352eQ7Wwj5UUlZOqhQX2GZ3XAw9g94XNw76eTZxUMSywuwo8nvtrR7XXYSwZoqphgd1cl+fx92PYB98DPrsjQ1U5LLAHF1Zm3HYu9oCHBKh6WGCPWo30wdC1KKpQVbvcMJx+uvsIqP19fxKoTmEB3IxdMhhzgv87il38PFjoHjVU3cJqmwTcCowFvgVeAt5NukcNU9ewJLE6HLxLCSksCaGwJITCkhAKS0IoLAmhsCSEwpIQCktCKCwJobAkhMKSEApLQigsCaGwJITCkhAKS0IoLAmhsCSEwpIQCktCKCwJobAkhMKSEApLQigsCaGwJITCkhAKS0IoLAnxL3WBYWyxSXBfAAAAAElFTkSuQmCC",zt="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAACXBIWXMAAAYCAAAGAgHyxpylAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAABw9JREFUeJzt3cmrHFUUx/HvcULBIbpRcKMbXbhSUBHc6l/gbBTU5MUJNM6zRo1Gk5gYccjkjCMuXIkDKjiigjvBnYIKThhBUETfcVH1NDxMeK/6nLq3qn9fqE1e+tbtqg/1uvt13zZ3R6no9ig9ATXOBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEp7lZ6AKpeZHQ2cBBwKfA287+7fhIyt9bGmLzM7FtgEnDzvR7PAq8BKd/96on0I1nRlZqcDTwP77ua//Qyc4u6fd96PYE1PZnYm8CwLewj0LXCMu//aZV968D4lmdlZLBwVwOHANZ33pyvW+GtRPcPin6x95e5HdtqnYI07MzubBtWeHYc4xN1/WeyN9KtwxJnZOUyGCmC/LjcSrJFmZufSPPubBNUfwE9dbihYI8zMlgJPMRkqgHfd/c8uNxSskWVm5wFPMjkqgPVdbyhYI8rMzgeeIAbVw+7+Vue56FnhOGpRPU4MqueA8939787zEazhF/CSws69BJzr7n9NMoh+FQ48M7uA5hX1CFQvEoAKBGvQtai2EXMeXwSWRqACwRpsZnYhcaheIBAVCNYga1FtJQ7VeZGoQO8gHVwJqJZO8uxvV+mKNaDM7CLiUD1PEioQrMHUotpCzDl7gkRUIFiDyMyWEYtqmbvPBoy1ywSr8lpUm4k5V4/TAyoQrKozs+XEolreByoQrGprUT3GAFGBYFVZ8JVqOz2jAsGqLjOboUFlAcNtB2b6RgWCVVUtqseIQbWNQqhAsKrJzFYQi2pFKVQgWFXUonqUGFRbKYwKBKt4ZnYxsaguLo0KBKtoZnYl8AgjulLNJViFalFtIAbVFhpU1bzPXLAKZGYraVBFtIXm1181qECweq9F9UDQcJupEBUIVq+Z2VXEorqkRlQgWL3Vour8yeJ5baRiVKC3JveSmV0NrAsabqO7rwwaKy1dsZILRrVhCKhAsFIzs2uIRXVV0FjpCVZSLaq1QcM9MCRUIFgpmdm1xKK6Omis3hKs4FpU9wcNt36IqECwQjOz64hF1Xk57NIJVlAtqvuChls3ZFQgWCGZ2fXEoro2aKxiCdaEtajWBA23dgyooOdX3s1sL+BE4Kj2n74EPole6aSvElBdFzRW+dw9fQP2AW4EfgR83vYDcD2wdx9zCbxPd/zPfem63Vf6/oQfnx5OwBLggwUc3PeAg0sfEKEaACyad0e+uYiD/FntuIBVgajWlL4/Q4W1tMPBrhaXUNUD6+OOB/1TYEnpgzPvvtwpVAvf0tZ5N7P9gR10Xyb6U+BUd98RN6tumdldwC1Bw93h7quCxqq2zNexDmOytcePB94wsyVB8+mUUHUrE9bvAWMcD7xuZgcFjLXozOxu4lDdPi2oIBfWd3T8rrt5nQC8bWYHB4y14FpUNwcNd7u73xk01iBKg+XNg7dXgoY7DnitryuXma0mDtVt04YKSH9WeATwG3HPpj4CDkye8+rA+d5a+tlZqS1/B3Am8HfgyfowCxdwT+A8byl9ckcNqz1hF9aOS6gGCKs9cRcl4DogaG73Bs7r5tIntYat353F4/pgUlxCNQJY7YlcVgMumj+Qbwycx02lT2ZNW5mdxuN6fzG4hGqksNqTuxyY7RtXi+rBwP3eWPok1riV3XnPuIRqSmAl4XoP2H8XqDYF7ueG0seu5q34BNqTPpOJS6imFFYmrhbVQ0FjzgJXlD5WQ9jS3ujXpeCF9KHB9QWwImAsB1a6+4MBY42+qmABmNkVxC1THZUDV7r7ptITGUrVfRK6vSLUtBaUUHWoOlgA7r4RqGFJRKd5TCVUi6xKWPAvrpJXrjlUDxWcw2CrFhaAu28ASiyS4cDlQtW9qmEBuPs6oM/FMhy4zN0f6XGfo6t6WADuvpZm4ZD0XQGXuvujPexr1FX3csPuCl4zfX5O820Pm5PGn6oGccWay93X0yyHFD40zZcdCVVQg4IF4O5rgJsCh5yl+a6/LYFjTn2DgwXg7vcS87m/OVRbA8ZSOzVIWADufg+Tffx9Fphx921BU1I7NVhYAO6+Gri1481n3H175HzUfw0aFoC73w3ctcibrRKq3Ab1csPuMrP1LOxPQIP4vr+hNxpYAGZ2Gs1X2h7yPz/eQfPi5/P9zmo6GxWsuczsZOAM4HDge+Bld3+n7Kymq1HCUuUb/IN3VWeCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqpX8Abns5VFEOJoIAAAAASUVORK5CYII=",kd={data:()=>({input:""}),computed:{...Ze(["tableData","sourceTab","allowButtons","artist","addDialogVis","primaryColor","urlExists"])},watch:{tableData(){this.determineDiagShow()}},methods:{clickURL(){const e=encodeURIComponent(this.input);this.input="",e&&U.post("/api/clickAddURL",e).then(()=>{const t=this.artist;U.post("/api/listOrTabClick",{item:t,origin:"list"}).then(n=>{this.$store.commit("SET_TABLE_CONTENT",n.data),this.$store.commit("SET_PREVIEW_VIS",!0)})}).catch(t=>{console.error(t)})},determineDiagShow(){this.tableData.length===0?U.get("/api/checkExistURL").then(e=>{this.$store.commit("SET_URL_EXISTS",e.data)}).catch(e=>{console.error(e)}):this.$store.commit("SET_URL_EXISTS",!0)}}},ae=e=>(Ht("data-v-0fe96286"),e=e(),Kt(),e),Nd={key:0},Fd={key:0,class:"dialog"},Ud=ae(()=>p("h1",null,"MusicBrainz source",-1)),Dd={class:"artist"},Vd=ae(()=>p("p",null,[p("a",{href:"https://musicbrainz.org",target:"_blank"},"https://musicbrainz.org"),pe(" > find artist > copy URL")],-1)),Bd=ae(()=>p("br",null,null,-1)),Md=ae(()=>p("p",null,"Example link:",-1)),$d=ae(()=>p("p",null,[pe("https://musicbrainz.org/artist/"),p("span",{class:"variabletext"},"id/...")],-1)),jd={key:0,class:"image",src:Gt,alt:"OK"},Hd={key:1,class:"image",src:zt,alt:"OK"},Kd={key:1,class:"dialog"},qd=ae(()=>p("h1",null,"Beatport source",-1)),Wd={class:"artist"},Gd=ae(()=>p("p",null,[p("a",{href:"https://beatport.com",target:"_blank"},"https://beatport.com"),pe(" > find artist > copy URL")],-1)),zd=ae(()=>p("br",null,null,-1)),Jd=ae(()=>p("p",null,"Example link:",-1)),Yd=ae(()=>p("p",null,[pe("https://beatport.com/artist/"),p("span",{class:"variabletext"},"artistname/id/...")],-1)),Xd={key:0,class:"image",src:Gt,alt:"OK"},Qd={key:1,class:"image",src:zt,alt:"OK"},Zd={key:2,class:"dialog"},eh=ae(()=>p("h1",null,"Junodownload source",-1)),th={class:"artist"},nh=ae(()=>p("p",null,[p("a",{href:"https://junodownload.com",target:"_blank"},"https://junodownload.com"),pe(" > find artist > copy URL")],-1)),sh=ae(()=>p("br",null,null,-1)),rh=ae(()=>p("p",null,"Example link:",-1)),oh=ae(()=>p("p",null,[pe("https://junodownload.com/artists/"),p("span",{class:"variabletext"},"artistname/...")],-1)),ih={key:0,class:"image",src:Gt,alt:"OK"},lh={key:1,class:"image",src:zt,alt:"OK"},ch={key:3,class:"dialog"},ah=ae(()=>p("h1",null,"Youtube source",-1)),uh={class:"artist"},fh=ae(()=>p("p",null,[p("a",{href:"https://youtube.com",target:"_blank"},"https://youtube.com")],-1)),dh=ae(()=>p("p",null,[pe(' Find an auto-generated channel with "Topic" in its name. '),p("br"),pe("Obtain the ID (share > copy channel ID) or copy URL. "),p("br"),pe("An ID needs to be provided, not a channel handle. ")],-1)),hh=ae(()=>p("p",null,"Example link:",-1)),ph=ae(()=>p("p",null,[pe("https://youtube.com/channel/"),p("span",{class:"variabletext"},"UCwZEU0wAwIyZb...")],-1)),mh={key:0,class:"image",src:Gt,alt:"OK"},gh={key:1,class:"image",src:zt,alt:"OK"};function _h(e,t,n,s,r,o){return!e.urlExists&&e.allowButtons&&e.artist&&!e.addDialogVis?(x(),L("div",Nd,[e.sourceTab==="musicbrainz"?(x(),L("div",Fd,[Ud,p("p",Dd,ze(e.artist),1),Vd,Bd,Md,$d,ie(p("input",{"onUpdate:modelValue":t[0]||(t[0]=i=>e.input=i)},null,512),[[en,e.input]]),p("button",{onClick:t[1]||(t[1]=(...i)=>o.clickURL&&o.clickURL(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",jd)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Hd)):B("",!0)])])):e.sourceTab==="beatport"?(x(),L("div",Kd,[qd,p("p",Wd,ze(e.artist),1),Gd,zd,Jd,Yd,ie(p("input",{"onUpdate:modelValue":t[2]||(t[2]=i=>e.input=i)},null,512),[[en,e.input]]),p("button",{onClick:t[3]||(t[3]=(...i)=>o.clickURL&&o.clickURL(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",Xd)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Qd)):B("",!0)])])):e.sourceTab==="junodownload"?(x(),L("div",Zd,[eh,p("p",th,ze(e.artist),1),nh,sh,rh,oh,ie(p("input",{"onUpdate:modelValue":t[4]||(t[4]=i=>e.input=i)},null,512),[[en,e.input]]),p("button",{onClick:t[5]||(t[5]=(...i)=>o.clickURL&&o.clickURL(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",ih)):B("",!0),e.primaryColor==="Light"?(x(),L("img",lh)):B("",!0)])])):e.sourceTab==="youtube"?(x(),L("div",ch,[ah,p("p",uh,ze(e.artist),1),fh,dh,hh,ph,ie(p("input",{"onUpdate:modelValue":t[6]||(t[6]=i=>e.input=i)},null,512),[[en,e.input]]),p("button",{onClick:t[7]||(t[7]=(...i)=>o.clickURL&&o.clickURL(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",mh)):B("",!0),e.primaryColor==="Light"?(x(),L("img",gh)):B("",!0)])])):B("",!0)])):B("",!0)}const bh=et(kd,[["render",_h],["__scopeId","data-v-0fe96286"]]),Tr="/assets/crossdark-CYntds6r.png",Or="/assets/crosslight-CRspF710.png",yh={data:()=>({input:"",rules:[e=>!!e.trim(),e=>(e||"").length<=25]}),computed:{...Ze(["addDialogVis","primaryColor"]),isValid(){return this.rules.every(e=>e(this.input)===!0)}},methods:{clickAdd(){const e=encodeURIComponent(this.input);U.post("/api/clickArtistAdd",e).then(()=>{this.input="",this.$store.commit("SET_SELECTED_ARTIST",""),this.$store.commit("SET_ADD_VIS",!1),this.$store.commit("SET_LOAD_REQUEST",!0)}).catch(t=>{console.error(t)})},clickClose(){this.$store.commit("SET_ADD_VIS",!1)}}},Sh=e=>(Ht("data-v-cb695d37"),e=e(),Kt(),e),vh={key:0,class:"wrapper"},Ch=Sh(()=>p("div",{class:"card-text"},[p("p",{class:"text--primary"},"Type artist's name and confirm.")],-1)),Eh={class:"diag-actions"},wh={key:0,class:"image",src:Tr,alt:"X"},Ah={key:1,class:"image",src:Or,alt:"X"},Th=["disabled"],Oh={key:0,class:"image",src:Gt,alt:"OK"},Rh={key:1,class:"image",src:zt,alt:"OK"};function xh(e,t,n,s,r,o){return e.addDialogVis?(x(),L("div",vh,[Ch,p("div",Eh,[ie(p("input",{"onUpdate:modelValue":t[0]||(t[0]=i=>e.input=i),class:Ee({invalid:!o.isValid})},null,2),[[en,e.input]]),p("button",{onClick:t[1]||(t[1]=(...i)=>o.clickClose&&o.clickClose(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",wh)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Ah)):B("",!0)]),p("button",{onClick:t[2]||(t[2]=(...i)=>o.clickAdd&&o.clickAdd(...i)),class:"imgbutton",disabled:!o.isValid},[e.primaryColor!=="Light"?(x(),L("img",Oh)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Rh)):B("",!0)],8,Th)])])):B("",!0)}const Lh=et(yh,[["render",xh],["__scopeId","data-v-cb695d37"]]),Ih={computed:{...Ze(["progress"])},methods:{...Bf(["setProgress"])}},Ph={class:"progress-container"};function kh(e,t,n,s,r,o){return x(),L("div",Ph,[p("div",{class:"progressbar",style:pn({width:`${e.progress}%`})},null,4)])}const Nh=et(Ih,[["render",kh],["__scopeId","data-v-d29e2d3a"]]),Fh="/assets/blcktext-QjjfTEs8.png",Uh="/assets/MRTlogo-BpL2l-3G.png",Dh={data(){return{theme:"",accent:"",settingsProtection:!0,dbProtection:!0,filters:{Remix:!1,VIP:!1,Instrumental:!1,Acoustic:!1,Extended:!1,Remaster:!1},theme:{Black:!1,Dark:!1,Light:!1},isoDates:!1,autoTheme:!1}},computed:{...Ze(["primaryColor","accentColor"])},created(){U.get("/api/settingsOpened").then(e=>{this.filters=e.data,this.isoDates=e.data.isoDates,this.autoTheme=e.data.autoTheme}).catch(e=>{console.error(e)}),this.theme=this.primaryColor,this.accent=this.accentColor},methods:{clickClose(){this.$store.commit("SET_SETTINGS_OPEN",!1)},setSetting(e,t){switch(e){case"theme":this.$store.commit("SET_PRIMARY_COLOR",this.theme);case"accent":this.$store.commit("SET_ACCENT_COLOR",this.accent);case"isoDates":this.$store.commit("SET_ISODATES",this.isoDates)}U.post("/api/setSetting",{name:e,value:t}).catch(n=>{console.error(n)})},resetSettings(){this.settingsProtection==!0?this.settingsProtection=!1:U.post("/api/resetSettings").then(()=>{this.clickClose()}).catch(e=>{console.error(e)})},resetDB(){this.dbProtection==!0?this.dbProtection=!1:U.post("/api/resetDB").then(()=>{this.clickClose()}).catch(e=>{console.error(e)})},resetProtection(){this.settingsProtection=!0,this.dbProtection=!0}}},ue=e=>(Ht("data-v-6b545924"),e=e(),Kt(),e),Vh={class:"settings"},Bh={key:0,class:"image",src:Tr,alt:"X"},Mh={key:1,class:"image",src:Or,alt:"X"},$h={class:"filterscont"},jh=ue(()=>p("p",null,[p("span",{class:"title"},"Exclusion filters"),p("br"),pe("Select types of songs to be hidden in Combined view.")],-1)),Hh={class:"filters-buttons"},Kh=ue(()=>p("label",null,"Remix",-1)),qh=ue(()=>p("label",null,"VIP",-1)),Wh=ue(()=>p("label",null,"Instrumental",-1)),Gh=ue(()=>p("label",null,"Acoustic",-1)),zh=ue(()=>p("label",null,"Extended",-1)),Jh=ue(()=>p("label",null,"Remaster",-1)),Yh={class:"appearance"},Xh=ue(()=>p("p",{class:"title"},"Appearance",-1)),Qh={class:"appearancecont"},Zh={class:"theme-buttons"},ep=["disabled"],tp=["disabled"],np=["disabled"],sp=ue(()=>p("div",{class:"colorindicator"},null,-1)),rp={class:"accent-buttons"},op=ue(()=>p("label",null,"Lavender",-1)),ip=ue(()=>p("label",null,"Cactus",-1)),lp=ue(()=>p("label",null,"Rose",-1)),cp=ue(()=>p("label",null,"Warm",-1)),ap=ue(()=>p("label",null,"Cloud",-1)),up=ue(()=>p("label",null,"Ocean",-1)),fp={class:"belowAppearance"},dp=ue(()=>p("label",null,"Match system theme",-1)),hp={class:"other"},pp=ue(()=>p("p",{class:"title"},"Other",-1)),mp={class:"flex-items"},gp={class:"flex-padding"},_p=ue(()=>p("label",null,"Dates in yyyy-MM-dd (ISO 8601)",-1)),bp={class:"danger"},yp=ue(()=>p("p",{class:"title"},"Danger zone",-1)),Sp={class:"dangercont"},vp=ia('
logologo
',1);function Cp(e,t,n,s,r,o){return x(),L("div",Vh,[p("button",{onClick:t[0]||(t[0]=i=>o.clickClose()),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",Bh)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Mh)):B("",!0)]),p("section",$h,[jh,p("div",Hh,[p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[1]||(t[1]=i=>r.filters.Remix=i),onChange:t[2]||(t[2]=i=>o.setSetting("filters.Remix",i.target.checked))},null,544),[[ot,r.filters.Remix]]),Kh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[3]||(t[3]=i=>r.filters.VIP=i),onChange:t[4]||(t[4]=i=>o.setSetting("filters.VIP",i.target.checked))},null,544),[[ot,r.filters.VIP]]),qh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[5]||(t[5]=i=>r.filters.Instrumental=i),onChange:t[6]||(t[6]=i=>o.setSetting("filters.Instrumental",i.target.checked))},null,544),[[ot,r.filters.Instrumental]]),Wh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[7]||(t[7]=i=>r.filters.Acoustic=i),onChange:t[8]||(t[8]=i=>o.setSetting("filters.Acoustic",i.target.checked))},null,544),[[ot,r.filters.Acoustic]]),Gh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[9]||(t[9]=i=>r.filters.Extended=i),onChange:t[10]||(t[10]=i=>o.setSetting("filters.Extended",i.target.checked))},null,544),[[ot,r.filters.Extended]]),zh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[11]||(t[11]=i=>r.filters.Remaster=i),onChange:t[12]||(t[12]=i=>o.setSetting("filters.Remaster",i.target.checked))},null,544),[[ot,r.filters.Remaster]]),Jh])])]),p("section",Yh,[Xh,p("div",Qh,[p("div",Zh,[ie(p("input",{type:"radio","onUpdate:modelValue":t[13]||(t[13]=i=>r.theme=i),value:"Black",onChange:t[14]||(t[14]=i=>o.setSetting("theme","Black")),disabled:r.autoTheme},null,40,ep),[[Ge,r.theme]]),p("label",{class:Ee({disabled:r.autoTheme})},"Black",2),ie(p("input",{type:"radio","onUpdate:modelValue":t[15]||(t[15]=i=>r.theme=i),value:"Dark",onChange:t[16]||(t[16]=i=>o.setSetting("theme","Dark")),disabled:r.autoTheme},null,40,tp),[[Ge,r.theme]]),p("label",{class:Ee({disabled:r.autoTheme})},"Dark",2),ie(p("input",{type:"radio","onUpdate:modelValue":t[17]||(t[17]=i=>r.theme=i),value:"Light",onChange:t[18]||(t[18]=i=>o.setSetting("theme","Light")),disabled:r.autoTheme},null,40,np),[[Ge,r.theme]]),p("label",{class:Ee({disabled:r.autoTheme})},"Light",2),sp]),p("div",rp,[ie(p("input",{type:"radio","onUpdate:modelValue":t[19]||(t[19]=i=>r.accent=i),value:"Lavender",onChange:t[20]||(t[20]=i=>o.setSetting("accent","Lavender"))},null,544),[[Ge,r.accent]]),op,ie(p("input",{type:"radio","onUpdate:modelValue":t[21]||(t[21]=i=>r.accent=i),value:"Cactus",onChange:t[22]||(t[22]=i=>o.setSetting("accent","Cactus"))},null,544),[[Ge,r.accent]]),ip,ie(p("input",{type:"radio","onUpdate:modelValue":t[23]||(t[23]=i=>r.accent=i),value:"Rose",onChange:t[24]||(t[24]=i=>o.setSetting("accent","Rose"))},null,544),[[Ge,r.accent]]),lp,ie(p("input",{type:"radio","onUpdate:modelValue":t[25]||(t[25]=i=>r.accent=i),value:"Warm",onChange:t[26]||(t[26]=i=>o.setSetting("accent","Warm"))},null,544),[[Ge,r.accent]]),cp,ie(p("input",{type:"radio","onUpdate:modelValue":t[27]||(t[27]=i=>r.accent=i),value:"Cloud",onChange:t[28]||(t[28]=i=>o.setSetting("accent","Cloud"))},null,544),[[Ge,r.accent]]),ap,ie(p("input",{type:"radio","onUpdate:modelValue":t[29]||(t[29]=i=>r.accent=i),value:"Ocean",onChange:t[30]||(t[30]=i=>o.setSetting("accent","Ocean"))},null,544),[[Ge,r.accent]]),up])]),p("div",fp,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[31]||(t[31]=i=>r.autoTheme=i),onChange:t[32]||(t[32]=i=>o.setSetting("autoTheme",i.target.checked))},null,544),[[ot,r.autoTheme]]),dp])]),p("section",hp,[pp,p("div",mp,[p("div",gp,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[33]||(t[33]=i=>r.isoDates=i),onChange:t[34]||(t[34]=i=>o.setSetting("isoDates",i.target.checked))},null,544),[[ot,r.isoDates]]),_p])])]),p("section",bp,[yp,p("div",Sp,[r.settingsProtection?(x(),L("button",{key:0,onClick:t[35]||(t[35]=i=>o.resetSettings())},"Reset settings")):B("",!0),r.settingsProtection?B("",!0):(x(),L("button",{key:1,onClick:t[36]||(t[36]=i=>o.resetSettings()),onMouseleave:t[37]||(t[37]=i=>o.resetProtection())},"confirm",32)),r.dbProtection?(x(),L("button",{key:2,onClick:t[38]||(t[38]=i=>o.resetDB())},"Reset database")):B("",!0),r.dbProtection?B("",!0):(x(),L("button",{key:3,onClick:t[39]||(t[39]=i=>o.resetDB()),onMouseleave:t[40]||(t[40]=i=>o.resetProtection())},"confirm",32))])]),vp])}const Ep=et(Dh,[["render",Cp],["__scopeId","data-v-6b545924"]]),wp={computed:{...Ze(["tableData","primaryColor"]),hideTable(){return this.tableData.length==0}},methods:{clickCancel(){U.request("/api/cleanArtistSource").catch(e=>{console.error(e)}),this.$store.commit("SET_PREVIEW_VIS",!1)},clickConfirm(){U.request("/api/saveUrl").catch(e=>{console.error(e)}),this.$store.commit("SET_PREVIEW_VIS",!1)}}},Ap=e=>(Ht("data-v-85018fb6"),e=e(),Kt(),e),Tp={class:"preview"},Op=Ap(()=>p("h1",null,"preview",-1)),Rp={key:0},xp={key:1},Lp=["disabled"],Ip={key:0,class:"image",src:Gt,alt:"OK"},Pp={key:1,class:"image",src:zt,alt:"OK"},kp={key:0,class:"image",src:Tr,alt:"X"},Np={key:1,class:"image",src:Or,alt:"X"};function Fp(e,t,n,s,r,o){return x(),L("div",Tp,[Op,o.hideTable?B("",!0):(x(),L("p",Rp,"Confirm only if the table has usable information.")),o.hideTable?(x(),L("p",xp,"Incorrect link.")):B("",!0),p("button",{onClick:t[0]||(t[0]=(...i)=>o.clickConfirm&&o.clickConfirm(...i)),class:"imgbutton",disabled:o.hideTable},[e.primaryColor!=="Light"?(x(),L("img",Ip)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Pp)):B("",!0)],8,Lp),p("button",{onClick:t[1]||(t[1]=(...i)=>o.clickCancel&&o.clickCancel(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",kp)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Np)):B("",!0)])])}const Up=et(wp,[["render",Fp],["__scopeId","data-v-85018fb6"]]);U.defaults.baseURL="http://localhost:57782";const Dp={data(){return{appliedStyles:[],theme:"",accent:""}},components:{ArtistList:Xf,SourceMenu:hd,SourceTable:Pd,DialogsURL:bh,AddArtistDialog:Lh,ProgressBar:Nh,SettingsWindow:Ep,PreviewDialog:Up},created(){this.loadTheme(),this.detectTheme()},computed:{...Ze(["settingsOpen","primaryColor","accentColor","previewVis"])},watch:{primaryColor(e){this.theme=e,this.applyTheme(e,this.accent)},accentColor(e){this.accent=e,this.applyTheme(this.theme,e)}},methods:{loadTheme(){U.get("/api/getThemeConfig").then(e=>{this.$store.commit("SET_PRIMARY_COLOR",e.data.theme),this.$store.commit("SET_ACCENT_COLOR",e.data.accent)}).catch(e=>{console.error(e)})},detectTheme(){U.get("/api/settingsOpened").then(e=>{const t=window.matchMedia("(prefers-color-scheme: dark)");e.data.autoTheme==!0&&(t.matches?this.$store.commit("SET_PRIMARY_COLOR","Black"):this.$store.commit("SET_PRIMARY_COLOR","Light"))}).catch(e=>{console.error(e)})},applyTheme(e,t){this.appliedStyles.forEach(r=>{r.remove()}),this.appliedStyles=[];let n,s;e!==""&&(n=`./primary${e}.css`,s=document.createElement("link"),s.rel="stylesheet",s.href=n,document.head.appendChild(s),this.appliedStyles.push(s)),t!==""&&(n=`./secondary${t}.css`,s=document.createElement("link"),s.rel="stylesheet",s.href=n,document.head.appendChild(s),this.appliedStyles.push(s))}}},Vp={key:0,class:"app"},Bp={class:"list"},Mp={class:"maincontent"},$p={key:0,class:"topbar"},jp={class:"sourcetable"},Hp={key:1,class:"dialogsurl"},Kp={class:"progressbar"},qp={key:1,class:"app"};function Wp(e,t,n,s,r,o){const i=nt("ArtistList"),l=nt("PreviewDialog"),c=nt("SourceMenu"),f=nt("AddArtistDialog"),u=nt("SourceTable"),d=nt("DialogsURL"),g=nt("ProgressBar"),C=nt("SettingsWindow");return x(),L(_e,null,[e.settingsOpen?B("",!0):(x(),L("div",Vp,[p("div",Bp,[e.previewVis?B("",!0):(x(),Hs(i,{key:0})),e.previewVis?(x(),Hs(l,{key:1,class:"preview"})):B("",!0)]),p("div",Mp,[e.previewVis?B("",!0):(x(),L("div",$p,[le(c)])),le(f),p("div",jp,[le(u)]),e.previewVis?B("",!0):(x(),L("div",Hp,[le(d)]))]),p("div",Kp,[le(g)])])),e.settingsOpen?(x(),L("div",qp,[le(C)])):B("",!0)],64)}const Gp=et(Dp,[["render",Wp],["__scopeId","data-v-e34fd722"]]),zp={artist:"",sourceTab:"",tableData:[],addDialogVis:!1,loadListRequest:!1,allowButtons:!0,progress:0,settingsOpen:!1,primaryColor:"",accentColor:"",previewVis:!1,isoDates:!1,urlExists:!1},Jp={SET_SOURCE_TAB(e,t){e.sourceTab=t},SET_SELECTED_ARTIST(e,t){e.artist=t},SET_TABLE_CONTENT(e,t){e.tableData=t,e.addDialogVis=!1},SET_ADD_VIS(e,t){e.addDialogVis=t},SET_LOAD_REQUEST(e,t){e.loadListRequest=t},SET_ALLOW_BUTTONS(e,t){e.allowButtons=t},SET_PROGRESS(e,t){e.progress=t*100,e.progress==100&&(e.progress=0)},SET_SETTINGS_OPEN(e,t){e.settingsOpen=t},SET_PRIMARY_COLOR(e,t){e.primaryColor=t},SET_ACCENT_COLOR(e,t){e.accentColor=t},SET_PREVIEW_VIS(e,t){e.previewVis=t},SET_ISODATES(e,t){e.isoDates=t},SET_URL_EXISTS(e,t){e.urlExists=t}},Yp={},Xp={},Qp=Vf({state:zp,mutations:Jp,actions:Yp,getters:Xp}),bl=za(Gp);bl.use(Qp);bl.mount("#app"); diff --git a/src/test/testresources/testdb.db b/src/test/testresources/testdb.db new file mode 100644 index 0000000000000000000000000000000000000000..189e3ce11637b21719ab683c4ea79be8651c2f26 GIT binary patch literal 32768 zcmeI)&1=(O90%|xP1mq!Ovg|+ zExVyRYL1K(jwAO}l@M~s-XrWCz7nh;ggb1@MariY56P{a*U98BB3}JK=)u^}vE8wF zQcHefyLdqW0uX=z1Rwwb2tWV=5IDO)OBCg)DXw$J(W`Z1!)jD_Ok+3Pjx3c6`AR{p z98LjCoH|nV=&33NGMOjg}gHf+n z{|{TiCehPp5M*6On_nvzSMuej>Vv}5IjL>e8|{|4QMGlm`NHeV3sw!?*|uzdL|$a8 z-Lz`fZnJLbwUc`LR@-S;{Xt5z^NECw4RqM{J$v1{BuY5Mi6p` zTfV2~FgjqbbCR>a-FH5{HEb}rBGfeMD75H+$E6V z+&bRk|E5`Y47*|UJsaSz|MT>S(C_p!J)-Z1#Sim@00bZa0SG_<0uX=z1Rwwb2wX6M zYg|G}$%J^h`>2qZaL2c087ZE{Q$gIx6_-~Qi_42^saQ0ub;E8e-P+kOEU~tDdQ9jK zb_L*=ez{_Gfk3#zE1bXLpW{!;T1?`V z(cn&i==1;d?P(1n4gm;200Izz00bZa0SG_<0uX?}{}Pzw!|(C$|3<)neg6M95Bjeq literal 0 HcmV?d00001 From 837305c0739e37ebe3fe688c8f59f63381c08460 Mon Sep 17 00:00:00 2001 From: BLCK <123077751+BLCK-B@users.noreply.github.com> Date: Sun, 26 May 2024 10:00:57 +0200 Subject: [PATCH 17/22] fixed slow batching --- .../Core/ErrorLogging.java | 2 - .../MusicReleaseTracker/DB/DBqueries.java | 113 ++++++++---------- .../DB/ManageMigrateDB.java | 23 ++-- .../MusicReleaseTracker/GUIController.java | 8 +- .../Scraping/ScrapeProcess.java | 15 ++- .../blck/MusicReleaseTracker/StartSetup.java | 2 - .../Scraping/ScrapeProcessTest.java | 9 +- .../blck/MusicReleaseTracker/helperDB.java | 23 ++-- src/test/testresources/testdb.db | Bin 32768 -> 32768 bytes 9 files changed, 91 insertions(+), 104 deletions(-) diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/ErrorLogging.java b/src/main/java/com/blck/MusicReleaseTracker/Core/ErrorLogging.java index 5b93fb8..2ee2fc3 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Core/ErrorLogging.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Core/ErrorLogging.java @@ -41,7 +41,6 @@ public void error(Exception e, Severity level, String message) { FileHandler fileHandler = null; try { final String errorLogs = store.getErrorLogsPath(); - // filehandler logging the error fileHandler = new FileHandler(errorLogs, true); fileHandler.setFormatter(new SimpleFormatter()); // clear log when it reaches approx 0.1 MB @@ -50,7 +49,6 @@ public void error(Exception e, Severity level, String message) { if (logFileSize > 100000) { Files.write(path, new byte[0], StandardOpenOption.TRUNCATE_EXISTING); } - // log the error logger.addHandler(fileHandler); switch (level) { case SEVERE -> logger.log(Level.SEVERE, message, e); diff --git a/src/main/java/com/blck/MusicReleaseTracker/DB/DBqueries.java b/src/main/java/com/blck/MusicReleaseTracker/DB/DBqueries.java index 3d4242f..7abd04e 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/DB/DBqueries.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DB/DBqueries.java @@ -49,9 +49,8 @@ public List getArtistList() { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT artist FROM artists ORDER BY artist LIMIT 500"); - while (rs.next()) { + while (rs.next()) dataList.add(rs.getString("artist")); - } stmt.close(); rs.close(); } catch (SQLException e) { @@ -61,17 +60,15 @@ public List getArtistList() { } public List loadTable(SourcesEnum source, String name) { - // adding data to tableContent List tableContent = new ArrayList<>(); try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "SELECT song, date FROM " + source + " WHERE artist = ? ORDER BY date DESC LIMIT 100"; - PreparedStatement pstmt = conn.prepareStatement(sql); + PreparedStatement pstmt = conn.prepareStatement( + "SELECT song, date FROM " + source + " WHERE artist = ? ORDER BY date DESC LIMIT 100"); pstmt.setString(1, name); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { - String songsCol = rs.getString("song"); - String datesCol = rs.getString("date"); - tableContent.add(new TableModel(songsCol, null, datesCol)); + tableContent.add(new TableModel( + rs.getString("song"), null, rs.getString("date"))); } pstmt.close(); rs.close(); @@ -88,10 +85,8 @@ public List loadCombviewTable() { PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet rs = pstmt.executeQuery(); while (rs.next()) { - String songsCol = rs.getString("song"); - String artistsCol = rs.getString("artist"); - String datesCol = rs.getString("date"); - tableContent.add(new TableModel(songsCol, artistsCol, datesCol)); + tableContent.add(new TableModel( + rs.getString("song"), rs.getString("artist"), rs.getString("date"))); } pstmt.close(); rs.close(); @@ -103,8 +98,8 @@ public List loadCombviewTable() { public void insertIntoArtistList(String name) { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "INSERT INTO artists (artist) values(?)"; - PreparedStatement pstmt = conn.prepareStatement(sql); + PreparedStatement pstmt = conn.prepareStatement( + "INSERT INTO artists (artist) values(?)"); pstmt.setString(1, name); pstmt.executeUpdate(); pstmt.close(); @@ -136,9 +131,9 @@ public void updateArtistSourceID(String name, SourcesEnum source, String newID) public String getArtistSourceID(String name, SourcesEnum source) { String ID = null; - String sql = "SELECT url" + source + " FROM artists WHERE artist = ?"; try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - PreparedStatement pstmt = conn.prepareStatement(sql); + PreparedStatement pstmt = conn.prepareStatement( + "SELECT url" + source + " FROM artists WHERE artist = ?"); pstmt.setString(1, name); ID = pstmt.executeQuery().getString(1); pstmt.close(); @@ -150,8 +145,8 @@ public String getArtistSourceID(String name, SourcesEnum source) { public void clearArtistDataFrom(String name, String table) { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "DELETE FROM " + table + " WHERE artist = ?"; - PreparedStatement pstmt = conn.prepareStatement(sql); + PreparedStatement pstmt = conn.prepareStatement( + "DELETE FROM " + table + " WHERE artist = ?"); pstmt.setString(1, name); pstmt.executeUpdate(); } catch (SQLException e) { @@ -166,16 +161,16 @@ public void removeArtist(String name) { public void truncateScrapeData(boolean all) { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { + Statement stmt = conn.createStatement(); if (all) { - for (SourcesEnum sourceTable : SourcesEnum.values()) { - String sql = "DELETE FROM " + sourceTable; - Statement stmt = conn.createStatement(); - stmt.executeUpdate(sql); - } + for (SourcesEnum sourceTable : SourcesEnum.values()) + stmt.addBatch("DELETE FROM " + sourceTable); } - String sql = "DELETE FROM combview"; - Statement stmt = conn.createStatement(); - stmt.executeUpdate(sql); + stmt.addBatch("DELETE FROM combview"); + conn.setAutoCommit(false); + stmt.executeBatch(); + conn.setAutoCommit(true); + stmt.close(); } catch (SQLException e) { log.error(e, ErrorLogging.Severity.WARNING, "error clearing DB"); } @@ -186,9 +181,8 @@ public ArrayList getSourceTablesDataForCombview() { ArrayList songObjectList = new ArrayList<>(); try (Connection conn = DriverManager.getConnection(store.getDBpath())) { for (SourcesEnum source : SourcesEnum.values()) { - String sql = "SELECT * FROM " + source + " ORDER BY date DESC LIMIT 200"; Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(sql); + ResultSet rs = stmt.executeQuery("SELECT * FROM " + source + " ORDER BY date DESC LIMIT 200"); while (rs.next()) { String songName = rs.getString("song"); String songArtist = rs.getString("artist"); @@ -214,7 +208,6 @@ public ArrayList getSourceTablesDataForCombview() { } private boolean filterWords(String songName, String songType) { - // filtering user-selected keywords for (String checkword : store.getFilterWords()) { if (songType != null) { if ((songType.toLowerCase()).contains(checkword.toLowerCase())) @@ -230,26 +223,26 @@ public LinkedList getAllScrapers() { // creating a list of scraper objects: one scraper holds one URL LinkedList scrapers = new LinkedList<>(); try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "SELECT artist FROM artists LIMIT 500"; - PreparedStatement pstmt = conn.prepareStatement(sql); + PreparedStatement pstmt = conn.prepareStatement( + "SELECT artist FROM artists LIMIT 500"); ResultSet artistResults = pstmt.executeQuery(); // cycling artists while (artistResults.next()) { String artist = artistResults.getString("artist"); // cycling sources for (SourcesEnum webSource : SourcesEnum.values()) { - sql = "SELECT * FROM artists WHERE artist = ? LIMIT 100"; - pstmt = conn.prepareStatement(sql); + pstmt = conn.prepareStatement( + "SELECT * FROM artists WHERE artist = ? LIMIT 100"); pstmt.setString(1, artist); ResultSet rs = pstmt.executeQuery(); String url = rs.getString("url" + webSource); if (url == null) continue; switch (webSource) { - case musicbrainz -> scrapers.add(new ScraperMusicbrainz(log, this, artist, url)); - case beatport -> scrapers.add(new ScraperBeatport(log, this, artist, url)); - case junodownload -> scrapers.add(new ScraperJunodownload(log, this, artist, url)); - case youtube -> scrapers.add(new ScraperYoutube(log, this, artist, url)); + case musicbrainz -> scrapers.add(new ScraperMusicbrainz(log, this, artist, url)); + case beatport -> scrapers.add(new ScraperBeatport(log, this, artist, url)); + case junodownload -> scrapers.add(new ScraperJunodownload(log, this, artist, url)); + case youtube -> scrapers.add(new ScraperYoutube(log, this, artist, url)); } } } @@ -262,44 +255,42 @@ public LinkedList getAllScrapers() { public void batchInsertSongs(ArrayList songList, SourcesEnum source, int limit) { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - int i = 0; String sql; - PreparedStatement pstmt = null; + boolean types = false; + if (songList.get(0).getType() != null && source != null) { + sql = "insert into " + source + "(song, artist, date, type) values(?, ?, ?, ?)"; + types = true; + } else { + if (source != null) + sql = "insert into " + source + "(song, artist, date) values(?, ?, ?)"; + else + sql = "insert into combview(song, artist, date) values(?, ?, ?)"; + } + PreparedStatement pstmt = conn.prepareStatement(sql); + int i = 0; for (Song songObject : songList) { if (i == limit) break; - if (songObject.getType() != null && source != null) { - sql = "insert into " + source + "(song, artist, date, type) values(?, ?, ?, ?)"; - pstmt = conn.prepareStatement(sql); - pstmt.setString(1, songObject.getName()); - pstmt.setString(2, songObject.getArtist()); - pstmt.setString(3, songObject.getDate()); + pstmt.setString(1, songObject.getName()); + pstmt.setString(2, songObject.getArtist()); + pstmt.setString(3, songObject.getDate()); + if (types) pstmt.setString(4, songObject.getType()); - } else { - if (source != null) - sql = "insert into " + source + "(song, artist, date) values(?, ?, ?)"; - else - sql = "insert into combview(song, artist, date) values(?, ?, ?)"; - pstmt = conn.prepareStatement(sql); - pstmt.setString(1, songObject.getName()); - pstmt.setString(2, songObject.getArtist()); - pstmt.setString(3, songObject.getDate()); - } - pstmt.executeUpdate(); - i++; + ++i; + pstmt.addBatch(); } conn.setAutoCommit(false); - conn.commit(); + pstmt.executeBatch(); conn.setAutoCommit(true); + pstmt.close(); } catch (SQLException e) { - log.error(e, ErrorLogging.Severity.SEVERE, "error inserting a set of songs"); + log.error(e, ErrorLogging.Severity.SEVERE, "error inserting a batch of songs"); } } public void vacuum() { try (Connection conn = DriverManager.getConnection(store.getDBpath())) { - String sql = "VACUUM;"; - PreparedStatement pstmt = conn.prepareStatement(sql); + PreparedStatement pstmt = conn.prepareStatement("VACUUM;"); pstmt.execute(); pstmt.close(); } catch (SQLException e) { diff --git a/src/main/java/com/blck/MusicReleaseTracker/DB/ManageMigrateDB.java b/src/main/java/com/blck/MusicReleaseTracker/DB/ManageMigrateDB.java index dde7001..6a21939 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/DB/ManageMigrateDB.java +++ b/src/main/java/com/blck/MusicReleaseTracker/DB/ManageMigrateDB.java @@ -37,6 +37,7 @@ public ManageMigrateDB(ValueStore valueStore, ErrorLogging errorLogging) { public void createDBandSourceTables(String path) { // note: generate by string templates after preview try (Connection conn = DriverManager.getConnection(path)) { + Statement stmt = conn.createStatement(); String sql = """ CREATE TABLE IF NOT EXISTS musicbrainz ( song text NOT NULL, @@ -44,8 +45,7 @@ CREATE TABLE IF NOT EXISTS musicbrainz ( date text NOT NULL ); """; - Statement stmt = conn.createStatement(); - stmt.execute(sql); + stmt.addBatch(sql); sql = """ CREATE TABLE IF NOT EXISTS beatport ( @@ -55,8 +55,7 @@ CREATE TABLE IF NOT EXISTS beatport ( type text NOT NULL ); """; - stmt = conn.createStatement(); - stmt.execute(sql); + stmt.addBatch(sql); sql = """ CREATE TABLE IF NOT EXISTS junodownload ( @@ -65,8 +64,7 @@ CREATE TABLE IF NOT EXISTS junodownload ( date text NOT NULL ); """; - stmt = conn.createStatement(); - stmt.execute(sql); + stmt.addBatch(sql); sql = """ CREATE TABLE IF NOT EXISTS youtube ( @@ -75,8 +73,7 @@ CREATE TABLE IF NOT EXISTS youtube ( date text NOT NULL ); """; - stmt = conn.createStatement(); - stmt.execute(sql); + stmt.addBatch(sql); sql = """ CREATE TABLE IF NOT EXISTS artists ( @@ -87,8 +84,7 @@ CREATE TABLE IF NOT EXISTS artists ( urlyoutube text ); """; - stmt = conn.createStatement(); - stmt.execute(sql); + stmt.addBatch(sql); sql = """ CREATE TABLE IF NOT EXISTS combview ( @@ -97,9 +93,11 @@ CREATE TABLE IF NOT EXISTS combview ( date text NOT NULL ); """; - stmt = conn.createStatement(); - stmt.execute(sql); + stmt.addBatch(sql); + conn.setAutoCommit(false); + stmt.executeBatch(); + conn.setAutoCommit(true); stmt.close(); } catch (SQLException e) { log.error(e, ErrorLogging.Severity.SEVERE, "error creating DB file"); @@ -148,7 +146,6 @@ public void migrateDB() { pstmt.executeBatch(); connDBtemplate.commit(); connDBtemplate.setAutoCommit(true); - pstmt.clearBatch(); pstmt.close(); } catch (Exception e) { log.error(e, ErrorLogging.Severity.SEVERE, "error updating DB file"); diff --git a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java index 20158a8..d086779 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/GUIController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/GUIController.java @@ -162,12 +162,8 @@ public HashMap settingsOpened() { config.readConfig(ConfigTools.configOptions.filters); ArrayList filterWords = store.getFilterWords(); String[] allFilters = new String[]{"Acoustic", "Extended", "Instrumental", "Remaster", "Remix", "VIP"}; - for (String filter : allFilters) { - if (filterWords.contains(filter)) - configData.put(filter, true); - else - configData.put(filter, false); - } + for (String filter : allFilters) + configData.put(filter, filterWords.contains(filter)); config.readConfig(ConfigTools.configOptions.isoDates); configData.put("isoDates", store.getIsoDates()); diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java index 489e85c..a6752e9 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java @@ -7,6 +7,9 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.Statement; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -37,9 +40,9 @@ public class ScrapeProcess { private final SSEController SSE; @Autowired - public ScrapeProcess(ErrorLogging errorLogging, DBqueries DB, SSEController sseController) { + public ScrapeProcess(ErrorLogging errorLogging, DBqueries dBqueries, SSEController sseController) { this.log = errorLogging; - this.DB = DB; + this.DB = dBqueries; this.SSE = sseController; } @@ -53,12 +56,10 @@ public void scrapeData(ScraperManager scraperManager) { return; int remaining = 1; double progress = 0.0; - while (remaining != 0) { - SSE.sendProgress(progress); - if (scrapeCancel) - break; + while (remaining != 0 && !scrapeCancel) { remaining = scraperManager.scrapeNext(); progress = ((double) initSize - (double) remaining) / (double) initSize; + SSE.sendProgress(progress); } SSE.sendProgress(1.0); System.gc(); @@ -67,6 +68,8 @@ public void scrapeData(ScraperManager scraperManager) { public void fillCombviewTable() { DB.truncateScrapeData(false); ArrayList songObjectList = DB.getSourceTablesDataForCombview(); + if (songObjectList.isEmpty()) + return; ArrayList finalSortedList = processSongs(songObjectList); DB.batchInsertSongs(finalSortedList, null, 115); System.gc(); diff --git a/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java b/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java index d22dc4f..66535a7 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java +++ b/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java @@ -1,10 +1,8 @@ package com.blck.MusicReleaseTracker; - import com.blck.MusicReleaseTracker.Core.ErrorLogging; import com.blck.MusicReleaseTracker.Core.ValueStore; import org.springframework.beans.factory.annotation.Autowired; -import org.sqlite.core.DB; import java.io.File; diff --git a/src/test/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcessTest.java b/src/test/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcessTest.java index b0f105e..06bf84d 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcessTest.java +++ b/src/test/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcessTest.java @@ -82,11 +82,10 @@ void calculatesCorrectProgress() { verify(sseController, atLeastOnce()).sendProgress(progressCaptor.capture()); List values = progressCaptor.getAllValues(); - assertEquals(0.0, values.get(0)); - assertEquals(0.25, values.get(1)); - assertEquals(0.5, values.get(2)); - assertEquals(0.75, values.get(3)); - assertEquals(1, values.get(4)); + assertEquals(0.25, values.get(0)); + assertEquals(0.5, values.get(1)); + assertEquals(0.75, values.get(2)); + assertEquals(1, values.get(3)); } @Test diff --git a/src/test/java/com/blck/MusicReleaseTracker/helperDB.java b/src/test/java/com/blck/MusicReleaseTracker/helperDB.java index 9df80ad..2e4fefc 100644 --- a/src/test/java/com/blck/MusicReleaseTracker/helperDB.java +++ b/src/test/java/com/blck/MusicReleaseTracker/helperDB.java @@ -72,13 +72,14 @@ private static void clearTables() { try (Connection conn = DriverManager.getConnection(testDBpath)) { Statement stmt = conn.createStatement(); for (SourcesEnum sourceTable : SourcesEnum.values()) { - String sql = "DELETE FROM " + sourceTable; - stmt.executeUpdate(sql); + stmt.addBatch("DELETE FROM " + sourceTable); } - String sql = "DELETE FROM combview"; - stmt.executeUpdate(sql); - sql = "DELETE FROM artists"; - stmt.executeUpdate(sql); + stmt.addBatch("DELETE FROM combview"); + stmt.addBatch("DELETE FROM artists"); + conn.setAutoCommit(false); + stmt.executeBatch(); + conn.setAutoCommit(true); + stmt.close(); } catch (SQLException e) { throw new RuntimeException(e); } @@ -86,14 +87,18 @@ private static void clearTables() { private static void insertIntoArtists(String... artists) { try (Connection conn = DriverManager.getConnection(testDBpath)) { + String sql = "INSERT INTO artists (artist, urlmusicbrainz, urlbeatport) values(?, ?, ?)"; + PreparedStatement pstmt = conn.prepareStatement(sql); for (String artist : artists) { - String sql = "INSERT INTO artists (artist, urlmusicbrainz, urlbeatport) values(?, ?, ?)"; - PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, artist); pstmt.setString(2, "IDMB"); pstmt.setString(3, "IDBP"); - pstmt.executeUpdate(); + pstmt.addBatch(); } + conn.setAutoCommit(false); + pstmt.executeBatch(); + conn.setAutoCommit(true); + pstmt.close(); } catch (SQLException e) { throw new RuntimeException(e); } diff --git a/src/test/testresources/testdb.db b/src/test/testresources/testdb.db index 189e3ce11637b21719ab683c4ea79be8651c2f26..67641b26360220c5ba9ae4e7a7021026327b8318 100644 GIT binary patch delta 19 acmZo@U}|V!njp<+Fj2;t(O_f3f_eZuHwH2Q delta 19 acmZo@U}|V!njp=%exi&s Date: Mon, 27 May 2024 16:34:21 +0200 Subject: [PATCH 18/22] scrape style --- .../Scraping/ScrapeProcess.java | 5 +- .../blck/MusicReleaseTracker/StartSetup.java | 13 ++++++ .../static/assets/index-C3_hPEEi.css | 1 - .../resources/static/assets/index-CB9h-D7W.js | 26 ----------- src/main/resources/static/index.html | 4 +- vue/src/components/SourceMenu.vue | 46 +++++++++++-------- 6 files changed, 45 insertions(+), 50 deletions(-) delete mode 100644 src/main/resources/static/assets/index-C3_hPEEi.css delete mode 100644 src/main/resources/static/assets/index-CB9h-D7W.js diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java index a6752e9..6466f1e 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java @@ -58,8 +58,11 @@ public void scrapeData(ScraperManager scraperManager) { double progress = 0.0; while (remaining != 0 && !scrapeCancel) { remaining = scraperManager.scrapeNext(); + if (scrapeCancel) + break; progress = ((double) initSize - (double) remaining) / (double) initSize; - SSE.sendProgress(progress); + if (progress != 1.0) + SSE.sendProgress(progress); } SSE.sendProgress(1.0); System.gc(); diff --git a/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java b/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java index 66535a7..8e7af39 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java +++ b/src/main/java/com/blck/MusicReleaseTracker/StartSetup.java @@ -6,6 +6,19 @@ import java.io.File; +/* MusicReleaseTracker + Copyright (C) 2023 BLCK + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see .*/ + public class StartSetup { private final ValueStore store; private final ErrorLogging log; diff --git a/src/main/resources/static/assets/index-C3_hPEEi.css b/src/main/resources/static/assets/index-C3_hPEEi.css deleted file mode 100644 index 852bf15..0000000 --- a/src/main/resources/static/assets/index-C3_hPEEi.css +++ /dev/null @@ -1 +0,0 @@ -*[data-v-18b2502f]::-webkit-scrollbar{width:8px;background:transparent}*[data-v-18b2502f]::-webkit-scrollbar-thumb{background-color:var(--dull-color)}.listbtn[data-v-18b2502f]{width:92%;height:28px;border-radius:0;margin:0;display:flex;align-items:center;white-space:nowrap;overflow:hidden;padding-left:7px}.artistlist[data-v-18b2502f]{height:calc(100vh - 40px);overflow-y:scroll}.artistlist li[data-v-18b2502f]{list-style-type:none}.buttonspace[data-v-18b2502f]{margin-bottom:5px}.addbtn[data-v-18b2502f],.morebtn[data-v-18b2502f]{font-size:12px;width:75px;height:28px;border:2px solid var(--dull-color);border-radius:6px;background-color:transparent;color:var(--contrast-color)}.addbtn[data-v-18b2502f]{margin-left:5px}.addbtn[data-v-18b2502f]:hover,.morebtn[data-v-18b2502f]:hover{background-color:var(--accent-color);border:2px solid var(--accent-color);color:var(--accent-contrast)}.addbtn[data-v-18b2502f]:active,.morebtn[data-v-18b2502f]:active{opacity:75%}.morebtn[data-v-18b2502f]{margin-left:5px}.dropdown[data-v-18b2502f]{position:relative;display:grid;grid-template-columns:repeat(1,1fr);background-color:var(--subtle-color);padding-right:10px;padding-left:6px}.dropdown .deletebtn[data-v-18b2502f]{font-size:12px;height:25px;margin-top:3px;border:2px solid var(--dull-color);border-radius:6px;background-color:transparent;color:var(--contrast-color)}.deletebtn[data-v-18b2502f]:hover{background-color:red;border:2px solid red}.listbtn[data-v-18b2502f]:hover{background-color:var(--duller-color)}.highlighted[data-v-18b2502f]{background-color:var(--accent-color);color:var(--accent-contrast)}.highlighted[data-v-18b2502f]:hover{background-color:var(--accent-color)}[data-v-18b2502f]:disabled{opacity:.5;pointer-events:none}.wrapper[data-v-671de189]{min-width:500px;width:100%;display:flex;align-items:center;height:38px}.tabs[data-v-671de189]{display:flex;text-align:center;font-weight:700;flex-grow:1;height:38px}.image[data-v-671de189]{height:32px;width:32px}.imgbutton1[data-v-671de189]:hover,.imgbutton2[data-v-671de189]:hover{opacity:70%}.imgbutton1[data-v-671de189]{padding:0;margin-left:8px;background-color:var(--accent-color);border:none;margin-top:2px;height:32px;width:32px}.imgbutton2[data-v-671de189]{padding:0;margin-left:8px;margin-right:20px;border:none;margin-top:2px;border-radius:50px;height:32px;width:32px}.cvtab[data-v-671de189]{width:80%;max-width:390px;padding:8px;border:solid 3px transparent;border-bottom:solid 3px var(--accent-color)}.stab[data-v-671de189]{width:20%;max-width:110px;padding:8px;border:solid 3px transparent;border-bottom:solid 3px var(--accent-color);white-space:nowrap;overflow:hidden}.tabs[data-v-671de189] :hover{border-bottom:solid 3px var(--dull-color)}.active[data-v-671de189]{transition:.15s;background-color:var(--accent-color);color:var(--accent-contrast);border-bottom:solid 3px var(--accent-color);border-radius:5px}.active[data-v-671de189]:hover{border-bottom:solid 3px var(--accent-color)}.scrapenotice[data-v-671de189]{position:absolute;z-index:50;background-color:var(--duller-color);border-radius:5px;padding-right:10px;padding-left:10px;right:14px;top:42px}.fade-enter-from[data-v-671de189],.fade-leave-to[data-v-671de189]{opacity:0}.fade-enter-active[data-v-671de189],.fade-leave-active[data-v-671de189]{transition:.15s}[data-v-671de189]:disabled{opacity:.5;pointer-events:none}.table-header[data-v-19adbfff]{flex-shrink:0;overflow:hidden;z-index:3;position:fixed;width:calc(100% - 170px)}.table-body[data-v-19adbfff]{flex-grow:1;overflow-y:auto;-webkit-user-select:text;user-select:text;margin-bottom:10vh}table[data-v-19adbfff]{width:100%;min-width:500px;border-collapse:collapse}th[data-v-19adbfff],td[data-v-19adbfff]{padding:4px}th[data-v-19adbfff]{background-color:var(--primary-color);border:none;position:sticky;top:0}.song[data-v-19adbfff],.tdsong[data-v-19adbfff],.artist[data-v-19adbfff],.tdartist[data-v-19adbfff]{width:50%;max-width:120px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.date[data-v-19adbfff],.tddate[data-v-19adbfff]{width:100px;min-width:100px}.future-date[data-v-19adbfff]{opacity:40%}.emptynotice[data-v-19adbfff]{position:absolute;left:40%;top:40%;color:var(--dull-color)}.quickstart[data-v-19adbfff]{position:relative;font-size:15px;line-height:22px;left:5%;top:5%}.quickstart .title[data-v-19adbfff]{font-weight:700}.tddate[data-v-19adbfff]{display:flex;justify-content:flex-end;margin-right:30px}p[data-v-0fe96286]{line-height:1.4}.dialog[data-v-0fe96286]{width:375px;height:280px;background-color:var(--primary-color);border:2px solid var(--contrast-color);border-radius:3px;color:var(--contrast-color);padding:8px}input[data-v-0fe96286]{background-color:var(--duller-color);color:var(--contrast-color);border:none;width:345px;position:absolute;bottom:5px;left:5px;font-size:13px;height:18px}input[data-v-0fe96286]:focus{outline:none}button[data-v-0fe96286]{color:#000;border:none;position:absolute;right:5px;bottom:5px}button[data-v-0fe96286]:hover{opacity:70%}a[data-v-0fe96286]{color:var(--accent-color);font-weight:700;text-decoration:none}a[data-v-0fe96286]:hover{text-decoration:underline}h1[data-v-0fe96286]{font-size:17px;font-weight:400}.variabletext[data-v-0fe96286]{color:var(--accent-color)}.artist[data-v-0fe96286]{-webkit-user-select:text;user-select:text}.imgbutton[data-v-0fe96286],.image[data-v-0fe96286]{height:23px;width:23px;padding:0;float:right;margin-right:2px;background-color:transparent}.imgbutton[data-v-0fe96286]:hover{opacity:50%}[data-v-0fe96286]:disabled{opacity:.5;pointer-events:none}.wrapper[data-v-cb695d37]{top:25%;left:35%;width:325px;height:240px;position:absolute;z-index:3;background-color:var(--primary-color);border:2px solid var(--contrast-color);border-radius:3px;padding:8px}.diag-actions[data-v-cb695d37]{position:absolute;bottom:3px;left:5px}button[data-v-cb695d37]{border:none}input[data-v-cb695d37]{background-color:var(--duller-color);color:var(--contrast-color);width:200px;margin-right:58px;margin-left:10px;border:none}input[data-v-cb695d37]:focus{outline:none}.imgbutton[data-v-cb695d37],.image[data-v-cb695d37]{height:23px;width:23px;padding:0;float:right;margin-left:5px;margin-right:2px;background-color:transparent}.imgbutton[data-v-cb695d37]{position:relative}.imgbutton[data-v-cb695d37]:hover{opacity:50%}[data-v-cb695d37]:disabled{opacity:.3;pointer-events:none}*[data-v-d29e2d3a]{transition:.2s}.progress-container[data-v-d29e2d3a]{background-color:transparent}.progressbar[data-v-d29e2d3a]{height:5px;line-height:5px;text-align:center;background-color:var(--accent-color)}*[data-v-6b545924]{transition:.1s}.title[data-v-6b545924]{font-weight:700}.settings[data-v-6b545924]{font-family:arial,sans-serif;font-size:14px;-webkit-user-select:none;user-select:none;background-color:var(--primary-color);color:var(--contrast-color);overflow-y:scroll;overflow-x:hidden;display:grid;align-content:start;width:100%;justify-content:center;accent-color:var(--contrast-color)}@media screen and (min-width: 950px){.settings[data-v-6b545924]{display:grid;grid-template-columns:repeat(2,0fr)}section[data-v-6b545924]{margin-right:90px}}.filters-buttons[data-v-6b545924]{margin-top:10px;display:grid;grid-template-columns:repeat(2,1fr);grid-gap:10px;max-height:80px}.flex-items[data-v-6b545924]{display:flex;flex-direction:column}.flex-padding[data-v-6b545924]{padding:5px}.appearancecont[data-v-6b545924]{display:flex;accent-color:var(--dull-color)}.theme-buttons[data-v-6b545924]{display:grid;grid-template-columns:repeat(2,1fr);width:30%;padding-right:20px;line-height:18px}.accent-buttons[data-v-6b545924]{display:grid;grid-template-columns:repeat(4,1fr)}.belowAppearance[data-v-6b545924]{margin-left:15px;margin-top:6px}.imgbutton[data-v-6b545924]{position:absolute;right:0;top:0;padding:0;margin:10px;background-color:transparent;border:none;transition:0s}.imgbutton[data-v-6b545924]:hover{opacity:60%}.image[data-v-6b545924]{height:33px}input[data-v-6b545924]{margin-right:5px}section[data-v-6b545924]{position:relative;margin-top:20px;left:40px;padding:1px 15px 10px;background-color:var(--duller-color);border-radius:5px;transition:.15s;width:345px}.self[data-v-6b545924]{justify-self:center;width:280px;background-color:transparent}.blckimg[data-v-6b545924]{height:48px;background-color:#000;border-radius:5px;padding:12px;margin-right:22px}.mrtimg[data-v-6b545924]{height:72px;border-radius:10px}.colorindicator[data-v-6b545924]{position:absolute;right:0;top:0;height:100%;width:8px;background-color:var(--accent-color);border-top-right-radius:5px;border-bottom-right-radius:5px}.dangercont[data-v-6b545924]{display:flex;justify-content:space-evenly}.danger button[data-v-6b545924]{border-radius:5px;background-color:transparent;color:var(--contrast-color);border:2px solid red;padding:4px;width:120px}.danger button[data-v-6b545924]:hover{background-color:red}.disabled[data-v-6b545924]{opacity:.3}.preview[data-v-85018fb6]{width:100%;height:100%;background-color:var(--subtle-color);font-size:15px}h1[data-v-85018fb6]{font-size:18px;color:var(--accent-color)}p[data-v-85018fb6],h1[data-v-85018fb6]{position:relative;left:6px}button[data-v-85018fb6]{margin-left:8px;border:none;border-radius:5px;width:60px}.imgbutton[data-v-85018fb6],.image[data-v-85018fb6]{margin-left:22px;height:26px;width:26px;padding:0;background-color:transparent}.imgbutton[data-v-85018fb6]:hover{opacity:50%}[data-v-85018fb6]:disabled{opacity:.5;pointer-events:none}*[data-v-e34fd722]{scrollbar-color:var(--dull-color) transparent}*[data-v-e34fd722]::-webkit-scrollbar-thumb{background-color:var(--dull-color)}*[data-v-e34fd722]::-webkit-scrollbar{width:8px;background:transparent}.app[data-v-e34fd722]{font-family:arial,sans-serif;font-size:14px;-webkit-user-select:none;user-select:none;display:flex;position:fixed;top:0;left:0;padding-left:5px;padding-top:3px;width:100%;height:100%;background-color:var(--primary-color);color:var(--contrast-color);transition:.15s}.list[data-v-e34fd722]{width:170px;min-width:170px;padding-top:5px;padding-left:2px;top:-3px;left:-5px;position:relative;background-color:var(--subtle-color)}.maincontent[data-v-e34fd722]{flex-grow:1;height:100vh}.topbar[data-v-e34fd722]{left:5px;position:relative}.dialogsurl[data-v-e34fd722]{top:25%;left:35%;position:absolute}.sourcetable[data-v-e34fd722]{position:relative;top:6px;height:100%;overflow-y:scroll;margin-right:4px}.progressbar[data-v-e34fd722]{position:absolute;bottom:3px;left:0;z-index:5;width:100%} diff --git a/src/main/resources/static/assets/index-CB9h-D7W.js b/src/main/resources/static/assets/index-CB9h-D7W.js deleted file mode 100644 index 64f54dd..0000000 --- a/src/main/resources/static/assets/index-CB9h-D7W.js +++ /dev/null @@ -1,26 +0,0 @@ -(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&s(i)}).observe(document,{childList:!0,subtree:!0});function n(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function s(r){if(r.ep)return;r.ep=!0;const o=n(r);fetch(r.href,o)}})();/** -* @vue/shared v3.4.21 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function Zs(e,t){const n=new Set(e.split(","));return t?s=>n.has(s.toLowerCase()):s=>n.has(s)}const Z={},Ft=[],Le=()=>{},vl=()=>!1,Hn=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),er=e=>e.startsWith("onUpdate:"),he=Object.assign,tr=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Cl=Object.prototype.hasOwnProperty,W=(e,t)=>Cl.call(e,t),k=Array.isArray,Ut=e=>hn(e)==="[object Map]",Kn=e=>hn(e)==="[object Set]",kr=e=>hn(e)==="[object Date]",M=e=>typeof e=="function",ce=e=>typeof e=="string",pt=e=>typeof e=="symbol",Y=e=>e!==null&&typeof e=="object",No=e=>(Y(e)||M(e))&&M(e.then)&&M(e.catch),Fo=Object.prototype.toString,hn=e=>Fo.call(e),El=e=>hn(e).slice(8,-1),Uo=e=>hn(e)==="[object Object]",nr=e=>ce(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,tn=Zs(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),qn=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},wl=/-(\w)/g,Ke=qn(e=>e.replace(wl,(t,n)=>n?n.toUpperCase():"")),Al=/\B([A-Z])/g,jt=qn(e=>e.replace(Al,"-$1").toLowerCase()),Wn=qn(e=>e.charAt(0).toUpperCase()+e.slice(1)),hs=qn(e=>e?`on${Wn(e)}`:""),Ot=(e,t)=>!Object.is(e,t),Rn=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},Rs=e=>{const t=parseFloat(e);return isNaN(t)?e:t},Tl=e=>{const t=ce(e)?Number(e):NaN;return isNaN(t)?e:t};let Nr;const Do=()=>Nr||(Nr=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function pn(e){if(k(e)){const t={};for(let n=0;n{if(n){const s=n.split(Rl);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function Ee(e){let t="";if(ce(e))t=e;else if(k(e))for(let n=0;nBt(n,t))}const ze=e=>ce(e)?e:e==null?"":k(e)||Y(e)&&(e.toString===Fo||!M(e.toString))?JSON.stringify(e,Mo,2):String(e),Mo=(e,t)=>t&&t.__v_isRef?Mo(e,t.value):Ut(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],o)=>(n[ps(s,o)+" =>"]=r,n),{})}:Kn(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>ps(n))}:pt(t)?ps(t):Y(t)&&!k(t)&&!Uo(t)?String(t):t,ps=(e,t="")=>{var n;return pt(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** -* @vue/reactivity v3.4.21 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let Ne;class $o{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Ne,!t&&Ne&&(this.index=(Ne.scopes||(Ne.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=Ne;try{return Ne=this,t()}finally{Ne=n}}}on(){Ne=this}off(){Ne=this.parent}stop(t){if(this._active){let n,s;for(n=0,s=this.effects.length;n=4))break}this._dirtyLevel===1&&(this._dirtyLevel=0),xt()}return this._dirtyLevel>=4}set dirty(t){this._dirtyLevel=t?4:0}run(){if(this._dirtyLevel=0,!this.active)return this.fn();let t=dt,n=At;try{return dt=!0,At=this,this._runnings++,Fr(this),this.fn()}finally{Ur(this),this._runnings--,At=n,dt=t}}stop(){var t;this.active&&(Fr(this),Ur(this),(t=this.onStop)==null||t.call(this),this.active=!1)}}function Dl(e){return e.value}function Fr(e){e._trackId++,e._depsLength=0}function Ur(e){if(e.deps.length>e._depsLength){for(let t=e._depsLength;t{const n=new Map;return n.cleanup=e,n.computed=t,n},Is=new WeakMap,Tt=Symbol(""),Ps=Symbol("");function we(e,t,n){if(dt&&At){let s=Is.get(e);s||Is.set(e,s=new Map);let r=s.get(n);r||s.set(n,r=Wo(()=>s.delete(n))),Ko(At,r)}}function Je(e,t,n,s,r,o){const i=Is.get(e);if(!i)return;let l=[];if(t==="clear")l=[...i.values()];else if(n==="length"&&k(e)){const c=Number(s);i.forEach((f,u)=>{(u==="length"||!pt(u)&&u>=c)&&l.push(f)})}else switch(n!==void 0&&l.push(i.get(n)),t){case"add":k(e)?nr(n)&&l.push(i.get("length")):(l.push(i.get(Tt)),Ut(e)&&l.push(i.get(Ps)));break;case"delete":k(e)||(l.push(i.get(Tt)),Ut(e)&&l.push(i.get(Ps)));break;case"set":Ut(e)&&l.push(i.get(Tt));break}rr();for(const c of l)c&&qo(c,4);or()}const Vl=Zs("__proto__,__v_isRef,__isVue"),Go=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(pt)),Dr=Bl();function Bl(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const s=G(this);for(let o=0,i=this.length;o{e[t]=function(...n){Rt(),rr();const s=G(this)[t].apply(this,n);return or(),xt(),s}}),e}function Ml(e){const t=G(this);return we(t,"has",e),t.hasOwnProperty(e)}class zo{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){const r=this._isReadonly,o=this._isShallow;if(n==="__v_isReactive")return!r;if(n==="__v_isReadonly")return r;if(n==="__v_isShallow")return o;if(n==="__v_raw")return s===(r?o?Zl:Qo:o?Xo:Yo).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const i=k(t);if(!r){if(i&&W(Dr,n))return Reflect.get(Dr,n,s);if(n==="hasOwnProperty")return Ml}const l=Reflect.get(t,n,s);return(pt(n)?Go.has(n):Vl(n))||(r||we(t,"get",n),o)?l:Re(l)?i&&nr(n)?l:l.value:Y(l)?r?Zo(l):zn(l):l}}class Jo extends zo{constructor(t=!1){super(!1,t)}set(t,n,s,r){let o=t[n];if(!this._isShallow){const c=ln(o);if(!ks(s)&&!ln(s)&&(o=G(o),s=G(s)),!k(t)&&Re(o)&&!Re(s))return c?!1:(o.value=s,!0)}const i=k(t)&&nr(n)?Number(n)e,Gn=e=>Reflect.getPrototypeOf(e);function vn(e,t,n=!1,s=!1){e=e.__v_raw;const r=G(e),o=G(t);n||(Ot(t,o)&&we(r,"get",t),we(r,"get",o));const{has:i}=Gn(r),l=s?ir:n?ur:ar;if(i.call(r,t))return l(e.get(t));if(i.call(r,o))return l(e.get(o));e!==r&&e.get(t)}function Cn(e,t=!1){const n=this.__v_raw,s=G(n),r=G(e);return t||(Ot(e,r)&&we(s,"has",e),we(s,"has",r)),e===r?n.has(e):n.has(e)||n.has(r)}function En(e,t=!1){return e=e.__v_raw,!t&&we(G(e),"iterate",Tt),Reflect.get(e,"size",e)}function Vr(e){e=G(e);const t=G(this);return Gn(t).has.call(t,e)||(t.add(e),Je(t,"add",e,e)),this}function Br(e,t){t=G(t);const n=G(this),{has:s,get:r}=Gn(n);let o=s.call(n,e);o||(e=G(e),o=s.call(n,e));const i=r.call(n,e);return n.set(e,t),o?Ot(t,i)&&Je(n,"set",e,t):Je(n,"add",e,t),this}function Mr(e){const t=G(this),{has:n,get:s}=Gn(t);let r=n.call(t,e);r||(e=G(e),r=n.call(t,e)),s&&s.call(t,e);const o=t.delete(e);return r&&Je(t,"delete",e,void 0),o}function $r(){const e=G(this),t=e.size!==0,n=e.clear();return t&&Je(e,"clear",void 0,void 0),n}function wn(e,t){return function(s,r){const o=this,i=o.__v_raw,l=G(i),c=t?ir:e?ur:ar;return!e&&we(l,"iterate",Tt),i.forEach((f,u)=>s.call(r,c(f),c(u),o))}}function An(e,t,n){return function(...s){const r=this.__v_raw,o=G(r),i=Ut(o),l=e==="entries"||e===Symbol.iterator&&i,c=e==="keys"&&i,f=r[e](...s),u=n?ir:t?ur:ar;return!t&&we(o,"iterate",c?Ps:Tt),{next(){const{value:d,done:g}=f.next();return g?{value:d,done:g}:{value:l?[u(d[0]),u(d[1])]:u(d),done:g}},[Symbol.iterator](){return this}}}}function tt(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function ql(){const e={get(o){return vn(this,o)},get size(){return En(this)},has:Cn,add:Vr,set:Br,delete:Mr,clear:$r,forEach:wn(!1,!1)},t={get(o){return vn(this,o,!1,!0)},get size(){return En(this)},has:Cn,add:Vr,set:Br,delete:Mr,clear:$r,forEach:wn(!1,!0)},n={get(o){return vn(this,o,!0)},get size(){return En(this,!0)},has(o){return Cn.call(this,o,!0)},add:tt("add"),set:tt("set"),delete:tt("delete"),clear:tt("clear"),forEach:wn(!0,!1)},s={get(o){return vn(this,o,!0,!0)},get size(){return En(this,!0)},has(o){return Cn.call(this,o,!0)},add:tt("add"),set:tt("set"),delete:tt("delete"),clear:tt("clear"),forEach:wn(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=An(o,!1,!1),n[o]=An(o,!0,!1),t[o]=An(o,!1,!0),s[o]=An(o,!0,!0)}),[e,n,t,s]}const[Wl,Gl,zl,Jl]=ql();function lr(e,t){const n=t?e?Jl:zl:e?Gl:Wl;return(s,r,o)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(W(n,r)&&r in s?n:s,r,o)}const Yl={get:lr(!1,!1)},Xl={get:lr(!1,!0)},Ql={get:lr(!0,!1)},Yo=new WeakMap,Xo=new WeakMap,Qo=new WeakMap,Zl=new WeakMap;function ec(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function tc(e){return e.__v_skip||!Object.isExtensible(e)?0:ec(El(e))}function zn(e){return ln(e)?e:cr(e,!1,jl,Yl,Yo)}function nc(e){return cr(e,!1,Kl,Xl,Xo)}function Zo(e){return cr(e,!0,Hl,Ql,Qo)}function cr(e,t,n,s,r){if(!Y(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const o=r.get(e);if(o)return o;const i=tc(e);if(i===0)return e;const l=new Proxy(e,i===2?s:n);return r.set(e,l),l}function Dt(e){return ln(e)?Dt(e.__v_raw):!!(e&&e.__v_isReactive)}function ln(e){return!!(e&&e.__v_isReadonly)}function ks(e){return!!(e&&e.__v_isShallow)}function ei(e){return Dt(e)||ln(e)}function G(e){const t=e&&e.__v_raw;return t?G(t):e}function ti(e){return Object.isExtensible(e)&&Dn(e,"__v_skip",!0),e}const ar=e=>Y(e)?zn(e):e,ur=e=>Y(e)?Zo(e):e;class ni{constructor(t,n,s,r){this.getter=t,this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this.effect=new sr(()=>t(this._value),()=>ms(this,this.effect._dirtyLevel===2?2:3)),this.effect.computed=this,this.effect.active=this._cacheable=!r,this.__v_isReadonly=s}get value(){const t=G(this);return(!t._cacheable||t.effect.dirty)&&Ot(t._value,t._value=t.effect.run())&&ms(t,4),rc(t),t.effect._dirtyLevel>=2&&ms(t,2),t._value}set value(t){this._setter(t)}get _dirty(){return this.effect.dirty}set _dirty(t){this.effect.dirty=t}}function sc(e,t,n=!1){let s,r;const o=M(e);return o?(s=e,r=Le):(s=e.get,r=e.set),new ni(s,r,o||!r,n)}function rc(e){var t;dt&&At&&(e=G(e),Ko(At,(t=e.dep)!=null?t:e.dep=Wo(()=>e.dep=void 0,e instanceof ni?e:void 0)))}function ms(e,t=4,n){e=G(e);const s=e.dep;s&&qo(s,t)}function Re(e){return!!(e&&e.__v_isRef===!0)}function oc(e){return Re(e)?e.value:e}const ic={get:(e,t,n)=>oc(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return Re(r)&&!Re(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function si(e){return Dt(e)?e:new Proxy(e,ic)}/** -* @vue/runtime-core v3.4.21 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function ht(e,t,n,s){try{return s?e(...s):e()}catch(r){Jn(r,t,n)}}function Ie(e,t,n,s){if(M(e)){const o=ht(e,t,n,s);return o&&No(o)&&o.catch(i=>{Jn(i,t,n)}),o}const r=[];for(let o=0;o>>1,r=be[s],o=an(r);oje&&be.splice(t,1)}function fc(e){k(e)?Vt.push(...e):(!lt||!lt.includes(e,e.allowRecurse?Ct+1:Ct))&&Vt.push(e),oi()}function jr(e,t,n=cn?je+1:0){for(;nan(n)-an(s));if(Vt.length=0,lt){lt.push(...t);return}for(lt=t,Ct=0;Cte.id==null?1/0:e.id,dc=(e,t)=>{const n=an(e)-an(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function li(e){Ns=!1,cn=!0,be.sort(dc);try{for(je=0;jece(C)?C.trim():C)),d&&(r=n.map(Rs))}let l,c=s[l=hs(t)]||s[l=hs(Ke(t))];!c&&o&&(c=s[l=hs(jt(t))]),c&&Ie(c,e,6,r);const f=s[l+"Once"];if(f){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Ie(f,e,6,r)}}function ci(e,t,n=!1){const s=t.emitsCache,r=s.get(e);if(r!==void 0)return r;const o=e.emits;let i={},l=!1;if(!M(e)){const c=f=>{const u=ci(f,t,!0);u&&(l=!0,he(i,u))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!o&&!l?(Y(e)&&s.set(e,null),null):(k(o)?o.forEach(c=>i[c]=null):he(i,o),Y(e)&&s.set(e,i),i)}function Yn(e,t){return!e||!Hn(t)?!1:(t=t.slice(2).replace(/Once$/,""),W(e,t[0].toLowerCase()+t.slice(1))||W(e,jt(t))||W(e,t))}let ve=null,Xn=null;function Vn(e){const t=ve;return ve=e,Xn=e&&e.type.__scopeId||null,t}function Ht(e){Xn=e}function Kt(){Xn=null}function ai(e,t=ve,n){if(!t||e._n)return e;const s=(...r)=>{s._d&&eo(-1);const o=Vn(t);let i;try{i=e(...r)}finally{Vn(o),s._d&&eo(1)}return i};return s._n=!0,s._c=!0,s._d=!0,s}function gs(e){const{type:t,vnode:n,proxy:s,withProxy:r,props:o,propsOptions:[i],slots:l,attrs:c,emit:f,render:u,renderCache:d,data:g,setupState:C,ctx:A,inheritAttrs:E}=e;let D,$;const ee=Vn(e);try{if(n.shapeFlag&4){const z=r||s,re=z;D=$e(u.call(re,z,d,o,C,g,A)),$=c}else{const z=t;D=$e(z.length>1?z(o,{attrs:c,slots:l,emit:f}):z(o,null)),$=t.props?c:pc(c)}}catch(z){on.length=0,Jn(z,e,1),D=le(Ue)}let j=D;if($&&E!==!1){const z=Object.keys($),{shapeFlag:re}=j;z.length&&re&7&&(i&&z.some(er)&&($=mc($,i)),j=mt(j,$))}return n.dirs&&(j=mt(j),j.dirs=j.dirs?j.dirs.concat(n.dirs):n.dirs),n.transition&&(j.transition=n.transition),D=j,Vn(ee),D}const pc=e=>{let t;for(const n in e)(n==="class"||n==="style"||Hn(n))&&((t||(t={}))[n]=e[n]);return t},mc=(e,t)=>{const n={};for(const s in e)(!er(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function gc(e,t,n){const{props:s,children:r,component:o}=e,{props:i,children:l,patchFlag:c}=t,f=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return s?Hr(s,i,f):!!i;if(c&8){const u=t.dynamicProps;for(let d=0;de.__isSuspense;function vc(e,t){t&&t.pendingBranch?k(e)?t.effects.push(...e):t.effects.push(e):fc(e)}const Cc=Symbol.for("v-scx"),Ec=()=>Ln(Cc),Tn={};function nn(e,t,n){return fi(e,t,n)}function fi(e,t,{immediate:n,deep:s,flush:r,once:o,onTrack:i,onTrigger:l}=Z){if(t&&o){const H=t;t=(...ye)=>{H(...ye),re()}}const c=me,f=H=>s===!0?H:wt(H,s===!1?1:void 0);let u,d=!1,g=!1;if(Re(e)?(u=()=>e.value,d=ks(e)):Dt(e)?(u=()=>f(e),d=!0):k(e)?(g=!0,d=e.some(H=>Dt(H)||ks(H)),u=()=>e.map(H=>{if(Re(H))return H.value;if(Dt(H))return f(H);if(M(H))return ht(H,c,2)})):M(e)?t?u=()=>ht(e,c,2):u=()=>(C&&C(),Ie(e,c,3,[A])):u=Le,t&&s){const H=u;u=()=>wt(H())}let C,A=H=>{C=j.onStop=()=>{ht(H,c,4),C=j.onStop=void 0}},E;if(ns)if(A=Le,t?n&&Ie(t,c,3,[u(),g?[]:void 0,A]):u(),r==="sync"){const H=Ec();E=H.__watcherHandles||(H.__watcherHandles=[])}else return Le;let D=g?new Array(e.length).fill(Tn):Tn;const $=()=>{if(!(!j.active||!j.dirty))if(t){const H=j.run();(s||d||(g?H.some((ye,V)=>Ot(ye,D[V])):Ot(H,D)))&&(C&&C(),Ie(t,c,3,[H,D===Tn?void 0:g&&D[0]===Tn?[]:D,A]),D=H)}else j.run()};$.allowRecurse=!!t;let ee;r==="sync"?ee=$:r==="post"?ee=()=>Ce($,c&&c.suspense):($.pre=!0,c&&($.id=c.uid),ee=()=>dr($));const j=new sr(u,Le,ee),z=Ul(),re=()=>{j.stop(),z&&tr(z.effects,j)};return t?n?$():D=j.run():r==="post"?Ce(j.run.bind(j),c&&c.suspense):j.run(),E&&E.push(re),re}function wc(e,t,n){const s=this.proxy,r=ce(e)?e.includes(".")?di(s,e):()=>s[e]:e.bind(s,s);let o;M(t)?o=t:(o=t.handler,n=t);const i=mn(this),l=fi(r,o.bind(s),n);return i(),l}function di(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;r0){if(n>=t)return e;n++}if(s=s||new Set,s.has(e))return e;if(s.add(e),Re(e))wt(e.value,t,n,s);else if(k(e))for(let r=0;r{wt(r,t,n,s)});else if(Uo(e))for(const r in e)wt(e[r],t,n,s);return e}function ie(e,t){if(ve===null)return e;const n=ss(ve)||ve.proxy,s=e.dirs||(e.dirs=[]);for(let r=0;r{e.isMounted=!0}),bi(()=>{e.isUnmounting=!0}),e}const xe=[Function,Array],hi={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:xe,onEnter:xe,onAfterEnter:xe,onEnterCancelled:xe,onBeforeLeave:xe,onLeave:xe,onAfterLeave:xe,onLeaveCancelled:xe,onBeforeAppear:xe,onAppear:xe,onAfterAppear:xe,onAppearCancelled:xe},Tc={name:"BaseTransition",props:hi,setup(e,{slots:t}){const n=fa(),s=Ac();return()=>{const r=t.default&&mi(t.default(),!0);if(!r||!r.length)return;let o=r[0];if(r.length>1){for(const g of r)if(g.type!==Ue){o=g;break}}const i=G(e),{mode:l}=i;if(s.isLeaving)return _s(o);const c=qr(o);if(!c)return _s(o);const f=Fs(c,i,s,n);Us(c,f);const u=n.subTree,d=u&&qr(u);if(d&&d.type!==Ue&&!Et(c,d)){const g=Fs(d,i,s,n);if(Us(d,g),l==="out-in")return s.isLeaving=!0,g.afterLeave=()=>{s.isLeaving=!1,n.update.active!==!1&&(n.effect.dirty=!0,n.update())},_s(o);l==="in-out"&&c.type!==Ue&&(g.delayLeave=(C,A,E)=>{const D=pi(s,d);D[String(d.key)]=d,C[ct]=()=>{A(),C[ct]=void 0,delete f.delayedLeave},f.delayedLeave=E})}return o}}},Oc=Tc;function pi(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function Fs(e,t,n,s){const{appear:r,mode:o,persisted:i=!1,onBeforeEnter:l,onEnter:c,onAfterEnter:f,onEnterCancelled:u,onBeforeLeave:d,onLeave:g,onAfterLeave:C,onLeaveCancelled:A,onBeforeAppear:E,onAppear:D,onAfterAppear:$,onAppearCancelled:ee}=t,j=String(e.key),z=pi(n,e),re=(V,oe)=>{V&&Ie(V,s,9,oe)},H=(V,oe)=>{const Q=oe[1];re(V,oe),k(V)?V.every(ge=>ge.length<=1)&&Q():V.length<=1&&Q()},ye={mode:o,persisted:i,beforeEnter(V){let oe=l;if(!n.isMounted)if(r)oe=E||l;else return;V[ct]&&V[ct](!0);const Q=z[j];Q&&Et(e,Q)&&Q.el[ct]&&Q.el[ct](),re(oe,[V])},enter(V){let oe=c,Q=f,ge=u;if(!n.isMounted)if(r)oe=D||c,Q=$||f,ge=ee||u;else return;let I=!1;const ne=V[On]=Te=>{I||(I=!0,Te?re(ge,[V]):re(Q,[V]),ye.delayedLeave&&ye.delayedLeave(),V[On]=void 0)};oe?H(oe,[V,ne]):ne()},leave(V,oe){const Q=String(e.key);if(V[On]&&V[On](!0),n.isUnmounting)return oe();re(d,[V]);let ge=!1;const I=V[ct]=ne=>{ge||(ge=!0,oe(),ne?re(A,[V]):re(C,[V]),V[ct]=void 0,z[Q]===e&&delete z[Q])};z[Q]=e,g?H(g,[V,I]):I()},clone(V){return Fs(V,t,n,s)}};return ye}function _s(e){if(Qn(e))return e=mt(e),e.children=null,e}function qr(e){return Qn(e)?e.children?e.children[0]:void 0:e}function Us(e,t){e.shapeFlag&6&&e.component?Us(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function mi(e,t=!1,n){let s=[],r=0;for(let o=0;o1)for(let o=0;o!!e.type.__asyncLoader,Qn=e=>e.type.__isKeepAlive;function Rc(e,t){gi(e,"a",t)}function xc(e,t){gi(e,"da",t)}function gi(e,t,n=me){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(Zn(t,s,n),n){let r=n.parent;for(;r&&r.parent;)Qn(r.parent.vnode)&&Lc(s,t,n,r),r=r.parent}}function Lc(e,t,n,s){const r=Zn(t,e,s,!0);yi(()=>{tr(s[t],r)},n)}function Zn(e,t,n=me,s=!1){if(n){const r=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...i)=>{if(n.isUnmounted)return;Rt();const l=mn(n),c=Ie(t,n,e,i);return l(),xt(),c});return s?r.unshift(o):r.push(o),o}}const Qe=e=>(t,n=me)=>(!ns||e==="sp")&&Zn(e,(...s)=>t(...s),n),Ic=Qe("bm"),_i=Qe("m"),Pc=Qe("bu"),kc=Qe("u"),bi=Qe("bum"),yi=Qe("um"),Nc=Qe("sp"),Fc=Qe("rtg"),Uc=Qe("rtc");function Dc(e,t=me){Zn("ec",e,t)}function Ds(e,t,n,s){let r;const o=n&&n[s];if(k(e)||ce(e)){r=new Array(e.length);for(let i=0,l=e.length;it(i,l,void 0,o&&o[l]));else{const i=Object.keys(e);r=new Array(i.length);for(let l=0,c=i.length;le?Ii(e)?ss(e)||e.proxy:Vs(e.parent):null,sn=he(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Vs(e.parent),$root:e=>Vs(e.root),$emit:e=>e.emit,$options:e=>hr(e),$forceUpdate:e=>e.f||(e.f=()=>{e.effect.dirty=!0,dr(e.update)}),$nextTick:e=>e.n||(e.n=cc.bind(e.proxy)),$watch:e=>wc.bind(e)}),bs=(e,t)=>e!==Z&&!e.__isScriptSetup&&W(e,t),Vc={get({_:e},t){const{ctx:n,setupState:s,data:r,props:o,accessCache:i,type:l,appContext:c}=e;let f;if(t[0]!=="$"){const C=i[t];if(C!==void 0)switch(C){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return o[t]}else{if(bs(s,t))return i[t]=1,s[t];if(r!==Z&&W(r,t))return i[t]=2,r[t];if((f=e.propsOptions[0])&&W(f,t))return i[t]=3,o[t];if(n!==Z&&W(n,t))return i[t]=4,n[t];Bs&&(i[t]=0)}}const u=sn[t];let d,g;if(u)return t==="$attrs"&&we(e,"get",t),u(e);if((d=l.__cssModules)&&(d=d[t]))return d;if(n!==Z&&W(n,t))return i[t]=4,n[t];if(g=c.config.globalProperties,W(g,t))return g[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:o}=e;return bs(r,t)?(r[t]=n,!0):s!==Z&&W(s,t)?(s[t]=n,!0):W(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,propsOptions:o}},i){let l;return!!n[i]||e!==Z&&W(e,i)||bs(t,i)||(l=o[0])&&W(l,i)||W(s,i)||W(sn,i)||W(r.config.globalProperties,i)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:W(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function Wr(e){return k(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Bs=!0;function Bc(e){const t=hr(e),n=e.proxy,s=e.ctx;Bs=!1,t.beforeCreate&&Gr(t.beforeCreate,e,"bc");const{data:r,computed:o,methods:i,watch:l,provide:c,inject:f,created:u,beforeMount:d,mounted:g,beforeUpdate:C,updated:A,activated:E,deactivated:D,beforeDestroy:$,beforeUnmount:ee,destroyed:j,unmounted:z,render:re,renderTracked:H,renderTriggered:ye,errorCaptured:V,serverPrefetch:oe,expose:Q,inheritAttrs:ge,components:I,directives:ne,filters:Te}=t;if(f&&Mc(f,s,null),i)for(const se in i){const X=i[se];M(X)&&(s[se]=X.bind(n))}if(r){const se=r.call(n,n);Y(se)&&(e.data=zn(se))}if(Bs=!0,o)for(const se in o){const X=o[se],gt=M(X)?X.bind(n,n):M(X.get)?X.get.bind(n,n):Le,yn=!M(X)&&M(X.set)?X.set.bind(n):Le,_t=ki({get:gt,set:yn});Object.defineProperty(s,se,{enumerable:!0,configurable:!0,get:()=>_t.value,set:Ve=>_t.value=Ve})}if(l)for(const se in l)Si(l[se],s,n,se);if(c){const se=M(c)?c.call(n):c;Reflect.ownKeys(se).forEach(X=>{Wc(X,se[X])})}u&&Gr(u,e,"c");function fe(se,X){k(X)?X.forEach(gt=>se(gt.bind(n))):X&&se(X.bind(n))}if(fe(Ic,d),fe(_i,g),fe(Pc,C),fe(kc,A),fe(Rc,E),fe(xc,D),fe(Dc,V),fe(Uc,H),fe(Fc,ye),fe(bi,ee),fe(yi,z),fe(Nc,oe),k(Q))if(Q.length){const se=e.exposed||(e.exposed={});Q.forEach(X=>{Object.defineProperty(se,X,{get:()=>n[X],set:gt=>n[X]=gt})})}else e.exposed||(e.exposed={});re&&e.render===Le&&(e.render=re),ge!=null&&(e.inheritAttrs=ge),I&&(e.components=I),ne&&(e.directives=ne)}function Mc(e,t,n=Le){k(e)&&(e=Ms(e));for(const s in e){const r=e[s];let o;Y(r)?"default"in r?o=Ln(r.from||s,r.default,!0):o=Ln(r.from||s):o=Ln(r),Re(o)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>o.value,set:i=>o.value=i}):t[s]=o}}function Gr(e,t,n){Ie(k(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function Si(e,t,n,s){const r=s.includes(".")?di(n,s):()=>n[s];if(ce(e)){const o=t[e];M(o)&&nn(r,o)}else if(M(e))nn(r,e.bind(n));else if(Y(e))if(k(e))e.forEach(o=>Si(o,t,n,s));else{const o=M(e.handler)?e.handler.bind(n):t[e.handler];M(o)&&nn(r,o,e)}}function hr(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:o,config:{optionMergeStrategies:i}}=e.appContext,l=o.get(t);let c;return l?c=l:!r.length&&!n&&!s?c=t:(c={},r.length&&r.forEach(f=>Bn(c,f,i,!0)),Bn(c,t,i)),Y(t)&&o.set(t,c),c}function Bn(e,t,n,s=!1){const{mixins:r,extends:o}=t;o&&Bn(e,o,n,!0),r&&r.forEach(i=>Bn(e,i,n,!0));for(const i in t)if(!(s&&i==="expose")){const l=$c[i]||n&&n[i];e[i]=l?l(e[i],t[i]):t[i]}return e}const $c={data:zr,props:Jr,emits:Jr,methods:Zt,computed:Zt,beforeCreate:Se,created:Se,beforeMount:Se,mounted:Se,beforeUpdate:Se,updated:Se,beforeDestroy:Se,beforeUnmount:Se,destroyed:Se,unmounted:Se,activated:Se,deactivated:Se,errorCaptured:Se,serverPrefetch:Se,components:Zt,directives:Zt,watch:Hc,provide:zr,inject:jc};function zr(e,t){return t?e?function(){return he(M(e)?e.call(this,this):e,M(t)?t.call(this,this):t)}:t:e}function jc(e,t){return Zt(Ms(e),Ms(t))}function Ms(e){if(k(e)){const t={};for(let n=0;n1)return n&&M(t)?t.call(s&&s.proxy):t}}function Gc(e,t,n,s=!1){const r={},o={};Dn(o,ts,1),e.propsDefaults=Object.create(null),Ci(e,t,r,o);for(const i in e.propsOptions[0])i in r||(r[i]=void 0);n?e.props=s?r:nc(r):e.type.props?e.props=r:e.props=o,e.attrs=o}function zc(e,t,n,s){const{props:r,attrs:o,vnode:{patchFlag:i}}=e,l=G(r),[c]=e.propsOptions;let f=!1;if((s||i>0)&&!(i&16)){if(i&8){const u=e.vnode.dynamicProps;for(let d=0;d{c=!0;const[g,C]=Ei(d,t,!0);he(i,g),C&&l.push(...C)};!n&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}if(!o&&!c)return Y(e)&&s.set(e,Ft),Ft;if(k(o))for(let u=0;u-1,C[1]=E<0||A-1||W(C,"default"))&&l.push(d)}}}const f=[i,l];return Y(e)&&s.set(e,f),f}function Yr(e){return e[0]!=="$"&&!tn(e)}function Xr(e){return e===null?"null":typeof e=="function"?e.name||"":typeof e=="object"&&e.constructor&&e.constructor.name||""}function Qr(e,t){return Xr(e)===Xr(t)}function Zr(e,t){return k(t)?t.findIndex(n=>Qr(n,e)):M(t)&&Qr(t,e)?0:-1}const wi=e=>e[0]==="_"||e==="$stable",pr=e=>k(e)?e.map($e):[$e(e)],Jc=(e,t,n)=>{if(t._n)return t;const s=ai((...r)=>pr(t(...r)),n);return s._c=!1,s},Ai=(e,t,n)=>{const s=e._ctx;for(const r in e){if(wi(r))continue;const o=e[r];if(M(o))t[r]=Jc(r,o,s);else if(o!=null){const i=pr(o);t[r]=()=>i}}},Ti=(e,t)=>{const n=pr(t);e.slots.default=()=>n},Yc=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=G(t),Dn(t,"_",n)):Ai(t,e.slots={})}else e.slots={},t&&Ti(e,t);Dn(e.slots,ts,1)},Xc=(e,t,n)=>{const{vnode:s,slots:r}=e;let o=!0,i=Z;if(s.shapeFlag&32){const l=t._;l?n&&l===1?o=!1:(he(r,t),!n&&l===1&&delete r._):(o=!t.$stable,Ai(t,r)),i=t}else t&&(Ti(e,t),i={default:1});if(o)for(const l in r)!wi(l)&&i[l]==null&&delete r[l]};function js(e,t,n,s,r=!1){if(k(e)){e.forEach((g,C)=>js(g,t&&(k(t)?t[C]:t),n,s,r));return}if(xn(s)&&!r)return;const o=s.shapeFlag&4?ss(s.component)||s.component.proxy:s.el,i=r?null:o,{i:l,r:c}=e,f=t&&t.r,u=l.refs===Z?l.refs={}:l.refs,d=l.setupState;if(f!=null&&f!==c&&(ce(f)?(u[f]=null,W(d,f)&&(d[f]=null)):Re(f)&&(f.value=null)),M(c))ht(c,l,12,[i,u]);else{const g=ce(c),C=Re(c);if(g||C){const A=()=>{if(e.f){const E=g?W(d,c)?d[c]:u[c]:c.value;r?k(E)&&tr(E,o):k(E)?E.includes(o)||E.push(o):g?(u[c]=[o],W(d,c)&&(d[c]=u[c])):(c.value=[o],e.k&&(u[e.k]=c.value))}else g?(u[c]=i,W(d,c)&&(d[c]=i)):C&&(c.value=i,e.k&&(u[e.k]=i))};i?(A.id=-1,Ce(A,n)):A()}}}const Ce=vc;function Qc(e){return Zc(e)}function Zc(e,t){const n=Do();n.__VUE__=!0;const{insert:s,remove:r,patchProp:o,createElement:i,createText:l,createComment:c,setText:f,setElementText:u,parentNode:d,nextSibling:g,setScopeId:C=Le,insertStaticContent:A}=e,E=(a,h,m,b=null,y=null,w=null,O=void 0,v=null,T=!!h.dynamicChildren)=>{if(a===h)return;a&&!Et(a,h)&&(b=Sn(a),Ve(a,y,w,!0),a=null),h.patchFlag===-2&&(T=!1,h.dynamicChildren=null);const{type:S,ref:R,shapeFlag:N}=h;switch(S){case es:D(a,h,m,b);break;case Ue:$(a,h,m,b);break;case In:a==null&&ee(h,m,b,O);break;case _e:I(a,h,m,b,y,w,O,v,T);break;default:N&1?re(a,h,m,b,y,w,O,v,T):N&6?ne(a,h,m,b,y,w,O,v,T):(N&64||N&128)&&S.process(a,h,m,b,y,w,O,v,T,It)}R!=null&&y&&js(R,a&&a.ref,w,h||a,!h)},D=(a,h,m,b)=>{if(a==null)s(h.el=l(h.children),m,b);else{const y=h.el=a.el;h.children!==a.children&&f(y,h.children)}},$=(a,h,m,b)=>{a==null?s(h.el=c(h.children||""),m,b):h.el=a.el},ee=(a,h,m,b)=>{[a.el,a.anchor]=A(a.children,h,m,b,a.el,a.anchor)},j=({el:a,anchor:h},m,b)=>{let y;for(;a&&a!==h;)y=g(a),s(a,m,b),a=y;s(h,m,b)},z=({el:a,anchor:h})=>{let m;for(;a&&a!==h;)m=g(a),r(a),a=m;r(h)},re=(a,h,m,b,y,w,O,v,T)=>{h.type==="svg"?O="svg":h.type==="math"&&(O="mathml"),a==null?H(h,m,b,y,w,O,v,T):oe(a,h,y,w,O,v,T)},H=(a,h,m,b,y,w,O,v)=>{let T,S;const{props:R,shapeFlag:N,transition:P,dirs:F}=a;if(T=a.el=i(a.type,w,R&&R.is,R),N&8?u(T,a.children):N&16&&V(a.children,T,null,b,y,ys(a,w),O,v),F&&bt(a,null,b,"created"),ye(T,a,a.scopeId,O,b),R){for(const J in R)J!=="value"&&!tn(J)&&o(T,J,null,R[J],w,a.children,b,y,We);"value"in R&&o(T,"value",null,R.value,w),(S=R.onVnodeBeforeMount)&&Me(S,b,a)}F&&bt(a,null,b,"beforeMount");const K=ea(y,P);K&&P.beforeEnter(T),s(T,h,m),((S=R&&R.onVnodeMounted)||K||F)&&Ce(()=>{S&&Me(S,b,a),K&&P.enter(T),F&&bt(a,null,b,"mounted")},y)},ye=(a,h,m,b,y)=>{if(m&&C(a,m),b)for(let w=0;w{for(let S=T;S{const v=h.el=a.el;let{patchFlag:T,dynamicChildren:S,dirs:R}=h;T|=a.patchFlag&16;const N=a.props||Z,P=h.props||Z;let F;if(m&&yt(m,!1),(F=P.onVnodeBeforeUpdate)&&Me(F,m,h,a),R&&bt(h,a,m,"beforeUpdate"),m&&yt(m,!0),S?Q(a.dynamicChildren,S,v,m,b,ys(h,y),w):O||X(a,h,v,null,m,b,ys(h,y),w,!1),T>0){if(T&16)ge(v,h,N,P,m,b,y);else if(T&2&&N.class!==P.class&&o(v,"class",null,P.class,y),T&4&&o(v,"style",N.style,P.style,y),T&8){const K=h.dynamicProps;for(let J=0;J{F&&Me(F,m,h,a),R&&bt(h,a,m,"updated")},b)},Q=(a,h,m,b,y,w,O)=>{for(let v=0;v{if(m!==b){if(m!==Z)for(const v in m)!tn(v)&&!(v in b)&&o(a,v,m[v],null,O,h.children,y,w,We);for(const v in b){if(tn(v))continue;const T=b[v],S=m[v];T!==S&&v!=="value"&&o(a,v,S,T,O,h.children,y,w,We)}"value"in b&&o(a,"value",m.value,b.value,O)}},I=(a,h,m,b,y,w,O,v,T)=>{const S=h.el=a?a.el:l(""),R=h.anchor=a?a.anchor:l("");let{patchFlag:N,dynamicChildren:P,slotScopeIds:F}=h;F&&(v=v?v.concat(F):F),a==null?(s(S,m,b),s(R,m,b),V(h.children||[],m,R,y,w,O,v,T)):N>0&&N&64&&P&&a.dynamicChildren?(Q(a.dynamicChildren,P,m,y,w,O,v),(h.key!=null||y&&h===y.subTree)&&Oi(a,h,!0)):X(a,h,m,R,y,w,O,v,T)},ne=(a,h,m,b,y,w,O,v,T)=>{h.slotScopeIds=v,a==null?h.shapeFlag&512?y.ctx.activate(h,m,b,O,T):Te(h,m,b,y,w,O,T):Jt(a,h,T)},Te=(a,h,m,b,y,w,O)=>{const v=a.component=ua(a,b,y);if(Qn(a)&&(v.ctx.renderer=It),da(v),v.asyncDep){if(y&&y.registerDep(v,fe),!a.el){const T=v.subTree=le(Ue);$(null,T,h,m)}}else fe(v,a,h,m,y,w,O)},Jt=(a,h,m)=>{const b=h.component=a.component;if(gc(a,h,m))if(b.asyncDep&&!b.asyncResolved){se(b,h,m);return}else b.next=h,uc(b.update),b.effect.dirty=!0,b.update();else h.el=a.el,b.vnode=h},fe=(a,h,m,b,y,w,O)=>{const v=()=>{if(a.isMounted){let{next:R,bu:N,u:P,parent:F,vnode:K}=a;{const Pt=Ri(a);if(Pt){R&&(R.el=K.el,se(a,R,O)),Pt.asyncDep.then(()=>{a.isUnmounted||v()});return}}let J=R,te;yt(a,!1),R?(R.el=K.el,se(a,R,O)):R=K,N&&Rn(N),(te=R.props&&R.props.onVnodeBeforeUpdate)&&Me(te,F,R,K),yt(a,!0);const de=gs(a),ke=a.subTree;a.subTree=de,E(ke,de,d(ke.el),Sn(ke),a,y,w),R.el=de.el,J===null&&_c(a,de.el),P&&Ce(P,y),(te=R.props&&R.props.onVnodeUpdated)&&Ce(()=>Me(te,F,R,K),y)}else{let R;const{el:N,props:P}=h,{bm:F,m:K,parent:J}=a,te=xn(h);if(yt(a,!1),F&&Rn(F),!te&&(R=P&&P.onVnodeBeforeMount)&&Me(R,J,h),yt(a,!0),N&&ds){const de=()=>{a.subTree=gs(a),ds(N,a.subTree,a,y,null)};te?h.type.__asyncLoader().then(()=>!a.isUnmounted&&de()):de()}else{const de=a.subTree=gs(a);E(null,de,m,b,a,y,w),h.el=de.el}if(K&&Ce(K,y),!te&&(R=P&&P.onVnodeMounted)){const de=h;Ce(()=>Me(R,J,de),y)}(h.shapeFlag&256||J&&xn(J.vnode)&&J.vnode.shapeFlag&256)&&a.a&&Ce(a.a,y),a.isMounted=!0,h=m=b=null}},T=a.effect=new sr(v,Le,()=>dr(S),a.scope),S=a.update=()=>{T.dirty&&T.run()};S.id=a.uid,yt(a,!0),S()},se=(a,h,m)=>{h.component=a;const b=a.vnode.props;a.vnode=h,a.next=null,zc(a,h.props,b,m),Xc(a,h.children,m),Rt(),jr(a),xt()},X=(a,h,m,b,y,w,O,v,T=!1)=>{const S=a&&a.children,R=a?a.shapeFlag:0,N=h.children,{patchFlag:P,shapeFlag:F}=h;if(P>0){if(P&128){yn(S,N,m,b,y,w,O,v,T);return}else if(P&256){gt(S,N,m,b,y,w,O,v,T);return}}F&8?(R&16&&We(S,y,w),N!==S&&u(m,N)):R&16?F&16?yn(S,N,m,b,y,w,O,v,T):We(S,y,w,!0):(R&8&&u(m,""),F&16&&V(N,m,b,y,w,O,v,T))},gt=(a,h,m,b,y,w,O,v,T)=>{a=a||Ft,h=h||Ft;const S=a.length,R=h.length,N=Math.min(S,R);let P;for(P=0;PR?We(a,y,w,!0,!1,N):V(h,m,b,y,w,O,v,T,N)},yn=(a,h,m,b,y,w,O,v,T)=>{let S=0;const R=h.length;let N=a.length-1,P=R-1;for(;S<=N&&S<=P;){const F=a[S],K=h[S]=T?at(h[S]):$e(h[S]);if(Et(F,K))E(F,K,m,null,y,w,O,v,T);else break;S++}for(;S<=N&&S<=P;){const F=a[N],K=h[P]=T?at(h[P]):$e(h[P]);if(Et(F,K))E(F,K,m,null,y,w,O,v,T);else break;N--,P--}if(S>N){if(S<=P){const F=P+1,K=FP)for(;S<=N;)Ve(a[S],y,w,!0),S++;else{const F=S,K=S,J=new Map;for(S=K;S<=P;S++){const Oe=h[S]=T?at(h[S]):$e(h[S]);Oe.key!=null&&J.set(Oe.key,S)}let te,de=0;const ke=P-K+1;let Pt=!1,Lr=0;const Yt=new Array(ke);for(S=0;S=ke){Ve(Oe,y,w,!0);continue}let Be;if(Oe.key!=null)Be=J.get(Oe.key);else for(te=K;te<=P;te++)if(Yt[te-K]===0&&Et(Oe,h[te])){Be=te;break}Be===void 0?Ve(Oe,y,w,!0):(Yt[Be-K]=S+1,Be>=Lr?Lr=Be:Pt=!0,E(Oe,h[Be],m,null,y,w,O,v,T),de++)}const Ir=Pt?ta(Yt):Ft;for(te=Ir.length-1,S=ke-1;S>=0;S--){const Oe=K+S,Be=h[Oe],Pr=Oe+1{const{el:w,type:O,transition:v,children:T,shapeFlag:S}=a;if(S&6){_t(a.component.subTree,h,m,b);return}if(S&128){a.suspense.move(h,m,b);return}if(S&64){O.move(a,h,m,It);return}if(O===_e){s(w,h,m);for(let N=0;Nv.enter(w),y);else{const{leave:N,delayLeave:P,afterLeave:F}=v,K=()=>s(w,h,m),J=()=>{N(w,()=>{K(),F&&F()})};P?P(w,K,J):J()}else s(w,h,m)},Ve=(a,h,m,b=!1,y=!1)=>{const{type:w,props:O,ref:v,children:T,dynamicChildren:S,shapeFlag:R,patchFlag:N,dirs:P}=a;if(v!=null&&js(v,null,m,a,!0),R&256){h.ctx.deactivate(a);return}const F=R&1&&P,K=!xn(a);let J;if(K&&(J=O&&O.onVnodeBeforeUnmount)&&Me(J,h,a),R&6)Sl(a.component,m,b);else{if(R&128){a.suspense.unmount(m,b);return}F&&bt(a,null,h,"beforeUnmount"),R&64?a.type.remove(a,h,m,y,It,b):S&&(w!==_e||N>0&&N&64)?We(S,h,m,!1,!0):(w===_e&&N&384||!y&&R&16)&&We(T,h,m),b&&Rr(a)}(K&&(J=O&&O.onVnodeUnmounted)||F)&&Ce(()=>{J&&Me(J,h,a),F&&bt(a,null,h,"unmounted")},m)},Rr=a=>{const{type:h,el:m,anchor:b,transition:y}=a;if(h===_e){yl(m,b);return}if(h===In){z(a);return}const w=()=>{r(m),y&&!y.persisted&&y.afterLeave&&y.afterLeave()};if(a.shapeFlag&1&&y&&!y.persisted){const{leave:O,delayLeave:v}=y,T=()=>O(m,w);v?v(a.el,w,T):T()}else w()},yl=(a,h)=>{let m;for(;a!==h;)m=g(a),r(a),a=m;r(h)},Sl=(a,h,m)=>{const{bum:b,scope:y,update:w,subTree:O,um:v}=a;b&&Rn(b),y.stop(),w&&(w.active=!1,Ve(O,a,h,m)),v&&Ce(v,h),Ce(()=>{a.isUnmounted=!0},h),h&&h.pendingBranch&&!h.isUnmounted&&a.asyncDep&&!a.asyncResolved&&a.suspenseId===h.pendingId&&(h.deps--,h.deps===0&&h.resolve())},We=(a,h,m,b=!1,y=!1,w=0)=>{for(let O=w;Oa.shapeFlag&6?Sn(a.component.subTree):a.shapeFlag&128?a.suspense.next():g(a.anchor||a.el);let us=!1;const xr=(a,h,m)=>{a==null?h._vnode&&Ve(h._vnode,null,null,!0):E(h._vnode||null,a,h,null,null,null,m),us||(us=!0,jr(),ii(),us=!1),h._vnode=a},It={p:E,um:Ve,m:_t,r:Rr,mt:Te,mc:V,pc:X,pbc:Q,n:Sn,o:e};let fs,ds;return t&&([fs,ds]=t(It)),{render:xr,hydrate:fs,createApp:qc(xr,fs)}}function ys({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function yt({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function ea(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Oi(e,t,n=!1){const s=e.children,r=t.children;if(k(s)&&k(r))for(let o=0;o>1,e[n[l]]0&&(t[s]=n[o-1]),n[o]=s)}}for(o=n.length,i=n[o-1];o-- >0;)n[o]=i,i=t[i];return n}function Ri(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:Ri(t)}const na=e=>e.__isTeleport,_e=Symbol.for("v-fgt"),es=Symbol.for("v-txt"),Ue=Symbol.for("v-cmt"),In=Symbol.for("v-stc"),on=[];let Fe=null;function x(e=!1){on.push(Fe=e?null:[])}function sa(){on.pop(),Fe=on[on.length-1]||null}let un=1;function eo(e){un+=e}function xi(e){return e.dynamicChildren=un>0?Fe||Ft:null,sa(),un>0&&Fe&&Fe.push(e),e}function L(e,t,n,s,r,o){return xi(p(e,t,n,s,r,o,!0))}function Hs(e,t,n,s,r){return xi(le(e,t,n,s,r,!0))}function Ks(e){return e?e.__v_isVNode===!0:!1}function Et(e,t){return e.type===t.type&&e.key===t.key}const ts="__vInternal",Li=({key:e})=>e??null,Pn=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?ce(e)||Re(e)||M(e)?{i:ve,r:e,k:t,f:!!n}:e:null);function p(e,t=null,n=null,s=0,r=null,o=e===_e?0:1,i=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Li(t),ref:t&&Pn(t),scopeId:Xn,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:ve};return l?(mr(c,n),o&128&&e.normalize(c)):n&&(c.shapeFlag|=ce(n)?8:16),un>0&&!i&&Fe&&(c.patchFlag>0||o&6)&&c.patchFlag!==32&&Fe.push(c),c}const le=ra;function ra(e,t=null,n=null,s=0,r=null,o=!1){if((!e||e===bc)&&(e=Ue),Ks(e)){const l=mt(e,t,!0);return n&&mr(l,n),un>0&&!o&&Fe&&(l.shapeFlag&6?Fe[Fe.indexOf(e)]=l:Fe.push(l)),l.patchFlag|=-2,l}if(_a(e)&&(e=e.__vccOpts),t){t=oa(t);let{class:l,style:c}=t;l&&!ce(l)&&(t.class=Ee(l)),Y(c)&&(ei(c)&&!k(c)&&(c=he({},c)),t.style=pn(c))}const i=ce(e)?1:Sc(e)?128:na(e)?64:Y(e)?4:M(e)?2:0;return p(e,t,n,s,r,i,o,!0)}function oa(e){return e?ei(e)||ts in e?he({},e):e:null}function mt(e,t,n=!1){const{props:s,ref:r,patchFlag:o,children:i}=e,l=t?la(s||{},t):s;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&Li(l),ref:t&&t.ref?n&&r?k(r)?r.concat(Pn(t)):[r,Pn(t)]:Pn(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==_e?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&mt(e.ssContent),ssFallback:e.ssFallback&&mt(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function pe(e=" ",t=0){return le(es,null,e,t)}function ia(e,t){const n=le(In,null,e);return n.staticCount=t,n}function B(e="",t=!1){return t?(x(),Hs(Ue,null,e)):le(Ue,null,e)}function $e(e){return e==null||typeof e=="boolean"?le(Ue):k(e)?le(_e,null,e.slice()):typeof e=="object"?at(e):le(es,null,String(e))}function at(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:mt(e)}function mr(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(k(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),mr(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!(ts in t)?t._ctx=ve:r===3&&ve&&(ve.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else M(t)?(t={default:t,_ctx:ve},n=32):(t=String(t),s&64?(n=16,t=[pe(t)]):n=8);e.children=t,e.shapeFlag|=n}function la(...e){const t={};for(let n=0;nme||ve;let Mn,qs;{const e=Do(),t=(n,s)=>{let r;return(r=e[n])||(r=e[n]=[]),r.push(s),o=>{r.length>1?r.forEach(i=>i(o)):r[0](o)}};Mn=t("__VUE_INSTANCE_SETTERS__",n=>me=n),qs=t("__VUE_SSR_SETTERS__",n=>ns=n)}const mn=e=>{const t=me;return Mn(e),e.scope.on(),()=>{e.scope.off(),Mn(t)}},to=()=>{me&&me.scope.off(),Mn(null)};function Ii(e){return e.vnode.shapeFlag&4}let ns=!1;function da(e,t=!1){t&&qs(t);const{props:n,children:s}=e.vnode,r=Ii(e);Gc(e,n,r,t),Yc(e,s);const o=r?ha(e,t):void 0;return t&&qs(!1),o}function ha(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=ti(new Proxy(e.ctx,Vc));const{setup:s}=n;if(s){const r=e.setupContext=s.length>1?ma(e):null,o=mn(e);Rt();const i=ht(s,e,0,[e.props,r]);if(xt(),o(),No(i)){if(i.then(to,to),t)return i.then(l=>{no(e,l,t)}).catch(l=>{Jn(l,e,0)});e.asyncDep=i}else no(e,i,t)}else Pi(e,t)}function no(e,t,n){M(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Y(t)&&(e.setupState=si(t)),Pi(e,n)}let so;function Pi(e,t,n){const s=e.type;if(!e.render){if(!t&&so&&!s.render){const r=s.template||hr(e).template;if(r){const{isCustomElement:o,compilerOptions:i}=e.appContext.config,{delimiters:l,compilerOptions:c}=s,f=he(he({isCustomElement:o,delimiters:l},i),c);s.render=so(r,f)}}e.render=s.render||Le}{const r=mn(e);Rt();try{Bc(e)}finally{xt(),r()}}}function pa(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return we(e,"get","$attrs"),t[n]}}))}function ma(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return pa(e)},slots:e.slots,emit:e.emit,expose:t}}function ss(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(si(ti(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in sn)return sn[n](e)},has(t,n){return n in t||n in sn}}))}function ga(e,t=!0){return M(e)?e.displayName||e.name:e.name||t&&e.__name}function _a(e){return M(e)&&"__vccOpts"in e}const ki=(e,t)=>sc(e,t,ns);function ba(e,t,n){const s=arguments.length;return s===2?Y(t)&&!k(t)?Ks(t)?le(e,null,[t]):le(e,t):le(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&Ks(n)&&(n=[n]),le(e,t,n))}const ya="3.4.21";/** -* @vue/runtime-dom v3.4.21 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/const Sa="http://www.w3.org/2000/svg",va="http://www.w3.org/1998/Math/MathML",ut=typeof document<"u"?document:null,ro=ut&&ut.createElement("template"),Ca={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?ut.createElementNS(Sa,e):t==="mathml"?ut.createElementNS(va,e):ut.createElement(e,n?{is:n}:void 0);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>ut.createTextNode(e),createComment:e=>ut.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>ut.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,o){const i=n?n.previousSibling:t.lastChild;if(r&&(r===o||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===o||!(r=r.nextSibling)););else{ro.innerHTML=s==="svg"?`${e}`:s==="mathml"?`${e}`:e;const l=ro.content;if(s==="svg"||s==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},st="transition",Xt="animation",fn=Symbol("_vtc"),gr=(e,{slots:t})=>ba(Oc,Ea(e),t);gr.displayName="Transition";const Ni={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};gr.props=he({},hi,Ni);const St=(e,t=[])=>{k(e)?e.forEach(n=>n(...t)):e&&e(...t)},oo=e=>e?k(e)?e.some(t=>t.length>1):e.length>1:!1;function Ea(e){const t={};for(const I in e)I in Ni||(t[I]=e[I]);if(e.css===!1)return t;const{name:n="v",type:s,duration:r,enterFromClass:o=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=o,appearActiveClass:f=i,appearToClass:u=l,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:g=`${n}-leave-active`,leaveToClass:C=`${n}-leave-to`}=e,A=wa(r),E=A&&A[0],D=A&&A[1],{onBeforeEnter:$,onEnter:ee,onEnterCancelled:j,onLeave:z,onLeaveCancelled:re,onBeforeAppear:H=$,onAppear:ye=ee,onAppearCancelled:V=j}=t,oe=(I,ne,Te)=>{vt(I,ne?u:l),vt(I,ne?f:i),Te&&Te()},Q=(I,ne)=>{I._isLeaving=!1,vt(I,d),vt(I,C),vt(I,g),ne&&ne()},ge=I=>(ne,Te)=>{const Jt=I?ye:ee,fe=()=>oe(ne,I,Te);St(Jt,[ne,fe]),io(()=>{vt(ne,I?c:o),rt(ne,I?u:l),oo(Jt)||lo(ne,s,E,fe)})};return he(t,{onBeforeEnter(I){St($,[I]),rt(I,o),rt(I,i)},onBeforeAppear(I){St(H,[I]),rt(I,c),rt(I,f)},onEnter:ge(!1),onAppear:ge(!0),onLeave(I,ne){I._isLeaving=!0;const Te=()=>Q(I,ne);rt(I,d),Oa(),rt(I,g),io(()=>{I._isLeaving&&(vt(I,d),rt(I,C),oo(z)||lo(I,s,D,Te))}),St(z,[I,Te])},onEnterCancelled(I){oe(I,!1),St(j,[I])},onAppearCancelled(I){oe(I,!0),St(V,[I])},onLeaveCancelled(I){Q(I),St(re,[I])}})}function wa(e){if(e==null)return null;if(Y(e))return[Ss(e.enter),Ss(e.leave)];{const t=Ss(e);return[t,t]}}function Ss(e){return Tl(e)}function rt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[fn]||(e[fn]=new Set)).add(t)}function vt(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[fn];n&&(n.delete(t),n.size||(e[fn]=void 0))}function io(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Aa=0;function lo(e,t,n,s){const r=e._endId=++Aa,o=()=>{r===e._endId&&s()};if(n)return setTimeout(o,n);const{type:i,timeout:l,propCount:c}=Ta(e,t);if(!i)return s();const f=i+"end";let u=0;const d=()=>{e.removeEventListener(f,g),o()},g=C=>{C.target===e&&++u>=c&&d()};setTimeout(()=>{u(n[A]||"").split(", "),r=s(`${st}Delay`),o=s(`${st}Duration`),i=co(r,o),l=s(`${Xt}Delay`),c=s(`${Xt}Duration`),f=co(l,c);let u=null,d=0,g=0;t===st?i>0&&(u=st,d=i,g=o.length):t===Xt?f>0&&(u=Xt,d=f,g=c.length):(d=Math.max(i,f),u=d>0?i>f?st:Xt:null,g=u?u===st?o.length:c.length:0);const C=u===st&&/\b(transform|all)(,|$)/.test(s(`${st}Property`).toString());return{type:u,timeout:d,propCount:g,hasTransform:C}}function co(e,t){for(;e.lengthao(n)+ao(e[s])))}function ao(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Oa(){return document.body.offsetHeight}function Ra(e,t,n){const s=e[fn];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const uo=Symbol("_vod"),xa=Symbol("_vsh"),La=Symbol(""),Ia=/(^|;)\s*display\s*:/;function Pa(e,t,n){const s=e.style,r=ce(n);let o=!1;if(n&&!r){if(t)if(ce(t))for(const i of t.split(";")){const l=i.slice(0,i.indexOf(":")).trim();n[l]==null&&kn(s,l,"")}else for(const i in t)n[i]==null&&kn(s,i,"");for(const i in n)i==="display"&&(o=!0),kn(s,i,n[i])}else if(r){if(t!==n){const i=s[La];i&&(n+=";"+i),s.cssText=n,o=Ia.test(n)}}else t&&e.removeAttribute("style");uo in e&&(e[uo]=o?s.display:"",e[xa]&&(s.display="none"))}const fo=/\s*!important$/;function kn(e,t,n){if(k(n))n.forEach(s=>kn(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=ka(e,t);fo.test(n)?e.setProperty(jt(s),n.replace(fo,""),"important"):e[s]=n}}const ho=["Webkit","Moz","ms"],vs={};function ka(e,t){const n=vs[t];if(n)return n;let s=Ke(t);if(s!=="filter"&&s in e)return vs[t]=s;s=Wn(s);for(let r=0;rCs||(Ba.then(()=>Cs=0),Cs=Date.now());function $a(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;Ie(ja(s,n.value),t,5,[s])};return n.value=e,n.attached=Ma(),n}function ja(e,t){if(k(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>r=>!r._stopped&&s&&s(r))}else return t}const _o=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Ha=(e,t,n,s,r,o,i,l,c)=>{const f=r==="svg";t==="class"?Ra(e,s,f):t==="style"?Pa(e,n,s):Hn(t)?er(t)||Da(e,t,n,s,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Ka(e,t,s,f))?Fa(e,t,s,o,i,l,c):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),Na(e,t,s,f))};function Ka(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&_o(t)&&M(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const r=e.tagName;if(r==="IMG"||r==="VIDEO"||r==="CANVAS"||r==="SOURCE")return!1}return _o(t)&&ce(n)?!1:t in e}const Mt=e=>{const t=e.props["onUpdate:modelValue"]||!1;return k(t)?n=>Rn(t,n):t};function qa(e){e.target.composing=!0}function bo(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Ye=Symbol("_assign"),en={created(e,{modifiers:{lazy:t,trim:n,number:s}},r){e[Ye]=Mt(r);const o=s||r.props&&r.props.type==="number";ft(e,t?"change":"input",i=>{if(i.target.composing)return;let l=e.value;n&&(l=l.trim()),o&&(l=Rs(l)),e[Ye](l)}),n&&ft(e,"change",()=>{e.value=e.value.trim()}),t||(ft(e,"compositionstart",qa),ft(e,"compositionend",bo),ft(e,"change",bo))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,modifiers:{lazy:n,trim:s,number:r}},o){if(e[Ye]=Mt(o),e.composing)return;const i=r||e.type==="number"?Rs(e.value):e.value,l=t??"";i!==l&&(document.activeElement===e&&e.type!=="range"&&(n||s&&e.value.trim()===l)||(e.value=l))}},ot={deep:!0,created(e,t,n){e[Ye]=Mt(n),ft(e,"change",()=>{const s=e._modelValue,r=Fi(e),o=e.checked,i=e[Ye];if(k(s)){const l=Bo(s,r),c=l!==-1;if(o&&!c)i(s.concat(r));else if(!o&&c){const f=[...s];f.splice(l,1),i(f)}}else if(Kn(s)){const l=new Set(s);o?l.add(r):l.delete(r),i(l)}else i(Ui(e,o))})},mounted:yo,beforeUpdate(e,t,n){e[Ye]=Mt(n),yo(e,t,n)}};function yo(e,{value:t,oldValue:n},s){e._modelValue=t,k(t)?e.checked=Bo(t,s.props.value)>-1:Kn(t)?e.checked=t.has(s.props.value):t!==n&&(e.checked=Bt(t,Ui(e,!0)))}const Ge={created(e,{value:t},n){e.checked=Bt(t,n.props.value),e[Ye]=Mt(n),ft(e,"change",()=>{e[Ye](Fi(e))})},beforeUpdate(e,{value:t,oldValue:n},s){e[Ye]=Mt(s),t!==n&&(e.checked=Bt(t,s.props.value))}};function Fi(e){return"_value"in e?e._value:e.value}function Ui(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const Wa=he({patchProp:Ha},Ca);let So;function Ga(){return So||(So=Qc(Wa))}const za=(...e)=>{const t=Ga().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=Ya(s);if(!r)return;const o=t._component;!M(o)&&!o.render&&!o.template&&(o.template=r.innerHTML),r.innerHTML="";const i=n(r,!1,Ja(r));return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),i},t};function Ja(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Ya(e){return ce(e)?document.querySelector(e):e}function Di(e,t){return function(){return e.apply(t,arguments)}}const{toString:Xa}=Object.prototype,{getPrototypeOf:_r}=Object,rs=(e=>t=>{const n=Xa.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),qe=e=>(e=e.toLowerCase(),t=>rs(t)===e),os=e=>t=>typeof t===e,{isArray:qt}=Array,dn=os("undefined");function Qa(e){return e!==null&&!dn(e)&&e.constructor!==null&&!dn(e.constructor)&&Pe(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const Vi=qe("ArrayBuffer");function Za(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&Vi(e.buffer),t}const eu=os("string"),Pe=os("function"),Bi=os("number"),is=e=>e!==null&&typeof e=="object",tu=e=>e===!0||e===!1,Nn=e=>{if(rs(e)!=="object")return!1;const t=_r(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Symbol.toStringTag in e)&&!(Symbol.iterator in e)},nu=qe("Date"),su=qe("File"),ru=qe("Blob"),ou=qe("FileList"),iu=e=>is(e)&&Pe(e.pipe),lu=e=>{let t;return e&&(typeof FormData=="function"&&e instanceof FormData||Pe(e.append)&&((t=rs(e))==="formdata"||t==="object"&&Pe(e.toString)&&e.toString()==="[object FormData]"))},cu=qe("URLSearchParams"),au=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function gn(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;let s,r;if(typeof e!="object"&&(e=[e]),qt(e))for(s=0,r=e.length;s0;)if(r=n[s],t===r.toLowerCase())return r;return null}const $i=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,ji=e=>!dn(e)&&e!==$i;function Ws(){const{caseless:e}=ji(this)&&this||{},t={},n=(s,r)=>{const o=e&&Mi(t,r)||r;Nn(t[o])&&Nn(s)?t[o]=Ws(t[o],s):Nn(s)?t[o]=Ws({},s):qt(s)?t[o]=s.slice():t[o]=s};for(let s=0,r=arguments.length;s(gn(t,(r,o)=>{n&&Pe(r)?e[o]=Di(r,n):e[o]=r},{allOwnKeys:s}),e),fu=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),du=(e,t,n,s)=>{e.prototype=Object.create(t.prototype,s),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},hu=(e,t,n,s)=>{let r,o,i;const l={};if(t=t||{},e==null)return t;do{for(r=Object.getOwnPropertyNames(e),o=r.length;o-- >0;)i=r[o],(!s||s(i,e,t))&&!l[i]&&(t[i]=e[i],l[i]=!0);e=n!==!1&&_r(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},pu=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const s=e.indexOf(t,n);return s!==-1&&s===n},mu=e=>{if(!e)return null;if(qt(e))return e;let t=e.length;if(!Bi(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},gu=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&_r(Uint8Array)),_u=(e,t)=>{const s=(e&&e[Symbol.iterator]).call(e);let r;for(;(r=s.next())&&!r.done;){const o=r.value;t.call(e,o[0],o[1])}},bu=(e,t)=>{let n;const s=[];for(;(n=e.exec(t))!==null;)s.push(n);return s},yu=qe("HTMLFormElement"),Su=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,s,r){return s.toUpperCase()+r}),vo=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),vu=qe("RegExp"),Hi=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),s={};gn(n,(r,o)=>{let i;(i=t(r,o,e))!==!1&&(s[o]=i||r)}),Object.defineProperties(e,s)},Cu=e=>{Hi(e,(t,n)=>{if(Pe(e)&&["arguments","caller","callee"].indexOf(n)!==-1)return!1;const s=e[n];if(Pe(s)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},Eu=(e,t)=>{const n={},s=r=>{r.forEach(o=>{n[o]=!0})};return qt(e)?s(e):s(String(e).split(t)),n},wu=()=>{},Au=(e,t)=>(e=+e,Number.isFinite(e)?e:t),Es="abcdefghijklmnopqrstuvwxyz",Co="0123456789",Ki={DIGIT:Co,ALPHA:Es,ALPHA_DIGIT:Es+Es.toUpperCase()+Co},Tu=(e=16,t=Ki.ALPHA_DIGIT)=>{let n="";const{length:s}=t;for(;e--;)n+=t[Math.random()*s|0];return n};function Ou(e){return!!(e&&Pe(e.append)&&e[Symbol.toStringTag]==="FormData"&&e[Symbol.iterator])}const Ru=e=>{const t=new Array(10),n=(s,r)=>{if(is(s)){if(t.indexOf(s)>=0)return;if(!("toJSON"in s)){t[r]=s;const o=qt(s)?[]:{};return gn(s,(i,l)=>{const c=n(i,r+1);!dn(c)&&(o[l]=c)}),t[r]=void 0,o}}return s};return n(e,0)},xu=qe("AsyncFunction"),Lu=e=>e&&(is(e)||Pe(e))&&Pe(e.then)&&Pe(e.catch),_={isArray:qt,isArrayBuffer:Vi,isBuffer:Qa,isFormData:lu,isArrayBufferView:Za,isString:eu,isNumber:Bi,isBoolean:tu,isObject:is,isPlainObject:Nn,isUndefined:dn,isDate:nu,isFile:su,isBlob:ru,isRegExp:vu,isFunction:Pe,isStream:iu,isURLSearchParams:cu,isTypedArray:gu,isFileList:ou,forEach:gn,merge:Ws,extend:uu,trim:au,stripBOM:fu,inherits:du,toFlatObject:hu,kindOf:rs,kindOfTest:qe,endsWith:pu,toArray:mu,forEachEntry:_u,matchAll:bu,isHTMLForm:yu,hasOwnProperty:vo,hasOwnProp:vo,reduceDescriptors:Hi,freezeMethods:Cu,toObjectSet:Eu,toCamelCase:Su,noop:wu,toFiniteNumber:Au,findKey:Mi,global:$i,isContextDefined:ji,ALPHABET:Ki,generateString:Tu,isSpecCompliantForm:Ou,toJSONObject:Ru,isAsyncFn:xu,isThenable:Lu};function q(e,t,n,s,r){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),s&&(this.request=s),r&&(this.response=r)}_.inherits(q,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:_.toJSONObject(this.config),code:this.code,status:this.response&&this.response.status?this.response.status:null}}});const qi=q.prototype,Wi={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(e=>{Wi[e]={value:e}});Object.defineProperties(q,Wi);Object.defineProperty(qi,"isAxiosError",{value:!0});q.from=(e,t,n,s,r,o)=>{const i=Object.create(qi);return _.toFlatObject(e,i,function(c){return c!==Error.prototype},l=>l!=="isAxiosError"),q.call(i,e.message,t,n,s,r),i.cause=e,i.name=e.name,o&&Object.assign(i,o),i};const Iu=null;function Gs(e){return _.isPlainObject(e)||_.isArray(e)}function Gi(e){return _.endsWith(e,"[]")?e.slice(0,-2):e}function Eo(e,t,n){return e?e.concat(t).map(function(r,o){return r=Gi(r),!n&&o?"["+r+"]":r}).join(n?".":""):t}function Pu(e){return _.isArray(e)&&!e.some(Gs)}const ku=_.toFlatObject(_,{},null,function(t){return/^is[A-Z]/.test(t)});function ls(e,t,n){if(!_.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,n=_.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(E,D){return!_.isUndefined(D[E])});const s=n.metaTokens,r=n.visitor||u,o=n.dots,i=n.indexes,c=(n.Blob||typeof Blob<"u"&&Blob)&&_.isSpecCompliantForm(t);if(!_.isFunction(r))throw new TypeError("visitor must be a function");function f(A){if(A===null)return"";if(_.isDate(A))return A.toISOString();if(!c&&_.isBlob(A))throw new q("Blob is not supported. Use a Buffer instead.");return _.isArrayBuffer(A)||_.isTypedArray(A)?c&&typeof Blob=="function"?new Blob([A]):Buffer.from(A):A}function u(A,E,D){let $=A;if(A&&!D&&typeof A=="object"){if(_.endsWith(E,"{}"))E=s?E:E.slice(0,-2),A=JSON.stringify(A);else if(_.isArray(A)&&Pu(A)||(_.isFileList(A)||_.endsWith(E,"[]"))&&($=_.toArray(A)))return E=Gi(E),$.forEach(function(j,z){!(_.isUndefined(j)||j===null)&&t.append(i===!0?Eo([E],z,o):i===null?E:E+"[]",f(j))}),!1}return Gs(A)?!0:(t.append(Eo(D,E,o),f(A)),!1)}const d=[],g=Object.assign(ku,{defaultVisitor:u,convertValue:f,isVisitable:Gs});function C(A,E){if(!_.isUndefined(A)){if(d.indexOf(A)!==-1)throw Error("Circular reference detected in "+E.join("."));d.push(A),_.forEach(A,function($,ee){(!(_.isUndefined($)||$===null)&&r.call(t,$,_.isString(ee)?ee.trim():ee,E,g))===!0&&C($,E?E.concat(ee):[ee])}),d.pop()}}if(!_.isObject(e))throw new TypeError("data must be an object");return C(e),t}function wo(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(s){return t[s]})}function br(e,t){this._pairs=[],e&&ls(e,this,t)}const zi=br.prototype;zi.append=function(t,n){this._pairs.push([t,n])};zi.toString=function(t){const n=t?function(s){return t.call(this,s,wo)}:wo;return this._pairs.map(function(r){return n(r[0])+"="+n(r[1])},"").join("&")};function Nu(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function Ji(e,t,n){if(!t)return e;const s=n&&n.encode||Nu,r=n&&n.serialize;let o;if(r?o=r(t,n):o=_.isURLSearchParams(t)?t.toString():new br(t,n).toString(s),o){const i=e.indexOf("#");i!==-1&&(e=e.slice(0,i)),e+=(e.indexOf("?")===-1?"?":"&")+o}return e}class Ao{constructor(){this.handlers=[]}use(t,n,s){return this.handlers.push({fulfilled:t,rejected:n,synchronous:s?s.synchronous:!1,runWhen:s?s.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){_.forEach(this.handlers,function(s){s!==null&&t(s)})}}const Yi={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},Fu=typeof URLSearchParams<"u"?URLSearchParams:br,Uu=typeof FormData<"u"?FormData:null,Du=typeof Blob<"u"?Blob:null,Vu={isBrowser:!0,classes:{URLSearchParams:Fu,FormData:Uu,Blob:Du},protocols:["http","https","file","blob","url","data"]},Xi=typeof window<"u"&&typeof document<"u",Bu=(e=>Xi&&["ReactNative","NativeScript","NS"].indexOf(e)<0)(typeof navigator<"u"&&navigator.product),Mu=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",$u=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:Xi,hasStandardBrowserEnv:Bu,hasStandardBrowserWebWorkerEnv:Mu},Symbol.toStringTag,{value:"Module"})),He={...$u,...Vu};function ju(e,t){return ls(e,new He.classes.URLSearchParams,Object.assign({visitor:function(n,s,r,o){return He.isNode&&_.isBuffer(n)?(this.append(s,n.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)}},t))}function Hu(e){return _.matchAll(/\w+|\[(\w*)]/g,e).map(t=>t[0]==="[]"?"":t[1]||t[0])}function Ku(e){const t={},n=Object.keys(e);let s;const r=n.length;let o;for(s=0;s=n.length;return i=!i&&_.isArray(r)?r.length:i,c?(_.hasOwnProp(r,i)?r[i]=[r[i],s]:r[i]=s,!l):((!r[i]||!_.isObject(r[i]))&&(r[i]=[]),t(n,s,r[i],o)&&_.isArray(r[i])&&(r[i]=Ku(r[i])),!l)}if(_.isFormData(e)&&_.isFunction(e.entries)){const n={};return _.forEachEntry(e,(s,r)=>{t(Hu(s),r,n,0)}),n}return null}function qu(e,t,n){if(_.isString(e))try{return(t||JSON.parse)(e),_.trim(e)}catch(s){if(s.name!=="SyntaxError")throw s}return(n||JSON.stringify)(e)}const yr={transitional:Yi,adapter:["xhr","http"],transformRequest:[function(t,n){const s=n.getContentType()||"",r=s.indexOf("application/json")>-1,o=_.isObject(t);if(o&&_.isHTMLForm(t)&&(t=new FormData(t)),_.isFormData(t))return r?JSON.stringify(Qi(t)):t;if(_.isArrayBuffer(t)||_.isBuffer(t)||_.isStream(t)||_.isFile(t)||_.isBlob(t))return t;if(_.isArrayBufferView(t))return t.buffer;if(_.isURLSearchParams(t))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let l;if(o){if(s.indexOf("application/x-www-form-urlencoded")>-1)return ju(t,this.formSerializer).toString();if((l=_.isFileList(t))||s.indexOf("multipart/form-data")>-1){const c=this.env&&this.env.FormData;return ls(l?{"files[]":t}:t,c&&new c,this.formSerializer)}}return o||r?(n.setContentType("application/json",!1),qu(t)):t}],transformResponse:[function(t){const n=this.transitional||yr.transitional,s=n&&n.forcedJSONParsing,r=this.responseType==="json";if(t&&_.isString(t)&&(s&&!this.responseType||r)){const i=!(n&&n.silentJSONParsing)&&r;try{return JSON.parse(t)}catch(l){if(i)throw l.name==="SyntaxError"?q.from(l,q.ERR_BAD_RESPONSE,this,null,this.response):l}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:He.classes.FormData,Blob:He.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};_.forEach(["delete","get","head","post","put","patch"],e=>{yr.headers[e]={}});const Sr=yr,Wu=_.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Gu=e=>{const t={};let n,s,r;return e&&e.split(` -`).forEach(function(i){r=i.indexOf(":"),n=i.substring(0,r).trim().toLowerCase(),s=i.substring(r+1).trim(),!(!n||t[n]&&Wu[n])&&(n==="set-cookie"?t[n]?t[n].push(s):t[n]=[s]:t[n]=t[n]?t[n]+", "+s:s)}),t},To=Symbol("internals");function Qt(e){return e&&String(e).trim().toLowerCase()}function Fn(e){return e===!1||e==null?e:_.isArray(e)?e.map(Fn):String(e)}function zu(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let s;for(;s=n.exec(e);)t[s[1]]=s[2];return t}const Ju=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function ws(e,t,n,s,r){if(_.isFunction(s))return s.call(this,t,n);if(r&&(t=n),!!_.isString(t)){if(_.isString(s))return t.indexOf(s)!==-1;if(_.isRegExp(s))return s.test(t)}}function Yu(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,s)=>n.toUpperCase()+s)}function Xu(e,t){const n=_.toCamelCase(" "+t);["get","set","has"].forEach(s=>{Object.defineProperty(e,s+n,{value:function(r,o,i){return this[s].call(this,t,r,o,i)},configurable:!0})})}class cs{constructor(t){t&&this.set(t)}set(t,n,s){const r=this;function o(l,c,f){const u=Qt(c);if(!u)throw new Error("header name must be a non-empty string");const d=_.findKey(r,u);(!d||r[d]===void 0||f===!0||f===void 0&&r[d]!==!1)&&(r[d||c]=Fn(l))}const i=(l,c)=>_.forEach(l,(f,u)=>o(f,u,c));return _.isPlainObject(t)||t instanceof this.constructor?i(t,n):_.isString(t)&&(t=t.trim())&&!Ju(t)?i(Gu(t),n):t!=null&&o(n,t,s),this}get(t,n){if(t=Qt(t),t){const s=_.findKey(this,t);if(s){const r=this[s];if(!n)return r;if(n===!0)return zu(r);if(_.isFunction(n))return n.call(this,r,s);if(_.isRegExp(n))return n.exec(r);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=Qt(t),t){const s=_.findKey(this,t);return!!(s&&this[s]!==void 0&&(!n||ws(this,this[s],s,n)))}return!1}delete(t,n){const s=this;let r=!1;function o(i){if(i=Qt(i),i){const l=_.findKey(s,i);l&&(!n||ws(s,s[l],l,n))&&(delete s[l],r=!0)}}return _.isArray(t)?t.forEach(o):o(t),r}clear(t){const n=Object.keys(this);let s=n.length,r=!1;for(;s--;){const o=n[s];(!t||ws(this,this[o],o,t,!0))&&(delete this[o],r=!0)}return r}normalize(t){const n=this,s={};return _.forEach(this,(r,o)=>{const i=_.findKey(s,o);if(i){n[i]=Fn(r),delete n[o];return}const l=t?Yu(o):String(o).trim();l!==o&&delete n[o],n[l]=Fn(r),s[l]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return _.forEach(this,(s,r)=>{s!=null&&s!==!1&&(n[r]=t&&_.isArray(s)?s.join(", "):s)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(` -`)}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const s=new this(t);return n.forEach(r=>s.set(r)),s}static accessor(t){const s=(this[To]=this[To]={accessors:{}}).accessors,r=this.prototype;function o(i){const l=Qt(i);s[l]||(Xu(r,i),s[l]=!0)}return _.isArray(t)?t.forEach(o):o(t),this}}cs.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);_.reduceDescriptors(cs.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(s){this[n]=s}}});_.freezeMethods(cs);const Xe=cs;function As(e,t){const n=this||Sr,s=t||n,r=Xe.from(s.headers);let o=s.data;return _.forEach(e,function(l){o=l.call(n,o,r.normalize(),t?t.status:void 0)}),r.normalize(),o}function Zi(e){return!!(e&&e.__CANCEL__)}function _n(e,t,n){q.call(this,e??"canceled",q.ERR_CANCELED,t,n),this.name="CanceledError"}_.inherits(_n,q,{__CANCEL__:!0});function Qu(e,t,n){const s=n.config.validateStatus;!n.status||!s||s(n.status)?e(n):t(new q("Request failed with status code "+n.status,[q.ERR_BAD_REQUEST,q.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}const Zu=He.hasStandardBrowserEnv?{write(e,t,n,s,r,o){const i=[e+"="+encodeURIComponent(t)];_.isNumber(n)&&i.push("expires="+new Date(n).toGMTString()),_.isString(s)&&i.push("path="+s),_.isString(r)&&i.push("domain="+r),o===!0&&i.push("secure"),document.cookie=i.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function ef(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function tf(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function el(e,t){return e&&!ef(t)?tf(e,t):t}const nf=He.hasStandardBrowserEnv?function(){const t=/(msie|trident)/i.test(navigator.userAgent),n=document.createElement("a");let s;function r(o){let i=o;return t&&(n.setAttribute("href",i),i=n.href),n.setAttribute("href",i),{href:n.href,protocol:n.protocol?n.protocol.replace(/:$/,""):"",host:n.host,search:n.search?n.search.replace(/^\?/,""):"",hash:n.hash?n.hash.replace(/^#/,""):"",hostname:n.hostname,port:n.port,pathname:n.pathname.charAt(0)==="/"?n.pathname:"/"+n.pathname}}return s=r(window.location.href),function(i){const l=_.isString(i)?r(i):i;return l.protocol===s.protocol&&l.host===s.host}}():function(){return function(){return!0}}();function sf(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function rf(e,t){e=e||10;const n=new Array(e),s=new Array(e);let r=0,o=0,i;return t=t!==void 0?t:1e3,function(c){const f=Date.now(),u=s[o];i||(i=f),n[r]=c,s[r]=f;let d=o,g=0;for(;d!==r;)g+=n[d++],d=d%e;if(r=(r+1)%e,r===o&&(o=(o+1)%e),f-i{const o=r.loaded,i=r.lengthComputable?r.total:void 0,l=o-n,c=s(l),f=o<=i;n=o;const u={loaded:o,total:i,progress:i?o/i:void 0,bytes:l,rate:c||void 0,estimated:c&&i&&f?(i-o)/c:void 0,event:r};u[t?"download":"upload"]=!0,e(u)}}const of=typeof XMLHttpRequest<"u",lf=of&&function(e){return new Promise(function(n,s){let r=e.data;const o=Xe.from(e.headers).normalize();let{responseType:i,withXSRFToken:l}=e,c;function f(){e.cancelToken&&e.cancelToken.unsubscribe(c),e.signal&&e.signal.removeEventListener("abort",c)}let u;if(_.isFormData(r)){if(He.hasStandardBrowserEnv||He.hasStandardBrowserWebWorkerEnv)o.setContentType(!1);else if((u=o.getContentType())!==!1){const[E,...D]=u?u.split(";").map($=>$.trim()).filter(Boolean):[];o.setContentType([E||"multipart/form-data",...D].join("; "))}}let d=new XMLHttpRequest;if(e.auth){const E=e.auth.username||"",D=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";o.set("Authorization","Basic "+btoa(E+":"+D))}const g=el(e.baseURL,e.url);d.open(e.method.toUpperCase(),Ji(g,e.params,e.paramsSerializer),!0),d.timeout=e.timeout;function C(){if(!d)return;const E=Xe.from("getAllResponseHeaders"in d&&d.getAllResponseHeaders()),$={data:!i||i==="text"||i==="json"?d.responseText:d.response,status:d.status,statusText:d.statusText,headers:E,config:e,request:d};Qu(function(j){n(j),f()},function(j){s(j),f()},$),d=null}if("onloadend"in d?d.onloadend=C:d.onreadystatechange=function(){!d||d.readyState!==4||d.status===0&&!(d.responseURL&&d.responseURL.indexOf("file:")===0)||setTimeout(C)},d.onabort=function(){d&&(s(new q("Request aborted",q.ECONNABORTED,e,d)),d=null)},d.onerror=function(){s(new q("Network Error",q.ERR_NETWORK,e,d)),d=null},d.ontimeout=function(){let D=e.timeout?"timeout of "+e.timeout+"ms exceeded":"timeout exceeded";const $=e.transitional||Yi;e.timeoutErrorMessage&&(D=e.timeoutErrorMessage),s(new q(D,$.clarifyTimeoutError?q.ETIMEDOUT:q.ECONNABORTED,e,d)),d=null},He.hasStandardBrowserEnv&&(l&&_.isFunction(l)&&(l=l(e)),l||l!==!1&&nf(g))){const E=e.xsrfHeaderName&&e.xsrfCookieName&&Zu.read(e.xsrfCookieName);E&&o.set(e.xsrfHeaderName,E)}r===void 0&&o.setContentType(null),"setRequestHeader"in d&&_.forEach(o.toJSON(),function(D,$){d.setRequestHeader($,D)}),_.isUndefined(e.withCredentials)||(d.withCredentials=!!e.withCredentials),i&&i!=="json"&&(d.responseType=e.responseType),typeof e.onDownloadProgress=="function"&&d.addEventListener("progress",Oo(e.onDownloadProgress,!0)),typeof e.onUploadProgress=="function"&&d.upload&&d.upload.addEventListener("progress",Oo(e.onUploadProgress)),(e.cancelToken||e.signal)&&(c=E=>{d&&(s(!E||E.type?new _n(null,e,d):E),d.abort(),d=null)},e.cancelToken&&e.cancelToken.subscribe(c),e.signal&&(e.signal.aborted?c():e.signal.addEventListener("abort",c)));const A=sf(g);if(A&&He.protocols.indexOf(A)===-1){s(new q("Unsupported protocol "+A+":",q.ERR_BAD_REQUEST,e));return}d.send(r||null)})},zs={http:Iu,xhr:lf};_.forEach(zs,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch{}Object.defineProperty(e,"adapterName",{value:t})}});const Ro=e=>`- ${e}`,cf=e=>_.isFunction(e)||e===null||e===!1,tl={getAdapter:e=>{e=_.isArray(e)?e:[e];const{length:t}=e;let n,s;const r={};for(let o=0;o`adapter ${l} `+(c===!1?"is not supported by the environment":"is not available in the build"));let i=t?o.length>1?`since : -`+o.map(Ro).join(` -`):" "+Ro(o[0]):"as no adapter specified";throw new q("There is no suitable adapter to dispatch the request "+i,"ERR_NOT_SUPPORT")}return s},adapters:zs};function Ts(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new _n(null,e)}function xo(e){return Ts(e),e.headers=Xe.from(e.headers),e.data=As.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),tl.getAdapter(e.adapter||Sr.adapter)(e).then(function(s){return Ts(e),s.data=As.call(e,e.transformResponse,s),s.headers=Xe.from(s.headers),s},function(s){return Zi(s)||(Ts(e),s&&s.response&&(s.response.data=As.call(e,e.transformResponse,s.response),s.response.headers=Xe.from(s.response.headers))),Promise.reject(s)})}const Lo=e=>e instanceof Xe?{...e}:e;function $t(e,t){t=t||{};const n={};function s(f,u,d){return _.isPlainObject(f)&&_.isPlainObject(u)?_.merge.call({caseless:d},f,u):_.isPlainObject(u)?_.merge({},u):_.isArray(u)?u.slice():u}function r(f,u,d){if(_.isUndefined(u)){if(!_.isUndefined(f))return s(void 0,f,d)}else return s(f,u,d)}function o(f,u){if(!_.isUndefined(u))return s(void 0,u)}function i(f,u){if(_.isUndefined(u)){if(!_.isUndefined(f))return s(void 0,f)}else return s(void 0,u)}function l(f,u,d){if(d in t)return s(f,u);if(d in e)return s(void 0,f)}const c={url:o,method:o,data:o,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:l,headers:(f,u)=>r(Lo(f),Lo(u),!0)};return _.forEach(Object.keys(Object.assign({},e,t)),function(u){const d=c[u]||r,g=d(e[u],t[u],u);_.isUndefined(g)&&d!==l||(n[u]=g)}),n}const nl="1.6.8",vr={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{vr[e]=function(s){return typeof s===e||"a"+(t<1?"n ":" ")+e}});const Io={};vr.transitional=function(t,n,s){function r(o,i){return"[Axios v"+nl+"] Transitional option '"+o+"'"+i+(s?". "+s:"")}return(o,i,l)=>{if(t===!1)throw new q(r(i," has been removed"+(n?" in "+n:"")),q.ERR_DEPRECATED);return n&&!Io[i]&&(Io[i]=!0,console.warn(r(i," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(o,i,l):!0}};function af(e,t,n){if(typeof e!="object")throw new q("options must be an object",q.ERR_BAD_OPTION_VALUE);const s=Object.keys(e);let r=s.length;for(;r-- >0;){const o=s[r],i=t[o];if(i){const l=e[o],c=l===void 0||i(l,o,e);if(c!==!0)throw new q("option "+o+" must be "+c,q.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new q("Unknown option "+o,q.ERR_BAD_OPTION)}}const Js={assertOptions:af,validators:vr},it=Js.validators;class $n{constructor(t){this.defaults=t,this.interceptors={request:new Ao,response:new Ao}}async request(t,n){try{return await this._request(t,n)}catch(s){if(s instanceof Error){let r;Error.captureStackTrace?Error.captureStackTrace(r={}):r=new Error;const o=r.stack?r.stack.replace(/^.+\n/,""):"";s.stack?o&&!String(s.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(s.stack+=` -`+o):s.stack=o}throw s}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=$t(this.defaults,n);const{transitional:s,paramsSerializer:r,headers:o}=n;s!==void 0&&Js.assertOptions(s,{silentJSONParsing:it.transitional(it.boolean),forcedJSONParsing:it.transitional(it.boolean),clarifyTimeoutError:it.transitional(it.boolean)},!1),r!=null&&(_.isFunction(r)?n.paramsSerializer={serialize:r}:Js.assertOptions(r,{encode:it.function,serialize:it.function},!0)),n.method=(n.method||this.defaults.method||"get").toLowerCase();let i=o&&_.merge(o.common,o[n.method]);o&&_.forEach(["delete","get","head","post","put","patch","common"],A=>{delete o[A]}),n.headers=Xe.concat(i,o);const l=[];let c=!0;this.interceptors.request.forEach(function(E){typeof E.runWhen=="function"&&E.runWhen(n)===!1||(c=c&&E.synchronous,l.unshift(E.fulfilled,E.rejected))});const f=[];this.interceptors.response.forEach(function(E){f.push(E.fulfilled,E.rejected)});let u,d=0,g;if(!c){const A=[xo.bind(this),void 0];for(A.unshift.apply(A,l),A.push.apply(A,f),g=A.length,u=Promise.resolve(n);d{if(!s._listeners)return;let o=s._listeners.length;for(;o-- >0;)s._listeners[o](r);s._listeners=null}),this.promise.then=r=>{let o;const i=new Promise(l=>{s.subscribe(l),o=l}).then(r);return i.cancel=function(){s.unsubscribe(o)},i},t(function(o,i,l){s.reason||(s.reason=new _n(o,i,l),n(s.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}static source(){let t;return{token:new Cr(function(r){t=r}),cancel:t}}}const uf=Cr;function ff(e){return function(n){return e.apply(null,n)}}function df(e){return _.isObject(e)&&e.isAxiosError===!0}const Ys={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Ys).forEach(([e,t])=>{Ys[t]=e});const hf=Ys;function sl(e){const t=new Un(e),n=Di(Un.prototype.request,t);return _.extend(n,Un.prototype,t,{allOwnKeys:!0}),_.extend(n,t,null,{allOwnKeys:!0}),n.create=function(r){return sl($t(e,r))},n}const U=sl(Sr);U.Axios=Un;U.CanceledError=_n;U.CancelToken=uf;U.isCancel=Zi;U.VERSION=nl;U.toFormData=ls;U.AxiosError=q;U.Cancel=U.CanceledError;U.all=function(t){return Promise.all(t)};U.spread=ff;U.isAxiosError=df;U.mergeConfig=$t;U.AxiosHeaders=Xe;U.formToJSON=e=>Qi(_.isHTMLForm(e)?new FormData(e):e);U.getAdapter=tl.getAdapter;U.HttpStatusCode=hf;U.default=U;function pf(){return rl().__VUE_DEVTOOLS_GLOBAL_HOOK__}function rl(){return typeof navigator<"u"&&typeof window<"u"?window:typeof globalThis<"u"?globalThis:{}}const mf=typeof Proxy=="function",gf="devtools-plugin:setup",_f="plugin:settings:set";let kt,Xs;function bf(){var e;return kt!==void 0||(typeof window<"u"&&window.performance?(kt=!0,Xs=window.performance):typeof globalThis<"u"&&(!((e=globalThis.perf_hooks)===null||e===void 0)&&e.performance)?(kt=!0,Xs=globalThis.perf_hooks.performance):kt=!1),kt}function yf(){return bf()?Xs.now():Date.now()}class Sf{constructor(t,n){this.target=null,this.targetQueue=[],this.onQueue=[],this.plugin=t,this.hook=n;const s={};if(t.settings)for(const i in t.settings){const l=t.settings[i];s[i]=l.defaultValue}const r=`__vue-devtools-plugin-settings__${t.id}`;let o=Object.assign({},s);try{const i=localStorage.getItem(r),l=JSON.parse(i);Object.assign(o,l)}catch{}this.fallbacks={getSettings(){return o},setSettings(i){try{localStorage.setItem(r,JSON.stringify(i))}catch{}o=i},now(){return yf()}},n&&n.on(_f,(i,l)=>{i===this.plugin.id&&this.fallbacks.setSettings(l)}),this.proxiedOn=new Proxy({},{get:(i,l)=>this.target?this.target.on[l]:(...c)=>{this.onQueue.push({method:l,args:c})}}),this.proxiedTarget=new Proxy({},{get:(i,l)=>this.target?this.target[l]:l==="on"?this.proxiedOn:Object.keys(this.fallbacks).includes(l)?(...c)=>(this.targetQueue.push({method:l,args:c,resolve:()=>{}}),this.fallbacks[l](...c)):(...c)=>new Promise(f=>{this.targetQueue.push({method:l,args:c,resolve:f})})})}async setRealTarget(t){this.target=t;for(const n of this.onQueue)this.target.on[n.method](...n.args);for(const n of this.targetQueue)n.resolve(await this.target[n.method](...n.args))}}function vf(e,t){const n=e,s=rl(),r=pf(),o=mf&&n.enableEarlyProxy;if(r&&(s.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__||!o))r.emit(gf,e,t);else{const i=o?new Sf(n,r):null;(s.__VUE_DEVTOOLS_PLUGINS__=s.__VUE_DEVTOOLS_PLUGINS__||[]).push({pluginDescriptor:n,setupFn:t,proxy:i}),i&&t(i.proxiedTarget)}}/*! - * vuex v4.1.0 - * (c) 2022 Evan You - * @license MIT - */var Cf="store";function Wt(e,t){Object.keys(e).forEach(function(n){return t(e[n],n)})}function ol(e){return e!==null&&typeof e=="object"}function Ef(e){return e&&typeof e.then=="function"}function wf(e,t){return function(){return e(t)}}function il(e,t,n){return t.indexOf(e)<0&&(n&&n.prepend?t.unshift(e):t.push(e)),function(){var s=t.indexOf(e);s>-1&&t.splice(s,1)}}function ll(e,t){e._actions=Object.create(null),e._mutations=Object.create(null),e._wrappedGetters=Object.create(null),e._modulesNamespaceMap=Object.create(null);var n=e.state;as(e,n,[],e._modules.root,!0),Er(e,n,t)}function Er(e,t,n){var s=e._state,r=e._scope;e.getters={},e._makeLocalGettersCache=Object.create(null);var o=e._wrappedGetters,i={},l={},c=Nl(!0);c.run(function(){Wt(o,function(f,u){i[u]=wf(f,e),l[u]=ki(function(){return i[u]()}),Object.defineProperty(e.getters,u,{get:function(){return l[u].value},enumerable:!0})})}),e._state=zn({data:t}),e._scope=c,e.strict&&xf(e),s&&n&&e._withCommit(function(){s.data=null}),r&&r.stop()}function as(e,t,n,s,r){var o=!n.length,i=e._modules.getNamespace(n);if(s.namespaced&&(e._modulesNamespaceMap[i],e._modulesNamespaceMap[i]=s),!o&&!r){var l=wr(t,n.slice(0,-1)),c=n[n.length-1];e._withCommit(function(){l[c]=s.state})}var f=s.context=Af(e,i,n);s.forEachMutation(function(u,d){var g=i+d;Tf(e,g,u,f)}),s.forEachAction(function(u,d){var g=u.root?d:i+d,C=u.handler||u;Of(e,g,C,f)}),s.forEachGetter(function(u,d){var g=i+d;Rf(e,g,u,f)}),s.forEachChild(function(u,d){as(e,t,n.concat(d),u,r)})}function Af(e,t,n){var s=t==="",r={dispatch:s?e.dispatch:function(o,i,l){var c=jn(o,i,l),f=c.payload,u=c.options,d=c.type;return(!u||!u.root)&&(d=t+d),e.dispatch(d,f)},commit:s?e.commit:function(o,i,l){var c=jn(o,i,l),f=c.payload,u=c.options,d=c.type;(!u||!u.root)&&(d=t+d),e.commit(d,f,u)}};return Object.defineProperties(r,{getters:{get:s?function(){return e.getters}:function(){return cl(e,t)}},state:{get:function(){return wr(e.state,n)}}}),r}function cl(e,t){if(!e._makeLocalGettersCache[t]){var n={},s=t.length;Object.keys(e.getters).forEach(function(r){if(r.slice(0,s)===t){var o=r.slice(s);Object.defineProperty(n,o,{get:function(){return e.getters[r]},enumerable:!0})}}),e._makeLocalGettersCache[t]=n}return e._makeLocalGettersCache[t]}function Tf(e,t,n,s){var r=e._mutations[t]||(e._mutations[t]=[]);r.push(function(i){n.call(e,s.state,i)})}function Of(e,t,n,s){var r=e._actions[t]||(e._actions[t]=[]);r.push(function(i){var l=n.call(e,{dispatch:s.dispatch,commit:s.commit,getters:s.getters,state:s.state,rootGetters:e.getters,rootState:e.state},i);return Ef(l)||(l=Promise.resolve(l)),e._devtoolHook?l.catch(function(c){throw e._devtoolHook.emit("vuex:error",c),c}):l})}function Rf(e,t,n,s){e._wrappedGetters[t]||(e._wrappedGetters[t]=function(o){return n(s.state,s.getters,o.state,o.getters)})}function xf(e){nn(function(){return e._state.data},function(){},{deep:!0,flush:"sync"})}function wr(e,t){return t.reduce(function(n,s){return n[s]},e)}function jn(e,t,n){return ol(e)&&e.type&&(n=t,t=e,e=e.type),{type:e,payload:t,options:n}}var Lf="vuex bindings",Po="vuex:mutations",Os="vuex:actions",Nt="vuex",If=0;function Pf(e,t){vf({id:"org.vuejs.vuex",app:e,label:"Vuex",homepage:"https://next.vuex.vuejs.org/",logo:"https://vuejs.org/images/icons/favicon-96x96.png",packageName:"vuex",componentStateTypes:[Lf]},function(n){n.addTimelineLayer({id:Po,label:"Vuex Mutations",color:ko}),n.addTimelineLayer({id:Os,label:"Vuex Actions",color:ko}),n.addInspector({id:Nt,label:"Vuex",icon:"storage",treeFilterPlaceholder:"Filter stores..."}),n.on.getInspectorTree(function(s){if(s.app===e&&s.inspectorId===Nt)if(s.filter){var r=[];dl(r,t._modules.root,s.filter,""),s.rootNodes=r}else s.rootNodes=[fl(t._modules.root,"")]}),n.on.getInspectorState(function(s){if(s.app===e&&s.inspectorId===Nt){var r=s.nodeId;cl(t,r),s.state=Ff(Df(t._modules,r),r==="root"?t.getters:t._makeLocalGettersCache,r)}}),n.on.editInspectorState(function(s){if(s.app===e&&s.inspectorId===Nt){var r=s.nodeId,o=s.path;r!=="root"&&(o=r.split("/").filter(Boolean).concat(o)),t._withCommit(function(){s.set(t._state.data,o,s.state.value)})}}),t.subscribe(function(s,r){var o={};s.payload&&(o.payload=s.payload),o.state=r,n.notifyComponentUpdate(),n.sendInspectorTree(Nt),n.sendInspectorState(Nt),n.addTimelineEvent({layerId:Po,event:{time:Date.now(),title:s.type,data:o}})}),t.subscribeAction({before:function(s,r){var o={};s.payload&&(o.payload=s.payload),s._id=If++,s._time=Date.now(),o.state=r,n.addTimelineEvent({layerId:Os,event:{time:s._time,title:s.type,groupId:s._id,subtitle:"start",data:o}})},after:function(s,r){var o={},i=Date.now()-s._time;o.duration={_custom:{type:"duration",display:i+"ms",tooltip:"Action duration",value:i}},s.payload&&(o.payload=s.payload),o.state=r,n.addTimelineEvent({layerId:Os,event:{time:Date.now(),title:s.type,groupId:s._id,subtitle:"end",data:o}})}})})}var ko=8702998,kf=6710886,Nf=16777215,al={label:"namespaced",textColor:Nf,backgroundColor:kf};function ul(e){return e&&e!=="root"?e.split("/").slice(-2,-1)[0]:"Root"}function fl(e,t){return{id:t||"root",label:ul(t),tags:e.namespaced?[al]:[],children:Object.keys(e._children).map(function(n){return fl(e._children[n],t+n+"/")})}}function dl(e,t,n,s){s.includes(n)&&e.push({id:s||"root",label:s.endsWith("/")?s.slice(0,s.length-1):s||"Root",tags:t.namespaced?[al]:[]}),Object.keys(t._children).forEach(function(r){dl(e,t._children[r],n,s+r+"/")})}function Ff(e,t,n){t=n==="root"?t:t[n];var s=Object.keys(t),r={state:Object.keys(e.state).map(function(i){return{key:i,editable:!0,value:e.state[i]}})};if(s.length){var o=Uf(t);r.getters=Object.keys(o).map(function(i){return{key:i.endsWith("/")?ul(i):i,editable:!1,value:Qs(function(){return o[i]})}})}return r}function Uf(e){var t={};return Object.keys(e).forEach(function(n){var s=n.split("/");if(s.length>1){var r=t,o=s.pop();s.forEach(function(i){r[i]||(r[i]={_custom:{value:{},display:i,tooltip:"Module",abstract:!0}}),r=r[i]._custom.value}),r[o]=Qs(function(){return e[n]})}else t[n]=Qs(function(){return e[n]})}),t}function Df(e,t){var n=t.split("/").filter(function(s){return s});return n.reduce(function(s,r,o){var i=s[r];if(!i)throw new Error('Missing module "'+r+'" for path "'+t+'".');return o===n.length-1?i:i._children},t==="root"?e:e.root._children)}function Qs(e){try{return e()}catch(t){return t}}var De=function(t,n){this.runtime=n,this._children=Object.create(null),this._rawModule=t;var s=t.state;this.state=(typeof s=="function"?s():s)||{}},hl={namespaced:{configurable:!0}};hl.namespaced.get=function(){return!!this._rawModule.namespaced};De.prototype.addChild=function(t,n){this._children[t]=n};De.prototype.removeChild=function(t){delete this._children[t]};De.prototype.getChild=function(t){return this._children[t]};De.prototype.hasChild=function(t){return t in this._children};De.prototype.update=function(t){this._rawModule.namespaced=t.namespaced,t.actions&&(this._rawModule.actions=t.actions),t.mutations&&(this._rawModule.mutations=t.mutations),t.getters&&(this._rawModule.getters=t.getters)};De.prototype.forEachChild=function(t){Wt(this._children,t)};De.prototype.forEachGetter=function(t){this._rawModule.getters&&Wt(this._rawModule.getters,t)};De.prototype.forEachAction=function(t){this._rawModule.actions&&Wt(this._rawModule.actions,t)};De.prototype.forEachMutation=function(t){this._rawModule.mutations&&Wt(this._rawModule.mutations,t)};Object.defineProperties(De.prototype,hl);var Lt=function(t){this.register([],t,!1)};Lt.prototype.get=function(t){return t.reduce(function(n,s){return n.getChild(s)},this.root)};Lt.prototype.getNamespace=function(t){var n=this.root;return t.reduce(function(s,r){return n=n.getChild(r),s+(n.namespaced?r+"/":"")},"")};Lt.prototype.update=function(t){pl([],this.root,t)};Lt.prototype.register=function(t,n,s){var r=this;s===void 0&&(s=!0);var o=new De(n,s);if(t.length===0)this.root=o;else{var i=this.get(t.slice(0,-1));i.addChild(t[t.length-1],o)}n.modules&&Wt(n.modules,function(l,c){r.register(t.concat(c),l,s)})};Lt.prototype.unregister=function(t){var n=this.get(t.slice(0,-1)),s=t[t.length-1],r=n.getChild(s);r&&r.runtime&&n.removeChild(s)};Lt.prototype.isRegistered=function(t){var n=this.get(t.slice(0,-1)),s=t[t.length-1];return n?n.hasChild(s):!1};function pl(e,t,n){if(t.update(n),n.modules)for(var s in n.modules){if(!t.getChild(s))return;pl(e.concat(s),t.getChild(s),n.modules[s])}}function Vf(e){return new Ae(e)}var Ae=function(t){var n=this;t===void 0&&(t={});var s=t.plugins;s===void 0&&(s=[]);var r=t.strict;r===void 0&&(r=!1);var o=t.devtools;this._committing=!1,this._actions=Object.create(null),this._actionSubscribers=[],this._mutations=Object.create(null),this._wrappedGetters=Object.create(null),this._modules=new Lt(t),this._modulesNamespaceMap=Object.create(null),this._subscribers=[],this._makeLocalGettersCache=Object.create(null),this._scope=null,this._devtools=o;var i=this,l=this,c=l.dispatch,f=l.commit;this.dispatch=function(g,C){return c.call(i,g,C)},this.commit=function(g,C,A){return f.call(i,g,C,A)},this.strict=r;var u=this._modules.root.state;as(this,u,[],this._modules.root),Er(this,u),s.forEach(function(d){return d(n)})},Ar={state:{configurable:!0}};Ae.prototype.install=function(t,n){t.provide(n||Cf,this),t.config.globalProperties.$store=this;var s=this._devtools!==void 0?this._devtools:!1;s&&Pf(t,this)};Ar.state.get=function(){return this._state.data};Ar.state.set=function(e){};Ae.prototype.commit=function(t,n,s){var r=this,o=jn(t,n,s),i=o.type,l=o.payload,c={type:i,payload:l},f=this._mutations[i];f&&(this._withCommit(function(){f.forEach(function(d){d(l)})}),this._subscribers.slice().forEach(function(u){return u(c,r.state)}))};Ae.prototype.dispatch=function(t,n){var s=this,r=jn(t,n),o=r.type,i=r.payload,l={type:o,payload:i},c=this._actions[o];if(c){try{this._actionSubscribers.slice().filter(function(u){return u.before}).forEach(function(u){return u.before(l,s.state)})}catch{}var f=c.length>1?Promise.all(c.map(function(u){return u(i)})):c[0](i);return new Promise(function(u,d){f.then(function(g){try{s._actionSubscribers.filter(function(C){return C.after}).forEach(function(C){return C.after(l,s.state)})}catch{}u(g)},function(g){try{s._actionSubscribers.filter(function(C){return C.error}).forEach(function(C){return C.error(l,s.state,g)})}catch{}d(g)})})}};Ae.prototype.subscribe=function(t,n){return il(t,this._subscribers,n)};Ae.prototype.subscribeAction=function(t,n){var s=typeof t=="function"?{before:t}:t;return il(s,this._actionSubscribers,n)};Ae.prototype.watch=function(t,n,s){var r=this;return nn(function(){return t(r.state,r.getters)},n,Object.assign({},s))};Ae.prototype.replaceState=function(t){var n=this;this._withCommit(function(){n._state.data=t})};Ae.prototype.registerModule=function(t,n,s){s===void 0&&(s={}),typeof t=="string"&&(t=[t]),this._modules.register(t,n),as(this,this.state,t,this._modules.get(t),s.preserveState),Er(this,this.state)};Ae.prototype.unregisterModule=function(t){var n=this;typeof t=="string"&&(t=[t]),this._modules.unregister(t),this._withCommit(function(){var s=wr(n.state,t.slice(0,-1));delete s[t[t.length-1]]}),ll(this)};Ae.prototype.hasModule=function(t){return typeof t=="string"&&(t=[t]),this._modules.isRegistered(t)};Ae.prototype.hotUpdate=function(t){this._modules.update(t),ll(this,!0)};Ae.prototype._withCommit=function(t){var n=this._committing;this._committing=!0,t(),this._committing=n};Object.defineProperties(Ae.prototype,Ar);var Ze=gl(function(e,t){var n={};return ml(t).forEach(function(s){var r=s.key,o=s.val;n[r]=function(){var l=this.$store.state,c=this.$store.getters;if(e){var f=_l(this.$store,"mapState",e);if(!f)return;l=f.context.state,c=f.context.getters}return typeof o=="function"?o.call(this,l,c):l[o]},n[r].vuex=!0}),n}),Bf=gl(function(e,t){var n={};return ml(t).forEach(function(s){var r=s.key,o=s.val;n[r]=function(){for(var l=[],c=arguments.length;c--;)l[c]=arguments[c];var f=this.$store.commit;if(e){var u=_l(this.$store,"mapMutations",e);if(!u)return;f=u.context.commit}return typeof o=="function"?o.apply(this,[f].concat(l)):f.apply(this.$store,[o].concat(l))}}),n});function ml(e){return Mf(e)?Array.isArray(e)?e.map(function(t){return{key:t,val:t}}):Object.keys(e).map(function(t){return{key:t,val:e[t]}}):[]}function Mf(e){return Array.isArray(e)||ol(e)}function gl(e){return function(t,n){return typeof t!="string"?(n=t,t=""):t.charAt(t.length-1)!=="/"&&(t+="/"),e(t,n)}}function _l(e,t,n){var s=e._modulesNamespaceMap[n];return s}const et=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},$f={data(){return{artistsArrayList:[],lastClickedItem:null,showDrop:!1}},created(){this.loadList(),U.get("/api/getLastArtist").then(e=>{e.data!==""&&(this.lastClickedItem=e.data)})},computed:{...Ze(["allowButtons","sourceTab","artist"])},watch:{"$store.state.loadListRequest"(e){e&&(this.$store.commit("SET_LOAD_REQUEST",!1),this.loadList())}},methods:{loadList(){U.get("/api/loadList").then(e=>{this.artistsArrayList=e.data}).catch(e=>{console.error(e)})},handleItemClick(e){this.lastClickedItem=e,U.post("/api/listOrTabClick",{item:e,origin:"list"}).then(t=>{this.$store.commit("SET_SELECTED_ARTIST",e),this.$store.commit("SET_TABLE_CONTENT",t.data)}).catch(t=>{console.error(t)})},clickAddArtist(){this.$store.commit("SET_ADD_VIS",!0)},clickDeleteArtist(){this.lastClickedItem!==""&&U.get("/api/clickArtistDelete").then(()=>{this.$store.commit("SET_SELECTED_ARTIST",""),this.$store.commit("SET_SOURCE_TAB","combview"),this.loadList()}).catch(e=>{console.error(e)})},showMore(){this.showDrop=!this.showDrop},deleteUrl(){U.post("/api/deleteUrl").then(()=>{this.handleItemClick(this.lastClickedItem)})}}},jf={class:"buttonspace"},Hf=["disabled"],Kf={key:0,class:"dropdown"},qf=["disabled"],Wf=["disabled"],Gf={class:"artistlist"},zf=["onMousedown"],Jf={class:"listitems"};function Yf(e,t,n,s,r,o){return x(),L(_e,null,[p("div",jf,[p("button",{onMousedown:t[0]||(t[0]=i=>o.clickAddArtist()),class:"addbtn",disabled:!e.allowButtons},"add",40,Hf),p("button",{onClick:t[1]||(t[1]=i=>o.showMore()),class:"morebtn"},"more"),r.showDrop?(x(),L("div",Kf,[p("button",{onClick:t[2]||(t[2]=i=>o.deleteUrl()),disabled:e.sourceTab==null||e.sourceTab=="combview"||e.artist==""||!e.allowButtons,class:"deletebtn"},"delete selected URL",8,qf),p("button",{onClick:t[3]||(t[3]=i=>o.clickDeleteArtist()),disabled:e.artist==""||!e.allowButtons,class:"deletebtn"},"delete artist",8,Wf)])):B("",!0)]),p("div",Gf,[(x(!0),L(_e,null,Ds(r.artistsArrayList,i=>(x(),L("li",{key:i,onMousedown:l=>o.handleItemClick(i),class:Ee([{highlighted:i===r.lastClickedItem},"listbtn"])},[p("div",Jf,ze(i),1)],42,zf))),128)),(x(!0),L(_e,null,Ds(r.artistsArrayList,i=>(x(),L("li",{key:i}))),128))])],64)}const Xf=et($f,[["render",Yf],["__scopeId","data-v-18b2502f"]]),Qf="/assets/optionsblack-vjTCXWXl.png",Zf="/assets/optionsdark-ymr6Vwzk.png",ed="/assets/optionslight-B8QchSUy.png",td="/assets/refreshuniversal-3TIkIW2C.png",nd={data(){return{activeTab:"",eventSource:null,scrapeColor:"var(--accent-color)",scrapeNotice:!1,scrapeLast:"-"}},computed:{...Ze(["sourceTab","allowButtons","primaryColor"])},created(){this.activeTab=this.sourceTab,U.post("/api/fillCombview").catch(e=>{console.error(e)}).then(()=>{this.sourceTab===""?this.setStoreTab("combview"):this.handleSourceClick(this.sourceTab)}),U.get("/api/getScrapeDate").then(e=>{this.scrapeLast=e.data})},watch:{sourceTab(e){this.activeTab=e,e&&this.handleSourceClick(e)}},methods:{setStoreTab(e){this.$store.commit("SET_SOURCE_TAB",e)},handleSourceClick(e){U.post("/api/listOrTabClick",{item:e,origin:"tab"}).then(t=>{this.$store.commit("SET_TABLE_CONTENT",t.data)}).catch(t=>{console.error(t)})},clickScrape(){this.allowButtons?(this.$store.commit("SET_ALLOW_BUTTONS",!1),this.scrapeColor="var(--dull-color)",this.eventSource=new EventSource("/progress"),this.eventSource.onmessage=t=>{const n=parseFloat(t.data);this.$store.commit("SET_PROGRESS",n)},U.post("/api/clickScrape").then(()=>{this.scrapeColor="var(--accent-color)",this.$store.commit("SET_ALLOW_BUTTONS",!0),this.eventSource.close();let t=new Date().toLocaleString("en-GB",{day:"2-digit",month:"2-digit",hour:"2-digit",minute:"2-digit"}).replace(/\//g,".").replace(",","").replace(/(\d{2})\.(\d{2})/,"$1.$2.");this.scrapeLast=t,this.scrapeNotice=!0,this.handleSourceClick("combview"),U.post("/api/setSetting",{name:"lastScrape",value:t}).catch(n=>{console.error(n)})})):U.post("/api/cancelScrape").then(()=>{this.$store.commit("SET_ALLOW_BUTTONS",!0),this.scrapeColor="var(--accent-color)"})},scrapeHover(){this.scrapeNotice=!0},scrapeMouseOff(){this.scrapeNotice=!1},openSettings(){this.$store.commit("SET_SETTINGS_OPEN",!0)}}},sd=e=>(Ht("data-v-671de189"),e=e(),Kt(),e),rd={class:"wrapper"},od={class:"tabs"},id=["disabled"],ld={key:0,class:"image",src:Qf,alt:"Settings"},cd={key:1,class:"image",src:Zf,alt:"Settings"},ad={key:2,class:"image",src:ed,alt:"Settings"},ud=sd(()=>p("img",{class:"image",src:td,alt:"Refresh"},null,-1)),fd=[ud];function dd(e,t,n,s,r,o){return x(),L("div",rd,[p("div",od,[p("div",{onMousedown:t[0]||(t[0]=i=>o.setStoreTab("combview")),class:Ee([{active:r.activeTab==="combview"},"cvtab"])},"Combined view",34),p("div",{onMousedown:t[1]||(t[1]=i=>o.setStoreTab("beatport")),class:Ee([{active:r.activeTab==="beatport"},"stab"])},"BP",34),p("div",{onMousedown:t[2]||(t[2]=i=>o.setStoreTab("musicbrainz")),class:Ee([{active:r.activeTab==="musicbrainz"},"stab"])},"MB",34),p("div",{onMousedown:t[3]||(t[3]=i=>o.setStoreTab("junodownload")),class:Ee([{active:r.activeTab==="junodownload"},"stab"])},"JD",34),p("div",{onMousedown:t[4]||(t[4]=i=>o.setStoreTab("youtube")),class:Ee([{active:r.activeTab==="youtube"},"stab"])},"YT",34)]),p("button",{onClick:t[5]||(t[5]=i=>o.openSettings()),class:"imgbutton1",disabled:!e.allowButtons},[e.primaryColor==="Black"?(x(),L("img",ld)):e.primaryColor==="Dark"?(x(),L("img",cd)):e.primaryColor==="Light"?(x(),L("img",ad)):B("",!0)],8,id),p("button",{onClick:t[6]||(t[6]=i=>o.clickScrape()),onMouseover:t[7]||(t[7]=i=>o.scrapeHover()),onMouseleave:t[8]||(t[8]=i=>o.scrapeMouseOff()),style:pn({"background-color":r.scrapeColor}),class:"imgbutton2"},fd,36),le(gr,{name:"fade"},{default:ai(()=>[r.scrapeNotice?(x(),L("div",{key:0,class:"scrapenotice",onMouseover:t[9]||(t[9]=i=>o.scrapeMouseOff())},[p("p",null,"Last scrape: "+ze(r.scrapeLast),1)],32)):B("",!0)]),_:1})])}const hd=et(nd,[["render",dd],["__scopeId","data-v-671de189"]]),pd={mounted(){this.isDateInFuture},computed:{...Ze(["tableData","previewVis","artist","isoDates","sourceTab","urlExists"]),hideArtistColumn(){return this.tableData.some(e=>e.artist===null)},hideTable(){return this.tableData.some(e=>e.song!==null)}},methods:{isDateInFuture(e){return new Date(e)>new Date},formatDate(e){if(this.isoDates)return e;{const t=new Date(e),n=t.getDate(),s=t.getMonth()+1,r=t.getFullYear();return`${n}. ${s}. ${r}`}}}},bn=e=>(Ht("data-v-19adbfff"),e=e(),Kt(),e),md={key:0,class:"table-container"},gd={class:"table-header"},_d=bn(()=>p("th",{class:"song"},"song",-1)),bd={key:0,class:"artist"},yd=bn(()=>p("th",{class:"date"},"date",-1)),Sd={class:"table-body"},vd=bn(()=>p("td",null,[p("br")],-1)),Cd={class:"tdsong"},Ed={key:0,class:"tdartist"},wd={class:"tddate"},Ad={key:1,class:"emptynotice"},Td=bn(()=>p("p",null,"table empty",-1)),Od=[Td],Rd={key:2,class:"quickstart"},xd=bn(()=>p("p",null,[p("span",{class:"title"},"Quickstart guide"),pe(),p("br"),pe(' 1. click "add" to add an artist, select the artist '),p("br"),pe(" 2. click on any BP / MB / JD / YT button at the top to select a source "),p("br"),pe(" 3. find the artist on the website, copy & paste the link or ID "),p("br"),pe(" 4. to scrape, click refresh button in the top right corner "),p("br")],-1)),Ld=[xd];function Id(e,t,n,s,r,o){return x(),L(_e,null,[o.hideTable?(x(),L("div",md,[p("div",gd,[p("table",null,[p("tr",null,[_d,o.hideArtistColumn?B("",!0):(x(),L("th",bd,"artist")),yd])])]),p("div",Sd,[p("table",null,[p("tbody",null,[vd,(x(!0),L(_e,null,Ds(e.tableData,(i,l)=>(x(),L("tr",{key:l,class:Ee({"future-date":o.isDateInFuture(i.date)})},[p("td",Cd,ze(i.song),1),o.hideArtistColumn?B("",!0):(x(),L("td",Ed,ze(i.artist),1)),p("td",wd,ze(o.formatDate(i.date)),1)],2))),128))])])])])):B("",!0),e.urlExists&&!o.hideTable&&!e.previewVis&&e.sourceTab!=="combview"?(x(),L("div",Ad,Od)):B("",!0),!e.urlExists&&!o.hideTable&&!e.previewVis&&e.sourceTab==="combview"?(x(),L("div",Rd,Ld)):B("",!0)],64)}const Pd=et(pd,[["render",Id],["__scopeId","data-v-19adbfff"]]),Gt="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAACXBIWXMAAAYCAAAGAgHyxpylAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAABwpJREFUeJzt3UmMFGUYh/FnlBiNGxITTbjoRQ+elBAFObpePLmgLAm7u8ywyQ7KIsuwGRdgALeIaDx4cDfRRGKMRr0YE2+Y6MEtosZoXGgP73ScNDD2VL1vfbX8fxcCTH1dyTz5uqq66uueVquFiLdTUu+A1JPCkhAKS0IoLAmhsCSEwpIQCktCKCwJobAkhMKSEApLQigsCaGwJITCkhAKS0IoLAmhsCSEwpIQCktCKCwJobAkhMKSEApLQigsCaGwJITCkhAKS0IoLAmhsCSEwpIQo1LvgCR1KTABuAD4CjgMfO0xsMJqpsuBXcCkjn8/BrwC9GKhZdajhdca5xbgGeD0YX7mR+Ba4LOsL6KwmuU24Dm6e6f6BrgM+DnLC+ngvTkm031UAGOBhVlfTDNWM0wGnmXkx9RHgIuzvKDCqr/bsahOzbj9GOCnkW6kt8J6u4N8UQGckWUjhVVfU7CzvzxR/QH8kGVDhVVPU4GnyRcVwHvAn1k2VFj1Mw14ivxRAfRn3VBh1ct04AA+UT0GvJN1Y50V1sd0YD8+UT0/ON4/WQdQWPWQ95LCUC9iB/5/5xlEb4XVNwO7ou4R1SEcogKFVXUzgAF8fo+HsLPJ3FGBwqqymfhF9QKOUYHCqqqZwF78opqGY1SgG/2qyDuqqeQ4+zsZzVjVMgu/qA4SFBUorCqZBezB53d2gMCoQGFVxWx8o5qN3d8eRmGV32xgNz6/q/0UEBUorLKbg29UcyggKlBYZTYHeJIKRgUKq6w8Z6p9FBwVKKwymotF1eMw1r7B8QqNChRW2czF3v48ohogUVSgsMpkHr5RzSNRVKCwymIe8AQ+Ue0lcVSgsMrgTnyjupPEUYHCSm0+8Dg1mqnaFFY684Ht+ES1B4uqNPeZK6w0erGoPOzB3v5KExUorBR6gW1OY+2mhFGBwipaH75R3UUJowKFVaQ+cjxZ3GEHJY4KFFZRFuAbVS8ljgoUVhEWAFudxtqORVV6CivWQnyj6nMaK5zCirMQ2OI01jYqFBUorCiL8I1qgdNYhVFY/hYBm53G6qeCUYHC8rYY36gyL4edmsLysxjY5DTWViocFSgsL0vwjWqR01jJKKz8lgCPOI21hRpEBcUvCjIKuBK4ZPDvXwIf4bzSSYG8o1rsNFZyRYV1GnZ20wec3/F/32MHqtuAvwraHw9rgNVOY23GIq2NItYgHQ28Ckz8n587DNxEhq/XSGANimpY0WH1AG8B13T5859g35NX5rjWAqucxtoEPOg0VqlEH7xPofuoAMYBbwPnxexOboqqS9Fh3Zthm3HYLDfaeV/yeghF1bXIt8KzgKNkXyb6Y+C6wTFSexhY4TTWGmzmq7XIGetC8q09Pp5yzFyKKoPIsH53GGM88CZwrsNYWazDL6rVNCQqiH0r7AG+4/jrVll8ip0EFHm2uA5Y7jTWauwYrTEiZ6wW8LLTWFcAr1PczLUev6hW0bCoIP461kXA58CZTuN9CFwP/OI03omsB5Y5jbUKO0ZrnOjLDUewZaS91hO4CngDOMdpvE4b8ItqJQ2NCoq5u+EQvksVTiAmrg3AUqexVmLHaI1V1G0z+/FdXa4d19lO423EL6oVNDwqKPZ+LO/1ML3i2ojfVfAV2DFa46X4hlXPBfEBPgBuAH4d4XY92LN6Dzjtx3Ls7VRIcwep9/qYE7FLESOZuRRVsFS3Jg/gu/zO1XQfVw+2/oFXVMtQVMdJec97e2nDIuNqR3W/02suw47RpEPqhyki4noNu7OiUw+wE7+olqKoTip1WPDfSr9ecU3CZq6hcbWjus/pNZbi9xBFLaU4KzwZz29lALuH/kbgN2AX2W467NTClhHa6TBWrZUpLPBdSB/gfeCLwXHzUlQjULawwM7WvJap9tLCls/elXpHqqIMx1iddlKutaAUVQZFPwndrR2Df3qthZ5VC5tBH028H5VTxhmrbQdpZy5FlUOZwwKbsVIsktHCziIVVUZlDwtsWZ8iF8toAfdgX54kGVUhLLCVWIpY36AF3I1d8pAcyni5YTiea6Z3amHf9rA7aPxGqcqM1daP352eQ7Wwj5UUlZOqhQX2GZ3XAw9g94XNw76eTZxUMSywuwo8nvtrR7XXYSwZoqphgd1cl+fx92PYB98DPrsjQ1U5LLAHF1Zm3HYu9oCHBKh6WGCPWo30wdC1KKpQVbvcMJx+uvsIqP19fxKoTmEB3IxdMhhzgv87il38PFjoHjVU3cJqmwTcCowFvgVeAt5NukcNU9ewJLE6HLxLCSksCaGwJITCkhAKS0IoLAmhsCSEwpIQCktCKCwJobAkhMKSEApLQigsCaGwJITCkhAKS0IoLAmhsCSEwpIQCktCKCwJobAkhMKSEApLQigsCaGwJITCkhAKS0IoLAnxL3WBYWyxSXBfAAAAAElFTkSuQmCC",zt="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAACXBIWXMAAAYCAAAGAgHyxpylAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAABw9JREFUeJzt3cmrHFUUx/HvcULBIbpRcKMbXbhSUBHc6l/gbBTU5MUJNM6zRo1Gk5gYccjkjCMuXIkDKjiigjvBnYIKThhBUETfcVH1NDxMeK/6nLq3qn9fqE1e+tbtqg/1uvt13zZ3R6no9ig9ATXOBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEp7lZ6AKpeZHQ2cBBwKfA287+7fhIyt9bGmLzM7FtgEnDzvR7PAq8BKd/96on0I1nRlZqcDTwP77ua//Qyc4u6fd96PYE1PZnYm8CwLewj0LXCMu//aZV968D4lmdlZLBwVwOHANZ33pyvW+GtRPcPin6x95e5HdtqnYI07MzubBtWeHYc4xN1/WeyN9KtwxJnZOUyGCmC/LjcSrJFmZufSPPubBNUfwE9dbihYI8zMlgJPMRkqgHfd/c8uNxSskWVm5wFPMjkqgPVdbyhYI8rMzgeeIAbVw+7+Vue56FnhOGpRPU4MqueA8939787zEazhF/CSws69BJzr7n9NMoh+FQ48M7uA5hX1CFQvEoAKBGvQtai2EXMeXwSWRqACwRpsZnYhcaheIBAVCNYga1FtJQ7VeZGoQO8gHVwJqJZO8uxvV+mKNaDM7CLiUD1PEioQrMHUotpCzDl7gkRUIFiDyMyWEYtqmbvPBoy1ywSr8lpUm4k5V4/TAyoQrKozs+XEolreByoQrGprUT3GAFGBYFVZ8JVqOz2jAsGqLjOboUFlAcNtB2b6RgWCVVUtqseIQbWNQqhAsKrJzFYQi2pFKVQgWFXUonqUGFRbKYwKBKt4ZnYxsaguLo0KBKtoZnYl8AgjulLNJViFalFtIAbVFhpU1bzPXLAKZGYraVBFtIXm1181qECweq9F9UDQcJupEBUIVq+Z2VXEorqkRlQgWL3Vour8yeJ5baRiVKC3JveSmV0NrAsabqO7rwwaKy1dsZILRrVhCKhAsFIzs2uIRXVV0FjpCVZSLaq1QcM9MCRUIFgpmdm1xKK6Omis3hKs4FpU9wcNt36IqECwQjOz64hF1Xk57NIJVlAtqvuChls3ZFQgWCGZ2fXEoro2aKxiCdaEtajWBA23dgyooOdX3s1sL+BE4Kj2n74EPole6aSvElBdFzRW+dw9fQP2AW4EfgR83vYDcD2wdx9zCbxPd/zPfem63Vf6/oQfnx5OwBLggwUc3PeAg0sfEKEaACyad0e+uYiD/FntuIBVgajWlL4/Q4W1tMPBrhaXUNUD6+OOB/1TYEnpgzPvvtwpVAvf0tZ5N7P9gR10Xyb6U+BUd98RN6tumdldwC1Bw93h7quCxqq2zNexDmOytcePB94wsyVB8+mUUHUrE9bvAWMcD7xuZgcFjLXozOxu4lDdPi2oIBfWd3T8rrt5nQC8bWYHB4y14FpUNwcNd7u73xk01iBKg+XNg7dXgoY7DnitryuXma0mDtVt04YKSH9WeATwG3HPpj4CDkye8+rA+d5a+tlZqS1/B3Am8HfgyfowCxdwT+A8byl9ckcNqz1hF9aOS6gGCKs9cRcl4DogaG73Bs7r5tIntYat353F4/pgUlxCNQJY7YlcVgMumj+Qbwycx02lT2ZNW5mdxuN6fzG4hGqksNqTuxyY7RtXi+rBwP3eWPok1riV3XnPuIRqSmAl4XoP2H8XqDYF7ueG0seu5q34BNqTPpOJS6imFFYmrhbVQ0FjzgJXlD5WQ9jS3ujXpeCF9KHB9QWwImAsB1a6+4MBY42+qmABmNkVxC1THZUDV7r7ptITGUrVfRK6vSLUtBaUUHWoOlgA7r4RqGFJRKd5TCVUi6xKWPAvrpJXrjlUDxWcw2CrFhaAu28ASiyS4cDlQtW9qmEBuPs6oM/FMhy4zN0f6XGfo6t6WADuvpZm4ZD0XQGXuvujPexr1FX3csPuCl4zfX5O820Pm5PGn6oGccWay93X0yyHFD40zZcdCVVQg4IF4O5rgJsCh5yl+a6/LYFjTn2DgwXg7vcS87m/OVRbA8ZSOzVIWADufg+Tffx9Fphx921BU1I7NVhYAO6+Gri1481n3H175HzUfw0aFoC73w3ctcibrRKq3Ab1csPuMrP1LOxPQIP4vr+hNxpYAGZ2Gs1X2h7yPz/eQfPi5/P9zmo6GxWsuczsZOAM4HDge+Bld3+n7Kymq1HCUuUb/IN3VWeCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqpX8Abns5VFEOJoIAAAAASUVORK5CYII=",kd={data:()=>({input:""}),computed:{...Ze(["tableData","sourceTab","allowButtons","artist","addDialogVis","primaryColor","urlExists"])},watch:{tableData(){this.determineDiagShow()}},methods:{clickURL(){const e=encodeURIComponent(this.input);this.input="",e&&U.post("/api/clickAddURL",e).then(()=>{const t=this.artist;U.post("/api/listOrTabClick",{item:t,origin:"list"}).then(n=>{this.$store.commit("SET_TABLE_CONTENT",n.data),this.$store.commit("SET_PREVIEW_VIS",!0)})}).catch(t=>{console.error(t)})},determineDiagShow(){this.tableData.length===0?U.get("/api/checkExistURL").then(e=>{this.$store.commit("SET_URL_EXISTS",e.data)}).catch(e=>{console.error(e)}):this.$store.commit("SET_URL_EXISTS",!0)}}},ae=e=>(Ht("data-v-0fe96286"),e=e(),Kt(),e),Nd={key:0},Fd={key:0,class:"dialog"},Ud=ae(()=>p("h1",null,"MusicBrainz source",-1)),Dd={class:"artist"},Vd=ae(()=>p("p",null,[p("a",{href:"https://musicbrainz.org",target:"_blank"},"https://musicbrainz.org"),pe(" > find artist > copy URL")],-1)),Bd=ae(()=>p("br",null,null,-1)),Md=ae(()=>p("p",null,"Example link:",-1)),$d=ae(()=>p("p",null,[pe("https://musicbrainz.org/artist/"),p("span",{class:"variabletext"},"id/...")],-1)),jd={key:0,class:"image",src:Gt,alt:"OK"},Hd={key:1,class:"image",src:zt,alt:"OK"},Kd={key:1,class:"dialog"},qd=ae(()=>p("h1",null,"Beatport source",-1)),Wd={class:"artist"},Gd=ae(()=>p("p",null,[p("a",{href:"https://beatport.com",target:"_blank"},"https://beatport.com"),pe(" > find artist > copy URL")],-1)),zd=ae(()=>p("br",null,null,-1)),Jd=ae(()=>p("p",null,"Example link:",-1)),Yd=ae(()=>p("p",null,[pe("https://beatport.com/artist/"),p("span",{class:"variabletext"},"artistname/id/...")],-1)),Xd={key:0,class:"image",src:Gt,alt:"OK"},Qd={key:1,class:"image",src:zt,alt:"OK"},Zd={key:2,class:"dialog"},eh=ae(()=>p("h1",null,"Junodownload source",-1)),th={class:"artist"},nh=ae(()=>p("p",null,[p("a",{href:"https://junodownload.com",target:"_blank"},"https://junodownload.com"),pe(" > find artist > copy URL")],-1)),sh=ae(()=>p("br",null,null,-1)),rh=ae(()=>p("p",null,"Example link:",-1)),oh=ae(()=>p("p",null,[pe("https://junodownload.com/artists/"),p("span",{class:"variabletext"},"artistname/...")],-1)),ih={key:0,class:"image",src:Gt,alt:"OK"},lh={key:1,class:"image",src:zt,alt:"OK"},ch={key:3,class:"dialog"},ah=ae(()=>p("h1",null,"Youtube source",-1)),uh={class:"artist"},fh=ae(()=>p("p",null,[p("a",{href:"https://youtube.com",target:"_blank"},"https://youtube.com")],-1)),dh=ae(()=>p("p",null,[pe(' Find an auto-generated channel with "Topic" in its name. '),p("br"),pe("Obtain the ID (share > copy channel ID) or copy URL. "),p("br"),pe("An ID needs to be provided, not a channel handle. ")],-1)),hh=ae(()=>p("p",null,"Example link:",-1)),ph=ae(()=>p("p",null,[pe("https://youtube.com/channel/"),p("span",{class:"variabletext"},"UCwZEU0wAwIyZb...")],-1)),mh={key:0,class:"image",src:Gt,alt:"OK"},gh={key:1,class:"image",src:zt,alt:"OK"};function _h(e,t,n,s,r,o){return!e.urlExists&&e.allowButtons&&e.artist&&!e.addDialogVis?(x(),L("div",Nd,[e.sourceTab==="musicbrainz"?(x(),L("div",Fd,[Ud,p("p",Dd,ze(e.artist),1),Vd,Bd,Md,$d,ie(p("input",{"onUpdate:modelValue":t[0]||(t[0]=i=>e.input=i)},null,512),[[en,e.input]]),p("button",{onClick:t[1]||(t[1]=(...i)=>o.clickURL&&o.clickURL(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",jd)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Hd)):B("",!0)])])):e.sourceTab==="beatport"?(x(),L("div",Kd,[qd,p("p",Wd,ze(e.artist),1),Gd,zd,Jd,Yd,ie(p("input",{"onUpdate:modelValue":t[2]||(t[2]=i=>e.input=i)},null,512),[[en,e.input]]),p("button",{onClick:t[3]||(t[3]=(...i)=>o.clickURL&&o.clickURL(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",Xd)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Qd)):B("",!0)])])):e.sourceTab==="junodownload"?(x(),L("div",Zd,[eh,p("p",th,ze(e.artist),1),nh,sh,rh,oh,ie(p("input",{"onUpdate:modelValue":t[4]||(t[4]=i=>e.input=i)},null,512),[[en,e.input]]),p("button",{onClick:t[5]||(t[5]=(...i)=>o.clickURL&&o.clickURL(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",ih)):B("",!0),e.primaryColor==="Light"?(x(),L("img",lh)):B("",!0)])])):e.sourceTab==="youtube"?(x(),L("div",ch,[ah,p("p",uh,ze(e.artist),1),fh,dh,hh,ph,ie(p("input",{"onUpdate:modelValue":t[6]||(t[6]=i=>e.input=i)},null,512),[[en,e.input]]),p("button",{onClick:t[7]||(t[7]=(...i)=>o.clickURL&&o.clickURL(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",mh)):B("",!0),e.primaryColor==="Light"?(x(),L("img",gh)):B("",!0)])])):B("",!0)])):B("",!0)}const bh=et(kd,[["render",_h],["__scopeId","data-v-0fe96286"]]),Tr="/assets/crossdark-CYntds6r.png",Or="/assets/crosslight-CRspF710.png",yh={data:()=>({input:"",rules:[e=>!!e.trim(),e=>(e||"").length<=25]}),computed:{...Ze(["addDialogVis","primaryColor"]),isValid(){return this.rules.every(e=>e(this.input)===!0)}},methods:{clickAdd(){const e=encodeURIComponent(this.input);U.post("/api/clickArtistAdd",e).then(()=>{this.input="",this.$store.commit("SET_SELECTED_ARTIST",""),this.$store.commit("SET_ADD_VIS",!1),this.$store.commit("SET_LOAD_REQUEST",!0)}).catch(t=>{console.error(t)})},clickClose(){this.$store.commit("SET_ADD_VIS",!1)}}},Sh=e=>(Ht("data-v-cb695d37"),e=e(),Kt(),e),vh={key:0,class:"wrapper"},Ch=Sh(()=>p("div",{class:"card-text"},[p("p",{class:"text--primary"},"Type artist's name and confirm.")],-1)),Eh={class:"diag-actions"},wh={key:0,class:"image",src:Tr,alt:"X"},Ah={key:1,class:"image",src:Or,alt:"X"},Th=["disabled"],Oh={key:0,class:"image",src:Gt,alt:"OK"},Rh={key:1,class:"image",src:zt,alt:"OK"};function xh(e,t,n,s,r,o){return e.addDialogVis?(x(),L("div",vh,[Ch,p("div",Eh,[ie(p("input",{"onUpdate:modelValue":t[0]||(t[0]=i=>e.input=i),class:Ee({invalid:!o.isValid})},null,2),[[en,e.input]]),p("button",{onClick:t[1]||(t[1]=(...i)=>o.clickClose&&o.clickClose(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",wh)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Ah)):B("",!0)]),p("button",{onClick:t[2]||(t[2]=(...i)=>o.clickAdd&&o.clickAdd(...i)),class:"imgbutton",disabled:!o.isValid},[e.primaryColor!=="Light"?(x(),L("img",Oh)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Rh)):B("",!0)],8,Th)])])):B("",!0)}const Lh=et(yh,[["render",xh],["__scopeId","data-v-cb695d37"]]),Ih={computed:{...Ze(["progress"])},methods:{...Bf(["setProgress"])}},Ph={class:"progress-container"};function kh(e,t,n,s,r,o){return x(),L("div",Ph,[p("div",{class:"progressbar",style:pn({width:`${e.progress}%`})},null,4)])}const Nh=et(Ih,[["render",kh],["__scopeId","data-v-d29e2d3a"]]),Fh="/assets/blcktext-QjjfTEs8.png",Uh="/assets/MRTlogo-BpL2l-3G.png",Dh={data(){return{theme:"",accent:"",settingsProtection:!0,dbProtection:!0,filters:{Remix:!1,VIP:!1,Instrumental:!1,Acoustic:!1,Extended:!1,Remaster:!1},theme:{Black:!1,Dark:!1,Light:!1},isoDates:!1,autoTheme:!1}},computed:{...Ze(["primaryColor","accentColor"])},created(){U.get("/api/settingsOpened").then(e=>{this.filters=e.data,this.isoDates=e.data.isoDates,this.autoTheme=e.data.autoTheme}).catch(e=>{console.error(e)}),this.theme=this.primaryColor,this.accent=this.accentColor},methods:{clickClose(){this.$store.commit("SET_SETTINGS_OPEN",!1)},setSetting(e,t){switch(e){case"theme":this.$store.commit("SET_PRIMARY_COLOR",this.theme);case"accent":this.$store.commit("SET_ACCENT_COLOR",this.accent);case"isoDates":this.$store.commit("SET_ISODATES",this.isoDates)}U.post("/api/setSetting",{name:e,value:t}).catch(n=>{console.error(n)})},resetSettings(){this.settingsProtection==!0?this.settingsProtection=!1:U.post("/api/resetSettings").then(()=>{this.clickClose()}).catch(e=>{console.error(e)})},resetDB(){this.dbProtection==!0?this.dbProtection=!1:U.post("/api/resetDB").then(()=>{this.clickClose()}).catch(e=>{console.error(e)})},resetProtection(){this.settingsProtection=!0,this.dbProtection=!0}}},ue=e=>(Ht("data-v-6b545924"),e=e(),Kt(),e),Vh={class:"settings"},Bh={key:0,class:"image",src:Tr,alt:"X"},Mh={key:1,class:"image",src:Or,alt:"X"},$h={class:"filterscont"},jh=ue(()=>p("p",null,[p("span",{class:"title"},"Exclusion filters"),p("br"),pe("Select types of songs to be hidden in Combined view.")],-1)),Hh={class:"filters-buttons"},Kh=ue(()=>p("label",null,"Remix",-1)),qh=ue(()=>p("label",null,"VIP",-1)),Wh=ue(()=>p("label",null,"Instrumental",-1)),Gh=ue(()=>p("label",null,"Acoustic",-1)),zh=ue(()=>p("label",null,"Extended",-1)),Jh=ue(()=>p("label",null,"Remaster",-1)),Yh={class:"appearance"},Xh=ue(()=>p("p",{class:"title"},"Appearance",-1)),Qh={class:"appearancecont"},Zh={class:"theme-buttons"},ep=["disabled"],tp=["disabled"],np=["disabled"],sp=ue(()=>p("div",{class:"colorindicator"},null,-1)),rp={class:"accent-buttons"},op=ue(()=>p("label",null,"Lavender",-1)),ip=ue(()=>p("label",null,"Cactus",-1)),lp=ue(()=>p("label",null,"Rose",-1)),cp=ue(()=>p("label",null,"Warm",-1)),ap=ue(()=>p("label",null,"Cloud",-1)),up=ue(()=>p("label",null,"Ocean",-1)),fp={class:"belowAppearance"},dp=ue(()=>p("label",null,"Match system theme",-1)),hp={class:"other"},pp=ue(()=>p("p",{class:"title"},"Other",-1)),mp={class:"flex-items"},gp={class:"flex-padding"},_p=ue(()=>p("label",null,"Dates in yyyy-MM-dd (ISO 8601)",-1)),bp={class:"danger"},yp=ue(()=>p("p",{class:"title"},"Danger zone",-1)),Sp={class:"dangercont"},vp=ia('
logologo
',1);function Cp(e,t,n,s,r,o){return x(),L("div",Vh,[p("button",{onClick:t[0]||(t[0]=i=>o.clickClose()),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",Bh)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Mh)):B("",!0)]),p("section",$h,[jh,p("div",Hh,[p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[1]||(t[1]=i=>r.filters.Remix=i),onChange:t[2]||(t[2]=i=>o.setSetting("filters.Remix",i.target.checked))},null,544),[[ot,r.filters.Remix]]),Kh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[3]||(t[3]=i=>r.filters.VIP=i),onChange:t[4]||(t[4]=i=>o.setSetting("filters.VIP",i.target.checked))},null,544),[[ot,r.filters.VIP]]),qh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[5]||(t[5]=i=>r.filters.Instrumental=i),onChange:t[6]||(t[6]=i=>o.setSetting("filters.Instrumental",i.target.checked))},null,544),[[ot,r.filters.Instrumental]]),Wh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[7]||(t[7]=i=>r.filters.Acoustic=i),onChange:t[8]||(t[8]=i=>o.setSetting("filters.Acoustic",i.target.checked))},null,544),[[ot,r.filters.Acoustic]]),Gh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[9]||(t[9]=i=>r.filters.Extended=i),onChange:t[10]||(t[10]=i=>o.setSetting("filters.Extended",i.target.checked))},null,544),[[ot,r.filters.Extended]]),zh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[11]||(t[11]=i=>r.filters.Remaster=i),onChange:t[12]||(t[12]=i=>o.setSetting("filters.Remaster",i.target.checked))},null,544),[[ot,r.filters.Remaster]]),Jh])])]),p("section",Yh,[Xh,p("div",Qh,[p("div",Zh,[ie(p("input",{type:"radio","onUpdate:modelValue":t[13]||(t[13]=i=>r.theme=i),value:"Black",onChange:t[14]||(t[14]=i=>o.setSetting("theme","Black")),disabled:r.autoTheme},null,40,ep),[[Ge,r.theme]]),p("label",{class:Ee({disabled:r.autoTheme})},"Black",2),ie(p("input",{type:"radio","onUpdate:modelValue":t[15]||(t[15]=i=>r.theme=i),value:"Dark",onChange:t[16]||(t[16]=i=>o.setSetting("theme","Dark")),disabled:r.autoTheme},null,40,tp),[[Ge,r.theme]]),p("label",{class:Ee({disabled:r.autoTheme})},"Dark",2),ie(p("input",{type:"radio","onUpdate:modelValue":t[17]||(t[17]=i=>r.theme=i),value:"Light",onChange:t[18]||(t[18]=i=>o.setSetting("theme","Light")),disabled:r.autoTheme},null,40,np),[[Ge,r.theme]]),p("label",{class:Ee({disabled:r.autoTheme})},"Light",2),sp]),p("div",rp,[ie(p("input",{type:"radio","onUpdate:modelValue":t[19]||(t[19]=i=>r.accent=i),value:"Lavender",onChange:t[20]||(t[20]=i=>o.setSetting("accent","Lavender"))},null,544),[[Ge,r.accent]]),op,ie(p("input",{type:"radio","onUpdate:modelValue":t[21]||(t[21]=i=>r.accent=i),value:"Cactus",onChange:t[22]||(t[22]=i=>o.setSetting("accent","Cactus"))},null,544),[[Ge,r.accent]]),ip,ie(p("input",{type:"radio","onUpdate:modelValue":t[23]||(t[23]=i=>r.accent=i),value:"Rose",onChange:t[24]||(t[24]=i=>o.setSetting("accent","Rose"))},null,544),[[Ge,r.accent]]),lp,ie(p("input",{type:"radio","onUpdate:modelValue":t[25]||(t[25]=i=>r.accent=i),value:"Warm",onChange:t[26]||(t[26]=i=>o.setSetting("accent","Warm"))},null,544),[[Ge,r.accent]]),cp,ie(p("input",{type:"radio","onUpdate:modelValue":t[27]||(t[27]=i=>r.accent=i),value:"Cloud",onChange:t[28]||(t[28]=i=>o.setSetting("accent","Cloud"))},null,544),[[Ge,r.accent]]),ap,ie(p("input",{type:"radio","onUpdate:modelValue":t[29]||(t[29]=i=>r.accent=i),value:"Ocean",onChange:t[30]||(t[30]=i=>o.setSetting("accent","Ocean"))},null,544),[[Ge,r.accent]]),up])]),p("div",fp,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[31]||(t[31]=i=>r.autoTheme=i),onChange:t[32]||(t[32]=i=>o.setSetting("autoTheme",i.target.checked))},null,544),[[ot,r.autoTheme]]),dp])]),p("section",hp,[pp,p("div",mp,[p("div",gp,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[33]||(t[33]=i=>r.isoDates=i),onChange:t[34]||(t[34]=i=>o.setSetting("isoDates",i.target.checked))},null,544),[[ot,r.isoDates]]),_p])])]),p("section",bp,[yp,p("div",Sp,[r.settingsProtection?(x(),L("button",{key:0,onClick:t[35]||(t[35]=i=>o.resetSettings())},"Reset settings")):B("",!0),r.settingsProtection?B("",!0):(x(),L("button",{key:1,onClick:t[36]||(t[36]=i=>o.resetSettings()),onMouseleave:t[37]||(t[37]=i=>o.resetProtection())},"confirm",32)),r.dbProtection?(x(),L("button",{key:2,onClick:t[38]||(t[38]=i=>o.resetDB())},"Reset database")):B("",!0),r.dbProtection?B("",!0):(x(),L("button",{key:3,onClick:t[39]||(t[39]=i=>o.resetDB()),onMouseleave:t[40]||(t[40]=i=>o.resetProtection())},"confirm",32))])]),vp])}const Ep=et(Dh,[["render",Cp],["__scopeId","data-v-6b545924"]]),wp={computed:{...Ze(["tableData","primaryColor"]),hideTable(){return this.tableData.length==0}},methods:{clickCancel(){U.request("/api/cleanArtistSource").catch(e=>{console.error(e)}),this.$store.commit("SET_PREVIEW_VIS",!1)},clickConfirm(){U.request("/api/saveUrl").catch(e=>{console.error(e)}),this.$store.commit("SET_PREVIEW_VIS",!1)}}},Ap=e=>(Ht("data-v-85018fb6"),e=e(),Kt(),e),Tp={class:"preview"},Op=Ap(()=>p("h1",null,"preview",-1)),Rp={key:0},xp={key:1},Lp=["disabled"],Ip={key:0,class:"image",src:Gt,alt:"OK"},Pp={key:1,class:"image",src:zt,alt:"OK"},kp={key:0,class:"image",src:Tr,alt:"X"},Np={key:1,class:"image",src:Or,alt:"X"};function Fp(e,t,n,s,r,o){return x(),L("div",Tp,[Op,o.hideTable?B("",!0):(x(),L("p",Rp,"Confirm only if the table has usable information.")),o.hideTable?(x(),L("p",xp,"Incorrect link.")):B("",!0),p("button",{onClick:t[0]||(t[0]=(...i)=>o.clickConfirm&&o.clickConfirm(...i)),class:"imgbutton",disabled:o.hideTable},[e.primaryColor!=="Light"?(x(),L("img",Ip)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Pp)):B("",!0)],8,Lp),p("button",{onClick:t[1]||(t[1]=(...i)=>o.clickCancel&&o.clickCancel(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",kp)):B("",!0),e.primaryColor==="Light"?(x(),L("img",Np)):B("",!0)])])}const Up=et(wp,[["render",Fp],["__scopeId","data-v-85018fb6"]]);U.defaults.baseURL="http://localhost:57782";const Dp={data(){return{appliedStyles:[],theme:"",accent:""}},components:{ArtistList:Xf,SourceMenu:hd,SourceTable:Pd,DialogsURL:bh,AddArtistDialog:Lh,ProgressBar:Nh,SettingsWindow:Ep,PreviewDialog:Up},created(){this.loadTheme(),this.detectTheme()},computed:{...Ze(["settingsOpen","primaryColor","accentColor","previewVis"])},watch:{primaryColor(e){this.theme=e,this.applyTheme(e,this.accent)},accentColor(e){this.accent=e,this.applyTheme(this.theme,e)}},methods:{loadTheme(){U.get("/api/getThemeConfig").then(e=>{this.$store.commit("SET_PRIMARY_COLOR",e.data.theme),this.$store.commit("SET_ACCENT_COLOR",e.data.accent)}).catch(e=>{console.error(e)})},detectTheme(){U.get("/api/settingsOpened").then(e=>{const t=window.matchMedia("(prefers-color-scheme: dark)");e.data.autoTheme==!0&&(t.matches?this.$store.commit("SET_PRIMARY_COLOR","Black"):this.$store.commit("SET_PRIMARY_COLOR","Light"))}).catch(e=>{console.error(e)})},applyTheme(e,t){this.appliedStyles.forEach(r=>{r.remove()}),this.appliedStyles=[];let n,s;e!==""&&(n=`./primary${e}.css`,s=document.createElement("link"),s.rel="stylesheet",s.href=n,document.head.appendChild(s),this.appliedStyles.push(s)),t!==""&&(n=`./secondary${t}.css`,s=document.createElement("link"),s.rel="stylesheet",s.href=n,document.head.appendChild(s),this.appliedStyles.push(s))}}},Vp={key:0,class:"app"},Bp={class:"list"},Mp={class:"maincontent"},$p={key:0,class:"topbar"},jp={class:"sourcetable"},Hp={key:1,class:"dialogsurl"},Kp={class:"progressbar"},qp={key:1,class:"app"};function Wp(e,t,n,s,r,o){const i=nt("ArtistList"),l=nt("PreviewDialog"),c=nt("SourceMenu"),f=nt("AddArtistDialog"),u=nt("SourceTable"),d=nt("DialogsURL"),g=nt("ProgressBar"),C=nt("SettingsWindow");return x(),L(_e,null,[e.settingsOpen?B("",!0):(x(),L("div",Vp,[p("div",Bp,[e.previewVis?B("",!0):(x(),Hs(i,{key:0})),e.previewVis?(x(),Hs(l,{key:1,class:"preview"})):B("",!0)]),p("div",Mp,[e.previewVis?B("",!0):(x(),L("div",$p,[le(c)])),le(f),p("div",jp,[le(u)]),e.previewVis?B("",!0):(x(),L("div",Hp,[le(d)]))]),p("div",Kp,[le(g)])])),e.settingsOpen?(x(),L("div",qp,[le(C)])):B("",!0)],64)}const Gp=et(Dp,[["render",Wp],["__scopeId","data-v-e34fd722"]]),zp={artist:"",sourceTab:"",tableData:[],addDialogVis:!1,loadListRequest:!1,allowButtons:!0,progress:0,settingsOpen:!1,primaryColor:"",accentColor:"",previewVis:!1,isoDates:!1,urlExists:!1},Jp={SET_SOURCE_TAB(e,t){e.sourceTab=t},SET_SELECTED_ARTIST(e,t){e.artist=t},SET_TABLE_CONTENT(e,t){e.tableData=t,e.addDialogVis=!1},SET_ADD_VIS(e,t){e.addDialogVis=t},SET_LOAD_REQUEST(e,t){e.loadListRequest=t},SET_ALLOW_BUTTONS(e,t){e.allowButtons=t},SET_PROGRESS(e,t){e.progress=t*100,e.progress==100&&(e.progress=0)},SET_SETTINGS_OPEN(e,t){e.settingsOpen=t},SET_PRIMARY_COLOR(e,t){e.primaryColor=t},SET_ACCENT_COLOR(e,t){e.accentColor=t},SET_PREVIEW_VIS(e,t){e.previewVis=t},SET_ISODATES(e,t){e.isoDates=t},SET_URL_EXISTS(e,t){e.urlExists=t}},Yp={},Xp={},Qp=Vf({state:zp,mutations:Jp,actions:Yp,getters:Xp}),bl=za(Gp);bl.use(Qp);bl.mount("#app"); diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html index 9650237..95affd6 100644 --- a/src/main/resources/static/index.html +++ b/src/main/resources/static/index.html @@ -5,8 +5,8 @@ MusicReleaseTracker - - + +
diff --git a/vue/src/components/SourceMenu.vue b/vue/src/components/SourceMenu.vue index 1fe8a18..f7a1d2d 100644 --- a/vue/src/components/SourceMenu.vue +++ b/vue/src/components/SourceMenu.vue @@ -9,12 +9,12 @@
YT
- - @@ -36,9 +36,9 @@ export default { return { activeTab: "", eventSource: null, - scrapeColor: "var(--accent-color)", scrapeNotice: false, scrapeLast: "-", + isActive: false, } }, computed: { @@ -91,17 +91,18 @@ export default { }, // trigger scraping or cancel it, SSE listener for progressbar clickScrape() { + this.scrapeNotice = false; const allowButtons = this.allowButtons; if (!allowButtons) { axios.post('/api/cancelScrape') .then(() => { this.$store.commit('SET_ALLOW_BUTTONS', true); - this.scrapeColor = "var(--accent-color)"; + this.isActive = false; }) } else { this.$store.commit('SET_ALLOW_BUTTONS', false); - this.scrapeColor = "var(--dull-color)"; + this.isActive = true; this.eventSource = new EventSource('/progress'); this.eventSource.onmessage = (event) => { const progress = parseFloat(event.data); @@ -110,7 +111,7 @@ export default { axios.post('/api/clickScrape') .then(() => { - this.scrapeColor = "var(--accent-color)"; + this.isActive = false; this.$store.commit('SET_ALLOW_BUTTONS', true); this.eventSource.close(); let time = new Date().toLocaleString('en-GB', { @@ -163,29 +164,34 @@ export default { height: 32px; width: 32px; } - .imgbutton1:hover, .imgbutton2:hover { - opacity: 70%; - } - .imgbutton1 { + .settingsButton, .scrapeButton { padding: 0; + margin-left: 8px; + margin-top: 2px; height: 32px; width: 32px; - margin-left: 8px; - background-color: var(--accent-color); border: none; - margin-top: 2px; + } + .settingsButton:hover, .scrapeButton:hover { + opacity: 70%; + } + .settingsButton { height: 32px; width: 32px; + background-color: var(--accent-color); } - .imgbutton2 { - padding: 0; - margin-left: 8px; + .scrapeButton { + background-color: var(--accent-color); margin-right: 20px; - border: none; - margin-top: 2px; border-radius: 50px; - height: 32px; - width: 32px; + } + .scrapeActive { + transition: 0.75s; + rotate: 180deg; + filter:hue-rotate(120deg); + } + .scrapeActive:hover { + opacity: 1; } .cvtab { width: 80%; From 92630d37c912a0462e5545faa7764e951f4643b6 Mon Sep 17 00:00:00 2001 From: BLCK <123077751+BLCK-B@users.noreply.github.com> Date: Tue, 28 May 2024 13:47:44 +0200 Subject: [PATCH 19/22] SSEemitter cancelling, dev port fix --- .../MusicReleaseTracker/Core/BeanConfig.java | 1 - .../FrontendAPI/SSEController.java | 15 +++++++---- .../Scraping/ScrapeProcess.java | 8 ++---- .../resources/static/assets/index-BVpPLp6L.js | 26 +++++++++++++++++++ .../static/assets/index-DQ2nizA8.css | 1 + vue/src/components/SettingsWindow.vue | 13 +++++----- vue/src/components/SourceMenu.vue | 15 ++++++----- 7 files changed, 53 insertions(+), 26 deletions(-) create mode 100644 src/main/resources/static/assets/index-BVpPLp6L.js create mode 100644 src/main/resources/static/assets/index-DQ2nizA8.css diff --git a/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java b/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java index 7360707..68bb669 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Core/BeanConfig.java @@ -55,5 +55,4 @@ public StartSetup startSetup(ValueStore valueStore, ErrorLogging errorLogging) { return new StartSetup(valueStore, errorLogging); } - } diff --git a/src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/SSEController.java b/src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/SSEController.java index e1dad17..8d5727b 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/SSEController.java +++ b/src/main/java/com/blck/MusicReleaseTracker/FrontendAPI/SSEController.java @@ -1,6 +1,7 @@ package com.blck.MusicReleaseTracker.FrontendAPI; import com.blck.MusicReleaseTracker.Core.ErrorLogging; +import com.blck.MusicReleaseTracker.Scraping.ScrapeProcess; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -33,19 +34,23 @@ public SSEController(ErrorLogging errorLogging) { @GetMapping("/progress") public SseEmitter eventStream() { - emitter = new SseEmitter(300000L); + emitter = new SseEmitter(3000000L); // timeout 10 min return emitter; } - public void sendProgress(double state) { + public boolean sendProgress(double state) { try { emitter.send(String.valueOf(state)); - } catch (Exception e) { - log.error(e, ErrorLogging.Severity.WARNING, "error in progress emitter"); - } finally { if (state == 1.0) emitter.complete(); } + catch (IllegalStateException e) { + return true; + } + catch (Exception e) { + log.error(e, ErrorLogging.Severity.INFO, "error in progress emitter"); + } + return false; } } diff --git a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java index 6466f1e..d49595f 100644 --- a/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java +++ b/src/main/java/com/blck/MusicReleaseTracker/Scraping/ScrapeProcess.java @@ -7,9 +7,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.Statement; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; @@ -58,11 +55,10 @@ public void scrapeData(ScraperManager scraperManager) { double progress = 0.0; while (remaining != 0 && !scrapeCancel) { remaining = scraperManager.scrapeNext(); - if (scrapeCancel) - break; progress = ((double) initSize - (double) remaining) / (double) initSize; if (progress != 1.0) - SSE.sendProgress(progress); + if (SSE.sendProgress(progress)) + scrapeCancel = true; } SSE.sendProgress(1.0); System.gc(); diff --git a/src/main/resources/static/assets/index-BVpPLp6L.js b/src/main/resources/static/assets/index-BVpPLp6L.js new file mode 100644 index 0000000..e368d90 --- /dev/null +++ b/src/main/resources/static/assets/index-BVpPLp6L.js @@ -0,0 +1,26 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const o of r)if(o.type==="childList")for(const i of o.addedNodes)i.tagName==="LINK"&&i.rel==="modulepreload"&&s(i)}).observe(document,{childList:!0,subtree:!0});function n(r){const o={};return r.integrity&&(o.integrity=r.integrity),r.referrerPolicy&&(o.referrerPolicy=r.referrerPolicy),r.crossOrigin==="use-credentials"?o.credentials="include":r.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function s(r){if(r.ep)return;r.ep=!0;const o=n(r);fetch(r.href,o)}})();/** +* @vue/shared v3.4.21 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function Zs(e,t){const n=new Set(e.split(","));return t?s=>n.has(s.toLowerCase()):s=>n.has(s)}const Z={},Ft=[],Le=()=>{},vl=()=>!1,jn=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),er=e=>e.startsWith("onUpdate:"),he=Object.assign,tr=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},El=Object.prototype.hasOwnProperty,W=(e,t)=>El.call(e,t),k=Array.isArray,Ut=e=>hn(e)==="[object Map]",Hn=e=>hn(e)==="[object Set]",kr=e=>hn(e)==="[object Date]",M=e=>typeof e=="function",ce=e=>typeof e=="string",pt=e=>typeof e=="symbol",Y=e=>e!==null&&typeof e=="object",No=e=>(Y(e)||M(e))&&M(e.then)&&M(e.catch),Fo=Object.prototype.toString,hn=e=>Fo.call(e),Cl=e=>hn(e).slice(8,-1),Uo=e=>hn(e)==="[object Object]",nr=e=>ce(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,tn=Zs(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Kn=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},wl=/-(\w)/g,Ke=Kn(e=>e.replace(wl,(t,n)=>n?n.toUpperCase():"")),Al=/\B([A-Z])/g,jt=Kn(e=>e.replace(Al,"-$1").toLowerCase()),qn=Kn(e=>e.charAt(0).toUpperCase()+e.slice(1)),hs=Kn(e=>e?`on${qn(e)}`:""),Ot=(e,t)=>!Object.is(e,t),On=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},Rs=e=>{const t=parseFloat(e);return isNaN(t)?e:t},Tl=e=>{const t=ce(e)?Number(e):NaN;return isNaN(t)?e:t};let Nr;const Do=()=>Nr||(Nr=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function Wn(e){if(k(e)){const t={};for(let n=0;n{if(n){const s=n.split(Rl);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function ve(e){let t="";if(ce(e))t=e;else if(k(e))for(let n=0;nVt(n,t))}const ze=e=>ce(e)?e:e==null?"":k(e)||Y(e)&&(e.toString===Fo||!M(e.toString))?JSON.stringify(e,Mo,2):String(e),Mo=(e,t)=>t&&t.__v_isRef?Mo(e,t.value):Ut(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r],o)=>(n[ps(s,o)+" =>"]=r,n),{})}:Hn(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>ps(n))}:pt(t)?ps(t):Y(t)&&!k(t)&&!Uo(t)?String(t):t,ps=(e,t="")=>{var n;return pt(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};/** +* @vue/reactivity v3.4.21 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let Ne;class $o{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Ne,!t&&Ne&&(this.index=(Ne.scopes||(Ne.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=Ne;try{return Ne=this,t()}finally{Ne=n}}}on(){Ne=this}off(){Ne=this.parent}stop(t){if(this._active){let n,s;for(n=0,s=this.effects.length;n=4))break}this._dirtyLevel===1&&(this._dirtyLevel=0),xt()}return this._dirtyLevel>=4}set dirty(t){this._dirtyLevel=t?4:0}run(){if(this._dirtyLevel=0,!this.active)return this.fn();let t=dt,n=At;try{return dt=!0,At=this,this._runnings++,Fr(this),this.fn()}finally{Ur(this),this._runnings--,At=n,dt=t}}stop(){var t;this.active&&(Fr(this),Ur(this),(t=this.onStop)==null||t.call(this),this.active=!1)}}function Dl(e){return e.value}function Fr(e){e._trackId++,e._depsLength=0}function Ur(e){if(e.deps.length>e._depsLength){for(let t=e._depsLength;t{const n=new Map;return n.cleanup=e,n.computed=t,n},Is=new WeakMap,Tt=Symbol(""),Ps=Symbol("");function we(e,t,n){if(dt&&At){let s=Is.get(e);s||Is.set(e,s=new Map);let r=s.get(n);r||s.set(n,r=Wo(()=>s.delete(n))),Ko(At,r)}}function Je(e,t,n,s,r,o){const i=Is.get(e);if(!i)return;let l=[];if(t==="clear")l=[...i.values()];else if(n==="length"&&k(e)){const c=Number(s);i.forEach((f,u)=>{(u==="length"||!pt(u)&&u>=c)&&l.push(f)})}else switch(n!==void 0&&l.push(i.get(n)),t){case"add":k(e)?nr(n)&&l.push(i.get("length")):(l.push(i.get(Tt)),Ut(e)&&l.push(i.get(Ps)));break;case"delete":k(e)||(l.push(i.get(Tt)),Ut(e)&&l.push(i.get(Ps)));break;case"set":Ut(e)&&l.push(i.get(Tt));break}rr();for(const c of l)c&&qo(c,4);or()}const Bl=Zs("__proto__,__v_isRef,__isVue"),Go=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(pt)),Dr=Vl();function Vl(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const s=G(this);for(let o=0,i=this.length;o{e[t]=function(...n){Rt(),rr();const s=G(this)[t].apply(this,n);return or(),xt(),s}}),e}function Ml(e){const t=G(this);return we(t,"has",e),t.hasOwnProperty(e)}class zo{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,s){const r=this._isReadonly,o=this._isShallow;if(n==="__v_isReactive")return!r;if(n==="__v_isReadonly")return r;if(n==="__v_isShallow")return o;if(n==="__v_raw")return s===(r?o?Zl:Qo:o?Xo:Yo).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(s)?t:void 0;const i=k(t);if(!r){if(i&&W(Dr,n))return Reflect.get(Dr,n,s);if(n==="hasOwnProperty")return Ml}const l=Reflect.get(t,n,s);return(pt(n)?Go.has(n):Bl(n))||(r||we(t,"get",n),o)?l:Re(l)?i&&nr(n)?l:l.value:Y(l)?r?Zo(l):zn(l):l}}class Jo extends zo{constructor(t=!1){super(!1,t)}set(t,n,s,r){let o=t[n];if(!this._isShallow){const c=ln(o);if(!ks(s)&&!ln(s)&&(o=G(o),s=G(s)),!k(t)&&Re(o)&&!Re(s))return c?!1:(o.value=s,!0)}const i=k(t)&&nr(n)?Number(n)e,Gn=e=>Reflect.getPrototypeOf(e);function Sn(e,t,n=!1,s=!1){e=e.__v_raw;const r=G(e),o=G(t);n||(Ot(t,o)&&we(r,"get",t),we(r,"get",o));const{has:i}=Gn(r),l=s?ir:n?ur:ar;if(i.call(r,t))return l(e.get(t));if(i.call(r,o))return l(e.get(o));e!==r&&e.get(t)}function vn(e,t=!1){const n=this.__v_raw,s=G(n),r=G(e);return t||(Ot(e,r)&&we(s,"has",e),we(s,"has",r)),e===r?n.has(e):n.has(e)||n.has(r)}function En(e,t=!1){return e=e.__v_raw,!t&&we(G(e),"iterate",Tt),Reflect.get(e,"size",e)}function Br(e){e=G(e);const t=G(this);return Gn(t).has.call(t,e)||(t.add(e),Je(t,"add",e,e)),this}function Vr(e,t){t=G(t);const n=G(this),{has:s,get:r}=Gn(n);let o=s.call(n,e);o||(e=G(e),o=s.call(n,e));const i=r.call(n,e);return n.set(e,t),o?Ot(t,i)&&Je(n,"set",e,t):Je(n,"add",e,t),this}function Mr(e){const t=G(this),{has:n,get:s}=Gn(t);let r=n.call(t,e);r||(e=G(e),r=n.call(t,e)),s&&s.call(t,e);const o=t.delete(e);return r&&Je(t,"delete",e,void 0),o}function $r(){const e=G(this),t=e.size!==0,n=e.clear();return t&&Je(e,"clear",void 0,void 0),n}function Cn(e,t){return function(s,r){const o=this,i=o.__v_raw,l=G(i),c=t?ir:e?ur:ar;return!e&&we(l,"iterate",Tt),i.forEach((f,u)=>s.call(r,c(f),c(u),o))}}function wn(e,t,n){return function(...s){const r=this.__v_raw,o=G(r),i=Ut(o),l=e==="entries"||e===Symbol.iterator&&i,c=e==="keys"&&i,f=r[e](...s),u=n?ir:t?ur:ar;return!t&&we(o,"iterate",c?Ps:Tt),{next(){const{value:d,done:g}=f.next();return g?{value:d,done:g}:{value:l?[u(d[0]),u(d[1])]:u(d),done:g}},[Symbol.iterator](){return this}}}}function tt(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function ql(){const e={get(o){return Sn(this,o)},get size(){return En(this)},has:vn,add:Br,set:Vr,delete:Mr,clear:$r,forEach:Cn(!1,!1)},t={get(o){return Sn(this,o,!1,!0)},get size(){return En(this)},has:vn,add:Br,set:Vr,delete:Mr,clear:$r,forEach:Cn(!1,!0)},n={get(o){return Sn(this,o,!0)},get size(){return En(this,!0)},has(o){return vn.call(this,o,!0)},add:tt("add"),set:tt("set"),delete:tt("delete"),clear:tt("clear"),forEach:Cn(!0,!1)},s={get(o){return Sn(this,o,!0,!0)},get size(){return En(this,!0)},has(o){return vn.call(this,o,!0)},add:tt("add"),set:tt("set"),delete:tt("delete"),clear:tt("clear"),forEach:Cn(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(o=>{e[o]=wn(o,!1,!1),n[o]=wn(o,!0,!1),t[o]=wn(o,!1,!0),s[o]=wn(o,!0,!0)}),[e,n,t,s]}const[Wl,Gl,zl,Jl]=ql();function lr(e,t){const n=t?e?Jl:zl:e?Gl:Wl;return(s,r,o)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(W(n,r)&&r in s?n:s,r,o)}const Yl={get:lr(!1,!1)},Xl={get:lr(!1,!0)},Ql={get:lr(!0,!1)},Yo=new WeakMap,Xo=new WeakMap,Qo=new WeakMap,Zl=new WeakMap;function ec(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function tc(e){return e.__v_skip||!Object.isExtensible(e)?0:ec(Cl(e))}function zn(e){return ln(e)?e:cr(e,!1,jl,Yl,Yo)}function nc(e){return cr(e,!1,Kl,Xl,Xo)}function Zo(e){return cr(e,!0,Hl,Ql,Qo)}function cr(e,t,n,s,r){if(!Y(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const o=r.get(e);if(o)return o;const i=tc(e);if(i===0)return e;const l=new Proxy(e,i===2?s:n);return r.set(e,l),l}function Dt(e){return ln(e)?Dt(e.__v_raw):!!(e&&e.__v_isReactive)}function ln(e){return!!(e&&e.__v_isReadonly)}function ks(e){return!!(e&&e.__v_isShallow)}function ei(e){return Dt(e)||ln(e)}function G(e){const t=e&&e.__v_raw;return t?G(t):e}function ti(e){return Object.isExtensible(e)&&Un(e,"__v_skip",!0),e}const ar=e=>Y(e)?zn(e):e,ur=e=>Y(e)?Zo(e):e;class ni{constructor(t,n,s,r){this.getter=t,this._setter=n,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this.effect=new sr(()=>t(this._value),()=>ms(this,this.effect._dirtyLevel===2?2:3)),this.effect.computed=this,this.effect.active=this._cacheable=!r,this.__v_isReadonly=s}get value(){const t=G(this);return(!t._cacheable||t.effect.dirty)&&Ot(t._value,t._value=t.effect.run())&&ms(t,4),rc(t),t.effect._dirtyLevel>=2&&ms(t,2),t._value}set value(t){this._setter(t)}get _dirty(){return this.effect.dirty}set _dirty(t){this.effect.dirty=t}}function sc(e,t,n=!1){let s,r;const o=M(e);return o?(s=e,r=Le):(s=e.get,r=e.set),new ni(s,r,o||!r,n)}function rc(e){var t;dt&&At&&(e=G(e),Ko(At,(t=e.dep)!=null?t:e.dep=Wo(()=>e.dep=void 0,e instanceof ni?e:void 0)))}function ms(e,t=4,n){e=G(e);const s=e.dep;s&&qo(s,t)}function Re(e){return!!(e&&e.__v_isRef===!0)}function oc(e){return Re(e)?e.value:e}const ic={get:(e,t,n)=>oc(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return Re(r)&&!Re(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function si(e){return Dt(e)?e:new Proxy(e,ic)}/** +* @vue/runtime-core v3.4.21 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function ht(e,t,n,s){try{return s?e(...s):e()}catch(r){Jn(r,t,n)}}function Ie(e,t,n,s){if(M(e)){const o=ht(e,t,n,s);return o&&No(o)&&o.catch(i=>{Jn(i,t,n)}),o}const r=[];for(let o=0;o>>1,r=be[s],o=an(r);oje&&be.splice(t,1)}function fc(e){k(e)?Bt.push(...e):(!lt||!lt.includes(e,e.allowRecurse?Et+1:Et))&&Bt.push(e),oi()}function jr(e,t,n=cn?je+1:0){for(;nan(n)-an(s));if(Bt.length=0,lt){lt.push(...t);return}for(lt=t,Et=0;Ete.id==null?1/0:e.id,dc=(e,t)=>{const n=an(e)-an(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function li(e){Ns=!1,cn=!0,be.sort(dc);try{for(je=0;jece(E)?E.trim():E)),d&&(r=n.map(Rs))}let l,c=s[l=hs(t)]||s[l=hs(Ke(t))];!c&&o&&(c=s[l=hs(jt(t))]),c&&Ie(c,e,6,r);const f=s[l+"Once"];if(f){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Ie(f,e,6,r)}}function ci(e,t,n=!1){const s=t.emitsCache,r=s.get(e);if(r!==void 0)return r;const o=e.emits;let i={},l=!1;if(!M(e)){const c=f=>{const u=ci(f,t,!0);u&&(l=!0,he(i,u))};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}return!o&&!l?(Y(e)&&s.set(e,null),null):(k(o)?o.forEach(c=>i[c]=null):he(i,o),Y(e)&&s.set(e,i),i)}function Yn(e,t){return!e||!jn(t)?!1:(t=t.slice(2).replace(/Once$/,""),W(e,t[0].toLowerCase()+t.slice(1))||W(e,jt(t))||W(e,t))}let Ee=null,Xn=null;function Dn(e){const t=Ee;return Ee=e,Xn=e&&e.type.__scopeId||null,t}function Ht(e){Xn=e}function Kt(){Xn=null}function ai(e,t=Ee,n){if(!t||e._n)return e;const s=(...r)=>{s._d&&eo(-1);const o=Dn(t);let i;try{i=e(...r)}finally{Dn(o),s._d&&eo(1)}return i};return s._n=!0,s._c=!0,s._d=!0,s}function gs(e){const{type:t,vnode:n,proxy:s,withProxy:r,props:o,propsOptions:[i],slots:l,attrs:c,emit:f,render:u,renderCache:d,data:g,setupState:E,ctx:A,inheritAttrs:C}=e;let D,$;const ee=Dn(e);try{if(n.shapeFlag&4){const z=r||s,re=z;D=$e(u.call(re,z,d,o,E,g,A)),$=c}else{const z=t;D=$e(z.length>1?z(o,{attrs:c,slots:l,emit:f}):z(o,null)),$=t.props?c:pc(c)}}catch(z){on.length=0,Jn(z,e,1),D=le(Ue)}let j=D;if($&&C!==!1){const z=Object.keys($),{shapeFlag:re}=j;z.length&&re&7&&(i&&z.some(er)&&($=mc($,i)),j=mt(j,$))}return n.dirs&&(j=mt(j),j.dirs=j.dirs?j.dirs.concat(n.dirs):n.dirs),n.transition&&(j.transition=n.transition),D=j,Dn(ee),D}const pc=e=>{let t;for(const n in e)(n==="class"||n==="style"||jn(n))&&((t||(t={}))[n]=e[n]);return t},mc=(e,t)=>{const n={};for(const s in e)(!er(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function gc(e,t,n){const{props:s,children:r,component:o}=e,{props:i,children:l,patchFlag:c}=t,f=o.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&c>=0){if(c&1024)return!0;if(c&16)return s?Hr(s,i,f):!!i;if(c&8){const u=t.dynamicProps;for(let d=0;de.__isSuspense;function vc(e,t){t&&t.pendingBranch?k(e)?t.effects.push(...e):t.effects.push(e):fc(e)}const Ec=Symbol.for("v-scx"),Cc=()=>xn(Ec),An={};function nn(e,t,n){return fi(e,t,n)}function fi(e,t,{immediate:n,deep:s,flush:r,once:o,onTrack:i,onTrigger:l}=Z){if(t&&o){const H=t;t=(...ye)=>{H(...ye),re()}}const c=me,f=H=>s===!0?H:wt(H,s===!1?1:void 0);let u,d=!1,g=!1;if(Re(e)?(u=()=>e.value,d=ks(e)):Dt(e)?(u=()=>f(e),d=!0):k(e)?(g=!0,d=e.some(H=>Dt(H)||ks(H)),u=()=>e.map(H=>{if(Re(H))return H.value;if(Dt(H))return f(H);if(M(H))return ht(H,c,2)})):M(e)?t?u=()=>ht(e,c,2):u=()=>(E&&E(),Ie(e,c,3,[A])):u=Le,t&&s){const H=u;u=()=>wt(H())}let E,A=H=>{E=j.onStop=()=>{ht(H,c,4),E=j.onStop=void 0}},C;if(ns)if(A=Le,t?n&&Ie(t,c,3,[u(),g?[]:void 0,A]):u(),r==="sync"){const H=Cc();C=H.__watcherHandles||(H.__watcherHandles=[])}else return Le;let D=g?new Array(e.length).fill(An):An;const $=()=>{if(!(!j.active||!j.dirty))if(t){const H=j.run();(s||d||(g?H.some((ye,B)=>Ot(ye,D[B])):Ot(H,D)))&&(E&&E(),Ie(t,c,3,[H,D===An?void 0:g&&D[0]===An?[]:D,A]),D=H)}else j.run()};$.allowRecurse=!!t;let ee;r==="sync"?ee=$:r==="post"?ee=()=>Ce($,c&&c.suspense):($.pre=!0,c&&($.id=c.uid),ee=()=>dr($));const j=new sr(u,Le,ee),z=Ul(),re=()=>{j.stop(),z&&tr(z.effects,j)};return t?n?$():D=j.run():r==="post"?Ce(j.run.bind(j),c&&c.suspense):j.run(),C&&C.push(re),re}function wc(e,t,n){const s=this.proxy,r=ce(e)?e.includes(".")?di(s,e):()=>s[e]:e.bind(s,s);let o;M(t)?o=t:(o=t.handler,n=t);const i=pn(this),l=fi(r,o.bind(s),n);return i(),l}function di(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;r0){if(n>=t)return e;n++}if(s=s||new Set,s.has(e))return e;if(s.add(e),Re(e))wt(e.value,t,n,s);else if(k(e))for(let r=0;r{wt(r,t,n,s)});else if(Uo(e))for(const r in e)wt(e[r],t,n,s);return e}function ie(e,t){if(Ee===null)return e;const n=ss(Ee)||Ee.proxy,s=e.dirs||(e.dirs=[]);for(let r=0;r{e.isMounted=!0}),bi(()=>{e.isUnmounting=!0}),e}const xe=[Function,Array],hi={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:xe,onEnter:xe,onAfterEnter:xe,onEnterCancelled:xe,onBeforeLeave:xe,onLeave:xe,onAfterLeave:xe,onLeaveCancelled:xe,onBeforeAppear:xe,onAppear:xe,onAfterAppear:xe,onAppearCancelled:xe},Tc={name:"BaseTransition",props:hi,setup(e,{slots:t}){const n=fa(),s=Ac();return()=>{const r=t.default&&mi(t.default(),!0);if(!r||!r.length)return;let o=r[0];if(r.length>1){for(const g of r)if(g.type!==Ue){o=g;break}}const i=G(e),{mode:l}=i;if(s.isLeaving)return _s(o);const c=qr(o);if(!c)return _s(o);const f=Fs(c,i,s,n);Us(c,f);const u=n.subTree,d=u&&qr(u);if(d&&d.type!==Ue&&!Ct(c,d)){const g=Fs(d,i,s,n);if(Us(d,g),l==="out-in")return s.isLeaving=!0,g.afterLeave=()=>{s.isLeaving=!1,n.update.active!==!1&&(n.effect.dirty=!0,n.update())},_s(o);l==="in-out"&&c.type!==Ue&&(g.delayLeave=(E,A,C)=>{const D=pi(s,d);D[String(d.key)]=d,E[ct]=()=>{A(),E[ct]=void 0,delete f.delayedLeave},f.delayedLeave=C})}return o}}},Oc=Tc;function pi(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function Fs(e,t,n,s){const{appear:r,mode:o,persisted:i=!1,onBeforeEnter:l,onEnter:c,onAfterEnter:f,onEnterCancelled:u,onBeforeLeave:d,onLeave:g,onAfterLeave:E,onLeaveCancelled:A,onBeforeAppear:C,onAppear:D,onAfterAppear:$,onAppearCancelled:ee}=t,j=String(e.key),z=pi(n,e),re=(B,oe)=>{B&&Ie(B,s,9,oe)},H=(B,oe)=>{const Q=oe[1];re(B,oe),k(B)?B.every(ge=>ge.length<=1)&&Q():B.length<=1&&Q()},ye={mode:o,persisted:i,beforeEnter(B){let oe=l;if(!n.isMounted)if(r)oe=C||l;else return;B[ct]&&B[ct](!0);const Q=z[j];Q&&Ct(e,Q)&&Q.el[ct]&&Q.el[ct](),re(oe,[B])},enter(B){let oe=c,Q=f,ge=u;if(!n.isMounted)if(r)oe=D||c,Q=$||f,ge=ee||u;else return;let I=!1;const ne=B[Tn]=Te=>{I||(I=!0,Te?re(ge,[B]):re(Q,[B]),ye.delayedLeave&&ye.delayedLeave(),B[Tn]=void 0)};oe?H(oe,[B,ne]):ne()},leave(B,oe){const Q=String(e.key);if(B[Tn]&&B[Tn](!0),n.isUnmounting)return oe();re(d,[B]);let ge=!1;const I=B[ct]=ne=>{ge||(ge=!0,oe(),ne?re(A,[B]):re(E,[B]),B[ct]=void 0,z[Q]===e&&delete z[Q])};z[Q]=e,g?H(g,[B,I]):I()},clone(B){return Fs(B,t,n,s)}};return ye}function _s(e){if(Qn(e))return e=mt(e),e.children=null,e}function qr(e){return Qn(e)?e.children?e.children[0]:void 0:e}function Us(e,t){e.shapeFlag&6&&e.component?Us(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function mi(e,t=!1,n){let s=[],r=0;for(let o=0;o1)for(let o=0;o!!e.type.__asyncLoader,Qn=e=>e.type.__isKeepAlive;function Rc(e,t){gi(e,"a",t)}function xc(e,t){gi(e,"da",t)}function gi(e,t,n=me){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(Zn(t,s,n),n){let r=n.parent;for(;r&&r.parent;)Qn(r.parent.vnode)&&Lc(s,t,n,r),r=r.parent}}function Lc(e,t,n,s){const r=Zn(t,e,s,!0);yi(()=>{tr(s[t],r)},n)}function Zn(e,t,n=me,s=!1){if(n){const r=n[e]||(n[e]=[]),o=t.__weh||(t.__weh=(...i)=>{if(n.isUnmounted)return;Rt();const l=pn(n),c=Ie(t,n,e,i);return l(),xt(),c});return s?r.unshift(o):r.push(o),o}}const Qe=e=>(t,n=me)=>(!ns||e==="sp")&&Zn(e,(...s)=>t(...s),n),Ic=Qe("bm"),_i=Qe("m"),Pc=Qe("bu"),kc=Qe("u"),bi=Qe("bum"),yi=Qe("um"),Nc=Qe("sp"),Fc=Qe("rtg"),Uc=Qe("rtc");function Dc(e,t=me){Zn("ec",e,t)}function Ds(e,t,n,s){let r;const o=n&&n[s];if(k(e)||ce(e)){r=new Array(e.length);for(let i=0,l=e.length;it(i,l,void 0,o&&o[l]));else{const i=Object.keys(e);r=new Array(i.length);for(let l=0,c=i.length;le?Ii(e)?ss(e)||e.proxy:Bs(e.parent):null,sn=he(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Bs(e.parent),$root:e=>Bs(e.root),$emit:e=>e.emit,$options:e=>hr(e),$forceUpdate:e=>e.f||(e.f=()=>{e.effect.dirty=!0,dr(e.update)}),$nextTick:e=>e.n||(e.n=cc.bind(e.proxy)),$watch:e=>wc.bind(e)}),bs=(e,t)=>e!==Z&&!e.__isScriptSetup&&W(e,t),Bc={get({_:e},t){const{ctx:n,setupState:s,data:r,props:o,accessCache:i,type:l,appContext:c}=e;let f;if(t[0]!=="$"){const E=i[t];if(E!==void 0)switch(E){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return o[t]}else{if(bs(s,t))return i[t]=1,s[t];if(r!==Z&&W(r,t))return i[t]=2,r[t];if((f=e.propsOptions[0])&&W(f,t))return i[t]=3,o[t];if(n!==Z&&W(n,t))return i[t]=4,n[t];Vs&&(i[t]=0)}}const u=sn[t];let d,g;if(u)return t==="$attrs"&&we(e,"get",t),u(e);if((d=l.__cssModules)&&(d=d[t]))return d;if(n!==Z&&W(n,t))return i[t]=4,n[t];if(g=c.config.globalProperties,W(g,t))return g[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:o}=e;return bs(r,t)?(r[t]=n,!0):s!==Z&&W(s,t)?(s[t]=n,!0):W(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(o[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,propsOptions:o}},i){let l;return!!n[i]||e!==Z&&W(e,i)||bs(t,i)||(l=o[0])&&W(l,i)||W(s,i)||W(sn,i)||W(r.config.globalProperties,i)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:W(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};function Wr(e){return k(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}let Vs=!0;function Vc(e){const t=hr(e),n=e.proxy,s=e.ctx;Vs=!1,t.beforeCreate&&Gr(t.beforeCreate,e,"bc");const{data:r,computed:o,methods:i,watch:l,provide:c,inject:f,created:u,beforeMount:d,mounted:g,beforeUpdate:E,updated:A,activated:C,deactivated:D,beforeDestroy:$,beforeUnmount:ee,destroyed:j,unmounted:z,render:re,renderTracked:H,renderTriggered:ye,errorCaptured:B,serverPrefetch:oe,expose:Q,inheritAttrs:ge,components:I,directives:ne,filters:Te}=t;if(f&&Mc(f,s,null),i)for(const se in i){const X=i[se];M(X)&&(s[se]=X.bind(n))}if(r){const se=r.call(n,n);Y(se)&&(e.data=zn(se))}if(Vs=!0,o)for(const se in o){const X=o[se],gt=M(X)?X.bind(n,n):M(X.get)?X.get.bind(n,n):Le,bn=!M(X)&&M(X.set)?X.set.bind(n):Le,_t=ki({get:gt,set:bn});Object.defineProperty(s,se,{enumerable:!0,configurable:!0,get:()=>_t.value,set:Be=>_t.value=Be})}if(l)for(const se in l)Si(l[se],s,n,se);if(c){const se=M(c)?c.call(n):c;Reflect.ownKeys(se).forEach(X=>{Wc(X,se[X])})}u&&Gr(u,e,"c");function fe(se,X){k(X)?X.forEach(gt=>se(gt.bind(n))):X&&se(X.bind(n))}if(fe(Ic,d),fe(_i,g),fe(Pc,E),fe(kc,A),fe(Rc,C),fe(xc,D),fe(Dc,B),fe(Uc,H),fe(Fc,ye),fe(bi,ee),fe(yi,z),fe(Nc,oe),k(Q))if(Q.length){const se=e.exposed||(e.exposed={});Q.forEach(X=>{Object.defineProperty(se,X,{get:()=>n[X],set:gt=>n[X]=gt})})}else e.exposed||(e.exposed={});re&&e.render===Le&&(e.render=re),ge!=null&&(e.inheritAttrs=ge),I&&(e.components=I),ne&&(e.directives=ne)}function Mc(e,t,n=Le){k(e)&&(e=Ms(e));for(const s in e){const r=e[s];let o;Y(r)?"default"in r?o=xn(r.from||s,r.default,!0):o=xn(r.from||s):o=xn(r),Re(o)?Object.defineProperty(t,s,{enumerable:!0,configurable:!0,get:()=>o.value,set:i=>o.value=i}):t[s]=o}}function Gr(e,t,n){Ie(k(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function Si(e,t,n,s){const r=s.includes(".")?di(n,s):()=>n[s];if(ce(e)){const o=t[e];M(o)&&nn(r,o)}else if(M(e))nn(r,e.bind(n));else if(Y(e))if(k(e))e.forEach(o=>Si(o,t,n,s));else{const o=M(e.handler)?e.handler.bind(n):t[e.handler];M(o)&&nn(r,o,e)}}function hr(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:o,config:{optionMergeStrategies:i}}=e.appContext,l=o.get(t);let c;return l?c=l:!r.length&&!n&&!s?c=t:(c={},r.length&&r.forEach(f=>Bn(c,f,i,!0)),Bn(c,t,i)),Y(t)&&o.set(t,c),c}function Bn(e,t,n,s=!1){const{mixins:r,extends:o}=t;o&&Bn(e,o,n,!0),r&&r.forEach(i=>Bn(e,i,n,!0));for(const i in t)if(!(s&&i==="expose")){const l=$c[i]||n&&n[i];e[i]=l?l(e[i],t[i]):t[i]}return e}const $c={data:zr,props:Jr,emits:Jr,methods:Zt,computed:Zt,beforeCreate:Se,created:Se,beforeMount:Se,mounted:Se,beforeUpdate:Se,updated:Se,beforeDestroy:Se,beforeUnmount:Se,destroyed:Se,unmounted:Se,activated:Se,deactivated:Se,errorCaptured:Se,serverPrefetch:Se,components:Zt,directives:Zt,watch:Hc,provide:zr,inject:jc};function zr(e,t){return t?e?function(){return he(M(e)?e.call(this,this):e,M(t)?t.call(this,this):t)}:t:e}function jc(e,t){return Zt(Ms(e),Ms(t))}function Ms(e){if(k(e)){const t={};for(let n=0;n1)return n&&M(t)?t.call(s&&s.proxy):t}}function Gc(e,t,n,s=!1){const r={},o={};Un(o,ts,1),e.propsDefaults=Object.create(null),Ei(e,t,r,o);for(const i in e.propsOptions[0])i in r||(r[i]=void 0);n?e.props=s?r:nc(r):e.type.props?e.props=r:e.props=o,e.attrs=o}function zc(e,t,n,s){const{props:r,attrs:o,vnode:{patchFlag:i}}=e,l=G(r),[c]=e.propsOptions;let f=!1;if((s||i>0)&&!(i&16)){if(i&8){const u=e.vnode.dynamicProps;for(let d=0;d{c=!0;const[g,E]=Ci(d,t,!0);he(i,g),E&&l.push(...E)};!n&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}if(!o&&!c)return Y(e)&&s.set(e,Ft),Ft;if(k(o))for(let u=0;u-1,E[1]=C<0||A-1||W(E,"default"))&&l.push(d)}}}const f=[i,l];return Y(e)&&s.set(e,f),f}function Yr(e){return e[0]!=="$"&&!tn(e)}function Xr(e){return e===null?"null":typeof e=="function"?e.name||"":typeof e=="object"&&e.constructor&&e.constructor.name||""}function Qr(e,t){return Xr(e)===Xr(t)}function Zr(e,t){return k(t)?t.findIndex(n=>Qr(n,e)):M(t)&&Qr(t,e)?0:-1}const wi=e=>e[0]==="_"||e==="$stable",pr=e=>k(e)?e.map($e):[$e(e)],Jc=(e,t,n)=>{if(t._n)return t;const s=ai((...r)=>pr(t(...r)),n);return s._c=!1,s},Ai=(e,t,n)=>{const s=e._ctx;for(const r in e){if(wi(r))continue;const o=e[r];if(M(o))t[r]=Jc(r,o,s);else if(o!=null){const i=pr(o);t[r]=()=>i}}},Ti=(e,t)=>{const n=pr(t);e.slots.default=()=>n},Yc=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=G(t),Un(t,"_",n)):Ai(t,e.slots={})}else e.slots={},t&&Ti(e,t);Un(e.slots,ts,1)},Xc=(e,t,n)=>{const{vnode:s,slots:r}=e;let o=!0,i=Z;if(s.shapeFlag&32){const l=t._;l?n&&l===1?o=!1:(he(r,t),!n&&l===1&&delete r._):(o=!t.$stable,Ai(t,r)),i=t}else t&&(Ti(e,t),i={default:1});if(o)for(const l in r)!wi(l)&&i[l]==null&&delete r[l]};function js(e,t,n,s,r=!1){if(k(e)){e.forEach((g,E)=>js(g,t&&(k(t)?t[E]:t),n,s,r));return}if(Rn(s)&&!r)return;const o=s.shapeFlag&4?ss(s.component)||s.component.proxy:s.el,i=r?null:o,{i:l,r:c}=e,f=t&&t.r,u=l.refs===Z?l.refs={}:l.refs,d=l.setupState;if(f!=null&&f!==c&&(ce(f)?(u[f]=null,W(d,f)&&(d[f]=null)):Re(f)&&(f.value=null)),M(c))ht(c,l,12,[i,u]);else{const g=ce(c),E=Re(c);if(g||E){const A=()=>{if(e.f){const C=g?W(d,c)?d[c]:u[c]:c.value;r?k(C)&&tr(C,o):k(C)?C.includes(o)||C.push(o):g?(u[c]=[o],W(d,c)&&(d[c]=u[c])):(c.value=[o],e.k&&(u[e.k]=c.value))}else g?(u[c]=i,W(d,c)&&(d[c]=i)):E&&(c.value=i,e.k&&(u[e.k]=i))};i?(A.id=-1,Ce(A,n)):A()}}}const Ce=vc;function Qc(e){return Zc(e)}function Zc(e,t){const n=Do();n.__VUE__=!0;const{insert:s,remove:r,patchProp:o,createElement:i,createText:l,createComment:c,setText:f,setElementText:u,parentNode:d,nextSibling:g,setScopeId:E=Le,insertStaticContent:A}=e,C=(a,h,m,b=null,y=null,w=null,O=void 0,v=null,T=!!h.dynamicChildren)=>{if(a===h)return;a&&!Ct(a,h)&&(b=yn(a),Be(a,y,w,!0),a=null),h.patchFlag===-2&&(T=!1,h.dynamicChildren=null);const{type:S,ref:R,shapeFlag:N}=h;switch(S){case es:D(a,h,m,b);break;case Ue:$(a,h,m,b);break;case Ln:a==null&&ee(h,m,b,O);break;case _e:I(a,h,m,b,y,w,O,v,T);break;default:N&1?re(a,h,m,b,y,w,O,v,T):N&6?ne(a,h,m,b,y,w,O,v,T):(N&64||N&128)&&S.process(a,h,m,b,y,w,O,v,T,It)}R!=null&&y&&js(R,a&&a.ref,w,h||a,!h)},D=(a,h,m,b)=>{if(a==null)s(h.el=l(h.children),m,b);else{const y=h.el=a.el;h.children!==a.children&&f(y,h.children)}},$=(a,h,m,b)=>{a==null?s(h.el=c(h.children||""),m,b):h.el=a.el},ee=(a,h,m,b)=>{[a.el,a.anchor]=A(a.children,h,m,b,a.el,a.anchor)},j=({el:a,anchor:h},m,b)=>{let y;for(;a&&a!==h;)y=g(a),s(a,m,b),a=y;s(h,m,b)},z=({el:a,anchor:h})=>{let m;for(;a&&a!==h;)m=g(a),r(a),a=m;r(h)},re=(a,h,m,b,y,w,O,v,T)=>{h.type==="svg"?O="svg":h.type==="math"&&(O="mathml"),a==null?H(h,m,b,y,w,O,v,T):oe(a,h,y,w,O,v,T)},H=(a,h,m,b,y,w,O,v)=>{let T,S;const{props:R,shapeFlag:N,transition:P,dirs:F}=a;if(T=a.el=i(a.type,w,R&&R.is,R),N&8?u(T,a.children):N&16&&B(a.children,T,null,b,y,ys(a,w),O,v),F&&bt(a,null,b,"created"),ye(T,a,a.scopeId,O,b),R){for(const J in R)J!=="value"&&!tn(J)&&o(T,J,null,R[J],w,a.children,b,y,We);"value"in R&&o(T,"value",null,R.value,w),(S=R.onVnodeBeforeMount)&&Me(S,b,a)}F&&bt(a,null,b,"beforeMount");const K=ea(y,P);K&&P.beforeEnter(T),s(T,h,m),((S=R&&R.onVnodeMounted)||K||F)&&Ce(()=>{S&&Me(S,b,a),K&&P.enter(T),F&&bt(a,null,b,"mounted")},y)},ye=(a,h,m,b,y)=>{if(m&&E(a,m),b)for(let w=0;w{for(let S=T;S{const v=h.el=a.el;let{patchFlag:T,dynamicChildren:S,dirs:R}=h;T|=a.patchFlag&16;const N=a.props||Z,P=h.props||Z;let F;if(m&&yt(m,!1),(F=P.onVnodeBeforeUpdate)&&Me(F,m,h,a),R&&bt(h,a,m,"beforeUpdate"),m&&yt(m,!0),S?Q(a.dynamicChildren,S,v,m,b,ys(h,y),w):O||X(a,h,v,null,m,b,ys(h,y),w,!1),T>0){if(T&16)ge(v,h,N,P,m,b,y);else if(T&2&&N.class!==P.class&&o(v,"class",null,P.class,y),T&4&&o(v,"style",N.style,P.style,y),T&8){const K=h.dynamicProps;for(let J=0;J{F&&Me(F,m,h,a),R&&bt(h,a,m,"updated")},b)},Q=(a,h,m,b,y,w,O)=>{for(let v=0;v{if(m!==b){if(m!==Z)for(const v in m)!tn(v)&&!(v in b)&&o(a,v,m[v],null,O,h.children,y,w,We);for(const v in b){if(tn(v))continue;const T=b[v],S=m[v];T!==S&&v!=="value"&&o(a,v,S,T,O,h.children,y,w,We)}"value"in b&&o(a,"value",m.value,b.value,O)}},I=(a,h,m,b,y,w,O,v,T)=>{const S=h.el=a?a.el:l(""),R=h.anchor=a?a.anchor:l("");let{patchFlag:N,dynamicChildren:P,slotScopeIds:F}=h;F&&(v=v?v.concat(F):F),a==null?(s(S,m,b),s(R,m,b),B(h.children||[],m,R,y,w,O,v,T)):N>0&&N&64&&P&&a.dynamicChildren?(Q(a.dynamicChildren,P,m,y,w,O,v),(h.key!=null||y&&h===y.subTree)&&Oi(a,h,!0)):X(a,h,m,R,y,w,O,v,T)},ne=(a,h,m,b,y,w,O,v,T)=>{h.slotScopeIds=v,a==null?h.shapeFlag&512?y.ctx.activate(h,m,b,O,T):Te(h,m,b,y,w,O,T):Jt(a,h,T)},Te=(a,h,m,b,y,w,O)=>{const v=a.component=ua(a,b,y);if(Qn(a)&&(v.ctx.renderer=It),da(v),v.asyncDep){if(y&&y.registerDep(v,fe),!a.el){const T=v.subTree=le(Ue);$(null,T,h,m)}}else fe(v,a,h,m,y,w,O)},Jt=(a,h,m)=>{const b=h.component=a.component;if(gc(a,h,m))if(b.asyncDep&&!b.asyncResolved){se(b,h,m);return}else b.next=h,uc(b.update),b.effect.dirty=!0,b.update();else h.el=a.el,b.vnode=h},fe=(a,h,m,b,y,w,O)=>{const v=()=>{if(a.isMounted){let{next:R,bu:N,u:P,parent:F,vnode:K}=a;{const Pt=Ri(a);if(Pt){R&&(R.el=K.el,se(a,R,O)),Pt.asyncDep.then(()=>{a.isUnmounted||v()});return}}let J=R,te;yt(a,!1),R?(R.el=K.el,se(a,R,O)):R=K,N&&On(N),(te=R.props&&R.props.onVnodeBeforeUpdate)&&Me(te,F,R,K),yt(a,!0);const de=gs(a),ke=a.subTree;a.subTree=de,C(ke,de,d(ke.el),yn(ke),a,y,w),R.el=de.el,J===null&&_c(a,de.el),P&&Ce(P,y),(te=R.props&&R.props.onVnodeUpdated)&&Ce(()=>Me(te,F,R,K),y)}else{let R;const{el:N,props:P}=h,{bm:F,m:K,parent:J}=a,te=Rn(h);if(yt(a,!1),F&&On(F),!te&&(R=P&&P.onVnodeBeforeMount)&&Me(R,J,h),yt(a,!0),N&&ds){const de=()=>{a.subTree=gs(a),ds(N,a.subTree,a,y,null)};te?h.type.__asyncLoader().then(()=>!a.isUnmounted&&de()):de()}else{const de=a.subTree=gs(a);C(null,de,m,b,a,y,w),h.el=de.el}if(K&&Ce(K,y),!te&&(R=P&&P.onVnodeMounted)){const de=h;Ce(()=>Me(R,J,de),y)}(h.shapeFlag&256||J&&Rn(J.vnode)&&J.vnode.shapeFlag&256)&&a.a&&Ce(a.a,y),a.isMounted=!0,h=m=b=null}},T=a.effect=new sr(v,Le,()=>dr(S),a.scope),S=a.update=()=>{T.dirty&&T.run()};S.id=a.uid,yt(a,!0),S()},se=(a,h,m)=>{h.component=a;const b=a.vnode.props;a.vnode=h,a.next=null,zc(a,h.props,b,m),Xc(a,h.children,m),Rt(),jr(a),xt()},X=(a,h,m,b,y,w,O,v,T=!1)=>{const S=a&&a.children,R=a?a.shapeFlag:0,N=h.children,{patchFlag:P,shapeFlag:F}=h;if(P>0){if(P&128){bn(S,N,m,b,y,w,O,v,T);return}else if(P&256){gt(S,N,m,b,y,w,O,v,T);return}}F&8?(R&16&&We(S,y,w),N!==S&&u(m,N)):R&16?F&16?bn(S,N,m,b,y,w,O,v,T):We(S,y,w,!0):(R&8&&u(m,""),F&16&&B(N,m,b,y,w,O,v,T))},gt=(a,h,m,b,y,w,O,v,T)=>{a=a||Ft,h=h||Ft;const S=a.length,R=h.length,N=Math.min(S,R);let P;for(P=0;PR?We(a,y,w,!0,!1,N):B(h,m,b,y,w,O,v,T,N)},bn=(a,h,m,b,y,w,O,v,T)=>{let S=0;const R=h.length;let N=a.length-1,P=R-1;for(;S<=N&&S<=P;){const F=a[S],K=h[S]=T?at(h[S]):$e(h[S]);if(Ct(F,K))C(F,K,m,null,y,w,O,v,T);else break;S++}for(;S<=N&&S<=P;){const F=a[N],K=h[P]=T?at(h[P]):$e(h[P]);if(Ct(F,K))C(F,K,m,null,y,w,O,v,T);else break;N--,P--}if(S>N){if(S<=P){const F=P+1,K=FP)for(;S<=N;)Be(a[S],y,w,!0),S++;else{const F=S,K=S,J=new Map;for(S=K;S<=P;S++){const Oe=h[S]=T?at(h[S]):$e(h[S]);Oe.key!=null&&J.set(Oe.key,S)}let te,de=0;const ke=P-K+1;let Pt=!1,Lr=0;const Yt=new Array(ke);for(S=0;S=ke){Be(Oe,y,w,!0);continue}let Ve;if(Oe.key!=null)Ve=J.get(Oe.key);else for(te=K;te<=P;te++)if(Yt[te-K]===0&&Ct(Oe,h[te])){Ve=te;break}Ve===void 0?Be(Oe,y,w,!0):(Yt[Ve-K]=S+1,Ve>=Lr?Lr=Ve:Pt=!0,C(Oe,h[Ve],m,null,y,w,O,v,T),de++)}const Ir=Pt?ta(Yt):Ft;for(te=Ir.length-1,S=ke-1;S>=0;S--){const Oe=K+S,Ve=h[Oe],Pr=Oe+1{const{el:w,type:O,transition:v,children:T,shapeFlag:S}=a;if(S&6){_t(a.component.subTree,h,m,b);return}if(S&128){a.suspense.move(h,m,b);return}if(S&64){O.move(a,h,m,It);return}if(O===_e){s(w,h,m);for(let N=0;Nv.enter(w),y);else{const{leave:N,delayLeave:P,afterLeave:F}=v,K=()=>s(w,h,m),J=()=>{N(w,()=>{K(),F&&F()})};P?P(w,K,J):J()}else s(w,h,m)},Be=(a,h,m,b=!1,y=!1)=>{const{type:w,props:O,ref:v,children:T,dynamicChildren:S,shapeFlag:R,patchFlag:N,dirs:P}=a;if(v!=null&&js(v,null,m,a,!0),R&256){h.ctx.deactivate(a);return}const F=R&1&&P,K=!Rn(a);let J;if(K&&(J=O&&O.onVnodeBeforeUnmount)&&Me(J,h,a),R&6)Sl(a.component,m,b);else{if(R&128){a.suspense.unmount(m,b);return}F&&bt(a,null,h,"beforeUnmount"),R&64?a.type.remove(a,h,m,y,It,b):S&&(w!==_e||N>0&&N&64)?We(S,h,m,!1,!0):(w===_e&&N&384||!y&&R&16)&&We(T,h,m),b&&Rr(a)}(K&&(J=O&&O.onVnodeUnmounted)||F)&&Ce(()=>{J&&Me(J,h,a),F&&bt(a,null,h,"unmounted")},m)},Rr=a=>{const{type:h,el:m,anchor:b,transition:y}=a;if(h===_e){yl(m,b);return}if(h===Ln){z(a);return}const w=()=>{r(m),y&&!y.persisted&&y.afterLeave&&y.afterLeave()};if(a.shapeFlag&1&&y&&!y.persisted){const{leave:O,delayLeave:v}=y,T=()=>O(m,w);v?v(a.el,w,T):T()}else w()},yl=(a,h)=>{let m;for(;a!==h;)m=g(a),r(a),a=m;r(h)},Sl=(a,h,m)=>{const{bum:b,scope:y,update:w,subTree:O,um:v}=a;b&&On(b),y.stop(),w&&(w.active=!1,Be(O,a,h,m)),v&&Ce(v,h),Ce(()=>{a.isUnmounted=!0},h),h&&h.pendingBranch&&!h.isUnmounted&&a.asyncDep&&!a.asyncResolved&&a.suspenseId===h.pendingId&&(h.deps--,h.deps===0&&h.resolve())},We=(a,h,m,b=!1,y=!1,w=0)=>{for(let O=w;Oa.shapeFlag&6?yn(a.component.subTree):a.shapeFlag&128?a.suspense.next():g(a.anchor||a.el);let us=!1;const xr=(a,h,m)=>{a==null?h._vnode&&Be(h._vnode,null,null,!0):C(h._vnode||null,a,h,null,null,null,m),us||(us=!0,jr(),ii(),us=!1),h._vnode=a},It={p:C,um:Be,m:_t,r:Rr,mt:Te,mc:B,pc:X,pbc:Q,n:yn,o:e};let fs,ds;return t&&([fs,ds]=t(It)),{render:xr,hydrate:fs,createApp:qc(xr,fs)}}function ys({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function yt({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function ea(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function Oi(e,t,n=!1){const s=e.children,r=t.children;if(k(s)&&k(r))for(let o=0;o>1,e[n[l]]0&&(t[s]=n[o-1]),n[o]=s)}}for(o=n.length,i=n[o-1];o-- >0;)n[o]=i,i=t[i];return n}function Ri(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:Ri(t)}const na=e=>e.__isTeleport,_e=Symbol.for("v-fgt"),es=Symbol.for("v-txt"),Ue=Symbol.for("v-cmt"),Ln=Symbol.for("v-stc"),on=[];let Fe=null;function x(e=!1){on.push(Fe=e?null:[])}function sa(){on.pop(),Fe=on[on.length-1]||null}let un=1;function eo(e){un+=e}function xi(e){return e.dynamicChildren=un>0?Fe||Ft:null,sa(),un>0&&Fe&&Fe.push(e),e}function L(e,t,n,s,r,o){return xi(p(e,t,n,s,r,o,!0))}function Hs(e,t,n,s,r){return xi(le(e,t,n,s,r,!0))}function Ks(e){return e?e.__v_isVNode===!0:!1}function Ct(e,t){return e.type===t.type&&e.key===t.key}const ts="__vInternal",Li=({key:e})=>e??null,In=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?ce(e)||Re(e)||M(e)?{i:Ee,r:e,k:t,f:!!n}:e:null);function p(e,t=null,n=null,s=0,r=null,o=e===_e?0:1,i=!1,l=!1){const c={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&Li(t),ref:t&&In(t),scopeId:Xn,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:o,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:Ee};return l?(mr(c,n),o&128&&e.normalize(c)):n&&(c.shapeFlag|=ce(n)?8:16),un>0&&!i&&Fe&&(c.patchFlag>0||o&6)&&c.patchFlag!==32&&Fe.push(c),c}const le=ra;function ra(e,t=null,n=null,s=0,r=null,o=!1){if((!e||e===bc)&&(e=Ue),Ks(e)){const l=mt(e,t,!0);return n&&mr(l,n),un>0&&!o&&Fe&&(l.shapeFlag&6?Fe[Fe.indexOf(e)]=l:Fe.push(l)),l.patchFlag|=-2,l}if(_a(e)&&(e=e.__vccOpts),t){t=oa(t);let{class:l,style:c}=t;l&&!ce(l)&&(t.class=ve(l)),Y(c)&&(ei(c)&&!k(c)&&(c=he({},c)),t.style=Wn(c))}const i=ce(e)?1:Sc(e)?128:na(e)?64:Y(e)?4:M(e)?2:0;return p(e,t,n,s,r,i,o,!0)}function oa(e){return e?ei(e)||ts in e?he({},e):e:null}function mt(e,t,n=!1){const{props:s,ref:r,patchFlag:o,children:i}=e,l=t?la(s||{},t):s;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&Li(l),ref:t&&t.ref?n&&r?k(r)?r.concat(In(t)):[r,In(t)]:In(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:i,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==_e?o===-1?16:o|16:o,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&mt(e.ssContent),ssFallback:e.ssFallback&&mt(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function pe(e=" ",t=0){return le(es,null,e,t)}function ia(e,t){const n=le(Ln,null,e);return n.staticCount=t,n}function V(e="",t=!1){return t?(x(),Hs(Ue,null,e)):le(Ue,null,e)}function $e(e){return e==null||typeof e=="boolean"?le(Ue):k(e)?le(_e,null,e.slice()):typeof e=="object"?at(e):le(es,null,String(e))}function at(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:mt(e)}function mr(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(k(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),mr(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!(ts in t)?t._ctx=Ee:r===3&&Ee&&(Ee.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else M(t)?(t={default:t,_ctx:Ee},n=32):(t=String(t),s&64?(n=16,t=[pe(t)]):n=8);e.children=t,e.shapeFlag|=n}function la(...e){const t={};for(let n=0;nme||Ee;let Vn,qs;{const e=Do(),t=(n,s)=>{let r;return(r=e[n])||(r=e[n]=[]),r.push(s),o=>{r.length>1?r.forEach(i=>i(o)):r[0](o)}};Vn=t("__VUE_INSTANCE_SETTERS__",n=>me=n),qs=t("__VUE_SSR_SETTERS__",n=>ns=n)}const pn=e=>{const t=me;return Vn(e),e.scope.on(),()=>{e.scope.off(),Vn(t)}},to=()=>{me&&me.scope.off(),Vn(null)};function Ii(e){return e.vnode.shapeFlag&4}let ns=!1;function da(e,t=!1){t&&qs(t);const{props:n,children:s}=e.vnode,r=Ii(e);Gc(e,n,r,t),Yc(e,s);const o=r?ha(e,t):void 0;return t&&qs(!1),o}function ha(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=ti(new Proxy(e.ctx,Bc));const{setup:s}=n;if(s){const r=e.setupContext=s.length>1?ma(e):null,o=pn(e);Rt();const i=ht(s,e,0,[e.props,r]);if(xt(),o(),No(i)){if(i.then(to,to),t)return i.then(l=>{no(e,l,t)}).catch(l=>{Jn(l,e,0)});e.asyncDep=i}else no(e,i,t)}else Pi(e,t)}function no(e,t,n){M(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Y(t)&&(e.setupState=si(t)),Pi(e,n)}let so;function Pi(e,t,n){const s=e.type;if(!e.render){if(!t&&so&&!s.render){const r=s.template||hr(e).template;if(r){const{isCustomElement:o,compilerOptions:i}=e.appContext.config,{delimiters:l,compilerOptions:c}=s,f=he(he({isCustomElement:o,delimiters:l},i),c);s.render=so(r,f)}}e.render=s.render||Le}{const r=pn(e);Rt();try{Vc(e)}finally{xt(),r()}}}function pa(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,n){return we(e,"get","$attrs"),t[n]}}))}function ma(e){const t=n=>{e.exposed=n||{}};return{get attrs(){return pa(e)},slots:e.slots,emit:e.emit,expose:t}}function ss(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(si(ti(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in sn)return sn[n](e)},has(t,n){return n in t||n in sn}}))}function ga(e,t=!0){return M(e)?e.displayName||e.name:e.name||t&&e.__name}function _a(e){return M(e)&&"__vccOpts"in e}const ki=(e,t)=>sc(e,t,ns);function ba(e,t,n){const s=arguments.length;return s===2?Y(t)&&!k(t)?Ks(t)?le(e,null,[t]):le(e,t):le(e,null,t):(s>3?n=Array.prototype.slice.call(arguments,2):s===3&&Ks(n)&&(n=[n]),le(e,t,n))}const ya="3.4.21";/** +* @vue/runtime-dom v3.4.21 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/const Sa="http://www.w3.org/2000/svg",va="http://www.w3.org/1998/Math/MathML",ut=typeof document<"u"?document:null,ro=ut&&ut.createElement("template"),Ea={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t==="svg"?ut.createElementNS(Sa,e):t==="mathml"?ut.createElementNS(va,e):ut.createElement(e,n?{is:n}:void 0);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>ut.createTextNode(e),createComment:e=>ut.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>ut.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,o){const i=n?n.previousSibling:t.lastChild;if(r&&(r===o||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===o||!(r=r.nextSibling)););else{ro.innerHTML=s==="svg"?`${e}`:s==="mathml"?`${e}`:e;const l=ro.content;if(s==="svg"||s==="mathml"){const c=l.firstChild;for(;c.firstChild;)l.appendChild(c.firstChild);l.removeChild(c)}t.insertBefore(l,n)}return[i?i.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},st="transition",Xt="animation",fn=Symbol("_vtc"),gr=(e,{slots:t})=>ba(Oc,Ca(e),t);gr.displayName="Transition";const Ni={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};gr.props=he({},hi,Ni);const St=(e,t=[])=>{k(e)?e.forEach(n=>n(...t)):e&&e(...t)},oo=e=>e?k(e)?e.some(t=>t.length>1):e.length>1:!1;function Ca(e){const t={};for(const I in e)I in Ni||(t[I]=e[I]);if(e.css===!1)return t;const{name:n="v",type:s,duration:r,enterFromClass:o=`${n}-enter-from`,enterActiveClass:i=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:c=o,appearActiveClass:f=i,appearToClass:u=l,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:g=`${n}-leave-active`,leaveToClass:E=`${n}-leave-to`}=e,A=wa(r),C=A&&A[0],D=A&&A[1],{onBeforeEnter:$,onEnter:ee,onEnterCancelled:j,onLeave:z,onLeaveCancelled:re,onBeforeAppear:H=$,onAppear:ye=ee,onAppearCancelled:B=j}=t,oe=(I,ne,Te)=>{vt(I,ne?u:l),vt(I,ne?f:i),Te&&Te()},Q=(I,ne)=>{I._isLeaving=!1,vt(I,d),vt(I,E),vt(I,g),ne&&ne()},ge=I=>(ne,Te)=>{const Jt=I?ye:ee,fe=()=>oe(ne,I,Te);St(Jt,[ne,fe]),io(()=>{vt(ne,I?c:o),rt(ne,I?u:l),oo(Jt)||lo(ne,s,C,fe)})};return he(t,{onBeforeEnter(I){St($,[I]),rt(I,o),rt(I,i)},onBeforeAppear(I){St(H,[I]),rt(I,c),rt(I,f)},onEnter:ge(!1),onAppear:ge(!0),onLeave(I,ne){I._isLeaving=!0;const Te=()=>Q(I,ne);rt(I,d),Oa(),rt(I,g),io(()=>{I._isLeaving&&(vt(I,d),rt(I,E),oo(z)||lo(I,s,D,Te))}),St(z,[I,Te])},onEnterCancelled(I){oe(I,!1),St(j,[I])},onAppearCancelled(I){oe(I,!0),St(B,[I])},onLeaveCancelled(I){Q(I),St(re,[I])}})}function wa(e){if(e==null)return null;if(Y(e))return[Ss(e.enter),Ss(e.leave)];{const t=Ss(e);return[t,t]}}function Ss(e){return Tl(e)}function rt(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[fn]||(e[fn]=new Set)).add(t)}function vt(e,t){t.split(/\s+/).forEach(s=>s&&e.classList.remove(s));const n=e[fn];n&&(n.delete(t),n.size||(e[fn]=void 0))}function io(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let Aa=0;function lo(e,t,n,s){const r=e._endId=++Aa,o=()=>{r===e._endId&&s()};if(n)return setTimeout(o,n);const{type:i,timeout:l,propCount:c}=Ta(e,t);if(!i)return s();const f=i+"end";let u=0;const d=()=>{e.removeEventListener(f,g),o()},g=E=>{E.target===e&&++u>=c&&d()};setTimeout(()=>{u(n[A]||"").split(", "),r=s(`${st}Delay`),o=s(`${st}Duration`),i=co(r,o),l=s(`${Xt}Delay`),c=s(`${Xt}Duration`),f=co(l,c);let u=null,d=0,g=0;t===st?i>0&&(u=st,d=i,g=o.length):t===Xt?f>0&&(u=Xt,d=f,g=c.length):(d=Math.max(i,f),u=d>0?i>f?st:Xt:null,g=u?u===st?o.length:c.length:0);const E=u===st&&/\b(transform|all)(,|$)/.test(s(`${st}Property`).toString());return{type:u,timeout:d,propCount:g,hasTransform:E}}function co(e,t){for(;e.lengthao(n)+ao(e[s])))}function ao(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function Oa(){return document.body.offsetHeight}function Ra(e,t,n){const s=e[fn];s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const uo=Symbol("_vod"),xa=Symbol("_vsh"),La=Symbol(""),Ia=/(^|;)\s*display\s*:/;function Pa(e,t,n){const s=e.style,r=ce(n);let o=!1;if(n&&!r){if(t)if(ce(t))for(const i of t.split(";")){const l=i.slice(0,i.indexOf(":")).trim();n[l]==null&&Pn(s,l,"")}else for(const i in t)n[i]==null&&Pn(s,i,"");for(const i in n)i==="display"&&(o=!0),Pn(s,i,n[i])}else if(r){if(t!==n){const i=s[La];i&&(n+=";"+i),s.cssText=n,o=Ia.test(n)}}else t&&e.removeAttribute("style");uo in e&&(e[uo]=o?s.display:"",e[xa]&&(s.display="none"))}const fo=/\s*!important$/;function Pn(e,t,n){if(k(n))n.forEach(s=>Pn(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=ka(e,t);fo.test(n)?e.setProperty(jt(s),n.replace(fo,""),"important"):e[s]=n}}const ho=["Webkit","Moz","ms"],vs={};function ka(e,t){const n=vs[t];if(n)return n;let s=Ke(t);if(s!=="filter"&&s in e)return vs[t]=s;s=qn(s);for(let r=0;rEs||(Va.then(()=>Es=0),Es=Date.now());function $a(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;Ie(ja(s,n.value),t,5,[s])};return n.value=e,n.attached=Ma(),n}function ja(e,t){if(k(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>r=>!r._stopped&&s&&s(r))}else return t}const _o=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,Ha=(e,t,n,s,r,o,i,l,c)=>{const f=r==="svg";t==="class"?Ra(e,s,f):t==="style"?Pa(e,n,s):jn(t)?er(t)||Da(e,t,n,s,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):Ka(e,t,s,f))?Fa(e,t,s,o,i,l,c):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),Na(e,t,s,f))};function Ka(e,t,n,s){if(s)return!!(t==="innerHTML"||t==="textContent"||t in e&&_o(t)&&M(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const r=e.tagName;if(r==="IMG"||r==="VIDEO"||r==="CANVAS"||r==="SOURCE")return!1}return _o(t)&&ce(n)?!1:t in e}const Mt=e=>{const t=e.props["onUpdate:modelValue"]||!1;return k(t)?n=>On(t,n):t};function qa(e){e.target.composing=!0}function bo(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const Ye=Symbol("_assign"),en={created(e,{modifiers:{lazy:t,trim:n,number:s}},r){e[Ye]=Mt(r);const o=s||r.props&&r.props.type==="number";ft(e,t?"change":"input",i=>{if(i.target.composing)return;let l=e.value;n&&(l=l.trim()),o&&(l=Rs(l)),e[Ye](l)}),n&&ft(e,"change",()=>{e.value=e.value.trim()}),t||(ft(e,"compositionstart",qa),ft(e,"compositionend",bo),ft(e,"change",bo))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,modifiers:{lazy:n,trim:s,number:r}},o){if(e[Ye]=Mt(o),e.composing)return;const i=r||e.type==="number"?Rs(e.value):e.value,l=t??"";i!==l&&(document.activeElement===e&&e.type!=="range"&&(n||s&&e.value.trim()===l)||(e.value=l))}},ot={deep:!0,created(e,t,n){e[Ye]=Mt(n),ft(e,"change",()=>{const s=e._modelValue,r=Fi(e),o=e.checked,i=e[Ye];if(k(s)){const l=Vo(s,r),c=l!==-1;if(o&&!c)i(s.concat(r));else if(!o&&c){const f=[...s];f.splice(l,1),i(f)}}else if(Hn(s)){const l=new Set(s);o?l.add(r):l.delete(r),i(l)}else i(Ui(e,o))})},mounted:yo,beforeUpdate(e,t,n){e[Ye]=Mt(n),yo(e,t,n)}};function yo(e,{value:t,oldValue:n},s){e._modelValue=t,k(t)?e.checked=Vo(t,s.props.value)>-1:Hn(t)?e.checked=t.has(s.props.value):t!==n&&(e.checked=Vt(t,Ui(e,!0)))}const Ge={created(e,{value:t},n){e.checked=Vt(t,n.props.value),e[Ye]=Mt(n),ft(e,"change",()=>{e[Ye](Fi(e))})},beforeUpdate(e,{value:t,oldValue:n},s){e[Ye]=Mt(s),t!==n&&(e.checked=Vt(t,s.props.value))}};function Fi(e){return"_value"in e?e._value:e.value}function Ui(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const Wa=he({patchProp:Ha},Ea);let So;function Ga(){return So||(So=Qc(Wa))}const za=(...e)=>{const t=Ga().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=Ya(s);if(!r)return;const o=t._component;!M(o)&&!o.render&&!o.template&&(o.template=r.innerHTML),r.innerHTML="";const i=n(r,!1,Ja(r));return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),i},t};function Ja(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function Ya(e){return ce(e)?document.querySelector(e):e}function Di(e,t){return function(){return e.apply(t,arguments)}}const{toString:Xa}=Object.prototype,{getPrototypeOf:_r}=Object,rs=(e=>t=>{const n=Xa.call(t);return e[n]||(e[n]=n.slice(8,-1).toLowerCase())})(Object.create(null)),qe=e=>(e=e.toLowerCase(),t=>rs(t)===e),os=e=>t=>typeof t===e,{isArray:qt}=Array,dn=os("undefined");function Qa(e){return e!==null&&!dn(e)&&e.constructor!==null&&!dn(e.constructor)&&Pe(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const Bi=qe("ArrayBuffer");function Za(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&Bi(e.buffer),t}const eu=os("string"),Pe=os("function"),Vi=os("number"),is=e=>e!==null&&typeof e=="object",tu=e=>e===!0||e===!1,kn=e=>{if(rs(e)!=="object")return!1;const t=_r(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Symbol.toStringTag in e)&&!(Symbol.iterator in e)},nu=qe("Date"),su=qe("File"),ru=qe("Blob"),ou=qe("FileList"),iu=e=>is(e)&&Pe(e.pipe),lu=e=>{let t;return e&&(typeof FormData=="function"&&e instanceof FormData||Pe(e.append)&&((t=rs(e))==="formdata"||t==="object"&&Pe(e.toString)&&e.toString()==="[object FormData]"))},cu=qe("URLSearchParams"),au=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function mn(e,t,{allOwnKeys:n=!1}={}){if(e===null||typeof e>"u")return;let s,r;if(typeof e!="object"&&(e=[e]),qt(e))for(s=0,r=e.length;s0;)if(r=n[s],t===r.toLowerCase())return r;return null}const $i=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global,ji=e=>!dn(e)&&e!==$i;function Ws(){const{caseless:e}=ji(this)&&this||{},t={},n=(s,r)=>{const o=e&&Mi(t,r)||r;kn(t[o])&&kn(s)?t[o]=Ws(t[o],s):kn(s)?t[o]=Ws({},s):qt(s)?t[o]=s.slice():t[o]=s};for(let s=0,r=arguments.length;s(mn(t,(r,o)=>{n&&Pe(r)?e[o]=Di(r,n):e[o]=r},{allOwnKeys:s}),e),fu=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),du=(e,t,n,s)=>{e.prototype=Object.create(t.prototype,s),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},hu=(e,t,n,s)=>{let r,o,i;const l={};if(t=t||{},e==null)return t;do{for(r=Object.getOwnPropertyNames(e),o=r.length;o-- >0;)i=r[o],(!s||s(i,e,t))&&!l[i]&&(t[i]=e[i],l[i]=!0);e=n!==!1&&_r(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},pu=(e,t,n)=>{e=String(e),(n===void 0||n>e.length)&&(n=e.length),n-=t.length;const s=e.indexOf(t,n);return s!==-1&&s===n},mu=e=>{if(!e)return null;if(qt(e))return e;let t=e.length;if(!Vi(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},gu=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&_r(Uint8Array)),_u=(e,t)=>{const s=(e&&e[Symbol.iterator]).call(e);let r;for(;(r=s.next())&&!r.done;){const o=r.value;t.call(e,o[0],o[1])}},bu=(e,t)=>{let n;const s=[];for(;(n=e.exec(t))!==null;)s.push(n);return s},yu=qe("HTMLFormElement"),Su=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(n,s,r){return s.toUpperCase()+r}),vo=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),vu=qe("RegExp"),Hi=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),s={};mn(n,(r,o)=>{let i;(i=t(r,o,e))!==!1&&(s[o]=i||r)}),Object.defineProperties(e,s)},Eu=e=>{Hi(e,(t,n)=>{if(Pe(e)&&["arguments","caller","callee"].indexOf(n)!==-1)return!1;const s=e[n];if(Pe(s)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")})}})},Cu=(e,t)=>{const n={},s=r=>{r.forEach(o=>{n[o]=!0})};return qt(e)?s(e):s(String(e).split(t)),n},wu=()=>{},Au=(e,t)=>(e=+e,Number.isFinite(e)?e:t),Cs="abcdefghijklmnopqrstuvwxyz",Eo="0123456789",Ki={DIGIT:Eo,ALPHA:Cs,ALPHA_DIGIT:Cs+Cs.toUpperCase()+Eo},Tu=(e=16,t=Ki.ALPHA_DIGIT)=>{let n="";const{length:s}=t;for(;e--;)n+=t[Math.random()*s|0];return n};function Ou(e){return!!(e&&Pe(e.append)&&e[Symbol.toStringTag]==="FormData"&&e[Symbol.iterator])}const Ru=e=>{const t=new Array(10),n=(s,r)=>{if(is(s)){if(t.indexOf(s)>=0)return;if(!("toJSON"in s)){t[r]=s;const o=qt(s)?[]:{};return mn(s,(i,l)=>{const c=n(i,r+1);!dn(c)&&(o[l]=c)}),t[r]=void 0,o}}return s};return n(e,0)},xu=qe("AsyncFunction"),Lu=e=>e&&(is(e)||Pe(e))&&Pe(e.then)&&Pe(e.catch),_={isArray:qt,isArrayBuffer:Bi,isBuffer:Qa,isFormData:lu,isArrayBufferView:Za,isString:eu,isNumber:Vi,isBoolean:tu,isObject:is,isPlainObject:kn,isUndefined:dn,isDate:nu,isFile:su,isBlob:ru,isRegExp:vu,isFunction:Pe,isStream:iu,isURLSearchParams:cu,isTypedArray:gu,isFileList:ou,forEach:mn,merge:Ws,extend:uu,trim:au,stripBOM:fu,inherits:du,toFlatObject:hu,kindOf:rs,kindOfTest:qe,endsWith:pu,toArray:mu,forEachEntry:_u,matchAll:bu,isHTMLForm:yu,hasOwnProperty:vo,hasOwnProp:vo,reduceDescriptors:Hi,freezeMethods:Eu,toObjectSet:Cu,toCamelCase:Su,noop:wu,toFiniteNumber:Au,findKey:Mi,global:$i,isContextDefined:ji,ALPHABET:Ki,generateString:Tu,isSpecCompliantForm:Ou,toJSONObject:Ru,isAsyncFn:xu,isThenable:Lu};function q(e,t,n,s,r){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),s&&(this.request=s),r&&(this.response=r)}_.inherits(q,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:_.toJSONObject(this.config),code:this.code,status:this.response&&this.response.status?this.response.status:null}}});const qi=q.prototype,Wi={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(e=>{Wi[e]={value:e}});Object.defineProperties(q,Wi);Object.defineProperty(qi,"isAxiosError",{value:!0});q.from=(e,t,n,s,r,o)=>{const i=Object.create(qi);return _.toFlatObject(e,i,function(c){return c!==Error.prototype},l=>l!=="isAxiosError"),q.call(i,e.message,t,n,s,r),i.cause=e,i.name=e.name,o&&Object.assign(i,o),i};const Iu=null;function Gs(e){return _.isPlainObject(e)||_.isArray(e)}function Gi(e){return _.endsWith(e,"[]")?e.slice(0,-2):e}function Co(e,t,n){return e?e.concat(t).map(function(r,o){return r=Gi(r),!n&&o?"["+r+"]":r}).join(n?".":""):t}function Pu(e){return _.isArray(e)&&!e.some(Gs)}const ku=_.toFlatObject(_,{},null,function(t){return/^is[A-Z]/.test(t)});function ls(e,t,n){if(!_.isObject(e))throw new TypeError("target must be an object");t=t||new FormData,n=_.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(C,D){return!_.isUndefined(D[C])});const s=n.metaTokens,r=n.visitor||u,o=n.dots,i=n.indexes,c=(n.Blob||typeof Blob<"u"&&Blob)&&_.isSpecCompliantForm(t);if(!_.isFunction(r))throw new TypeError("visitor must be a function");function f(A){if(A===null)return"";if(_.isDate(A))return A.toISOString();if(!c&&_.isBlob(A))throw new q("Blob is not supported. Use a Buffer instead.");return _.isArrayBuffer(A)||_.isTypedArray(A)?c&&typeof Blob=="function"?new Blob([A]):Buffer.from(A):A}function u(A,C,D){let $=A;if(A&&!D&&typeof A=="object"){if(_.endsWith(C,"{}"))C=s?C:C.slice(0,-2),A=JSON.stringify(A);else if(_.isArray(A)&&Pu(A)||(_.isFileList(A)||_.endsWith(C,"[]"))&&($=_.toArray(A)))return C=Gi(C),$.forEach(function(j,z){!(_.isUndefined(j)||j===null)&&t.append(i===!0?Co([C],z,o):i===null?C:C+"[]",f(j))}),!1}return Gs(A)?!0:(t.append(Co(D,C,o),f(A)),!1)}const d=[],g=Object.assign(ku,{defaultVisitor:u,convertValue:f,isVisitable:Gs});function E(A,C){if(!_.isUndefined(A)){if(d.indexOf(A)!==-1)throw Error("Circular reference detected in "+C.join("."));d.push(A),_.forEach(A,function($,ee){(!(_.isUndefined($)||$===null)&&r.call(t,$,_.isString(ee)?ee.trim():ee,C,g))===!0&&E($,C?C.concat(ee):[ee])}),d.pop()}}if(!_.isObject(e))throw new TypeError("data must be an object");return E(e),t}function wo(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(s){return t[s]})}function br(e,t){this._pairs=[],e&&ls(e,this,t)}const zi=br.prototype;zi.append=function(t,n){this._pairs.push([t,n])};zi.toString=function(t){const n=t?function(s){return t.call(this,s,wo)}:wo;return this._pairs.map(function(r){return n(r[0])+"="+n(r[1])},"").join("&")};function Nu(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function Ji(e,t,n){if(!t)return e;const s=n&&n.encode||Nu,r=n&&n.serialize;let o;if(r?o=r(t,n):o=_.isURLSearchParams(t)?t.toString():new br(t,n).toString(s),o){const i=e.indexOf("#");i!==-1&&(e=e.slice(0,i)),e+=(e.indexOf("?")===-1?"?":"&")+o}return e}class Ao{constructor(){this.handlers=[]}use(t,n,s){return this.handlers.push({fulfilled:t,rejected:n,synchronous:s?s.synchronous:!1,runWhen:s?s.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){_.forEach(this.handlers,function(s){s!==null&&t(s)})}}const Yi={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},Fu=typeof URLSearchParams<"u"?URLSearchParams:br,Uu=typeof FormData<"u"?FormData:null,Du=typeof Blob<"u"?Blob:null,Bu={isBrowser:!0,classes:{URLSearchParams:Fu,FormData:Uu,Blob:Du},protocols:["http","https","file","blob","url","data"]},Xi=typeof window<"u"&&typeof document<"u",Vu=(e=>Xi&&["ReactNative","NativeScript","NS"].indexOf(e)<0)(typeof navigator<"u"&&navigator.product),Mu=typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function",$u=Object.freeze(Object.defineProperty({__proto__:null,hasBrowserEnv:Xi,hasStandardBrowserEnv:Vu,hasStandardBrowserWebWorkerEnv:Mu},Symbol.toStringTag,{value:"Module"})),He={...$u,...Bu};function ju(e,t){return ls(e,new He.classes.URLSearchParams,Object.assign({visitor:function(n,s,r,o){return He.isNode&&_.isBuffer(n)?(this.append(s,n.toString("base64")),!1):o.defaultVisitor.apply(this,arguments)}},t))}function Hu(e){return _.matchAll(/\w+|\[(\w*)]/g,e).map(t=>t[0]==="[]"?"":t[1]||t[0])}function Ku(e){const t={},n=Object.keys(e);let s;const r=n.length;let o;for(s=0;s=n.length;return i=!i&&_.isArray(r)?r.length:i,c?(_.hasOwnProp(r,i)?r[i]=[r[i],s]:r[i]=s,!l):((!r[i]||!_.isObject(r[i]))&&(r[i]=[]),t(n,s,r[i],o)&&_.isArray(r[i])&&(r[i]=Ku(r[i])),!l)}if(_.isFormData(e)&&_.isFunction(e.entries)){const n={};return _.forEachEntry(e,(s,r)=>{t(Hu(s),r,n,0)}),n}return null}function qu(e,t,n){if(_.isString(e))try{return(t||JSON.parse)(e),_.trim(e)}catch(s){if(s.name!=="SyntaxError")throw s}return(n||JSON.stringify)(e)}const yr={transitional:Yi,adapter:["xhr","http"],transformRequest:[function(t,n){const s=n.getContentType()||"",r=s.indexOf("application/json")>-1,o=_.isObject(t);if(o&&_.isHTMLForm(t)&&(t=new FormData(t)),_.isFormData(t))return r?JSON.stringify(Qi(t)):t;if(_.isArrayBuffer(t)||_.isBuffer(t)||_.isStream(t)||_.isFile(t)||_.isBlob(t))return t;if(_.isArrayBufferView(t))return t.buffer;if(_.isURLSearchParams(t))return n.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let l;if(o){if(s.indexOf("application/x-www-form-urlencoded")>-1)return ju(t,this.formSerializer).toString();if((l=_.isFileList(t))||s.indexOf("multipart/form-data")>-1){const c=this.env&&this.env.FormData;return ls(l?{"files[]":t}:t,c&&new c,this.formSerializer)}}return o||r?(n.setContentType("application/json",!1),qu(t)):t}],transformResponse:[function(t){const n=this.transitional||yr.transitional,s=n&&n.forcedJSONParsing,r=this.responseType==="json";if(t&&_.isString(t)&&(s&&!this.responseType||r)){const i=!(n&&n.silentJSONParsing)&&r;try{return JSON.parse(t)}catch(l){if(i)throw l.name==="SyntaxError"?q.from(l,q.ERR_BAD_RESPONSE,this,null,this.response):l}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:He.classes.FormData,Blob:He.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};_.forEach(["delete","get","head","post","put","patch"],e=>{yr.headers[e]={}});const Sr=yr,Wu=_.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Gu=e=>{const t={};let n,s,r;return e&&e.split(` +`).forEach(function(i){r=i.indexOf(":"),n=i.substring(0,r).trim().toLowerCase(),s=i.substring(r+1).trim(),!(!n||t[n]&&Wu[n])&&(n==="set-cookie"?t[n]?t[n].push(s):t[n]=[s]:t[n]=t[n]?t[n]+", "+s:s)}),t},To=Symbol("internals");function Qt(e){return e&&String(e).trim().toLowerCase()}function Nn(e){return e===!1||e==null?e:_.isArray(e)?e.map(Nn):String(e)}function zu(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let s;for(;s=n.exec(e);)t[s[1]]=s[2];return t}const Ju=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function ws(e,t,n,s,r){if(_.isFunction(s))return s.call(this,t,n);if(r&&(t=n),!!_.isString(t)){if(_.isString(s))return t.indexOf(s)!==-1;if(_.isRegExp(s))return s.test(t)}}function Yu(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,n,s)=>n.toUpperCase()+s)}function Xu(e,t){const n=_.toCamelCase(" "+t);["get","set","has"].forEach(s=>{Object.defineProperty(e,s+n,{value:function(r,o,i){return this[s].call(this,t,r,o,i)},configurable:!0})})}class cs{constructor(t){t&&this.set(t)}set(t,n,s){const r=this;function o(l,c,f){const u=Qt(c);if(!u)throw new Error("header name must be a non-empty string");const d=_.findKey(r,u);(!d||r[d]===void 0||f===!0||f===void 0&&r[d]!==!1)&&(r[d||c]=Nn(l))}const i=(l,c)=>_.forEach(l,(f,u)=>o(f,u,c));return _.isPlainObject(t)||t instanceof this.constructor?i(t,n):_.isString(t)&&(t=t.trim())&&!Ju(t)?i(Gu(t),n):t!=null&&o(n,t,s),this}get(t,n){if(t=Qt(t),t){const s=_.findKey(this,t);if(s){const r=this[s];if(!n)return r;if(n===!0)return zu(r);if(_.isFunction(n))return n.call(this,r,s);if(_.isRegExp(n))return n.exec(r);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,n){if(t=Qt(t),t){const s=_.findKey(this,t);return!!(s&&this[s]!==void 0&&(!n||ws(this,this[s],s,n)))}return!1}delete(t,n){const s=this;let r=!1;function o(i){if(i=Qt(i),i){const l=_.findKey(s,i);l&&(!n||ws(s,s[l],l,n))&&(delete s[l],r=!0)}}return _.isArray(t)?t.forEach(o):o(t),r}clear(t){const n=Object.keys(this);let s=n.length,r=!1;for(;s--;){const o=n[s];(!t||ws(this,this[o],o,t,!0))&&(delete this[o],r=!0)}return r}normalize(t){const n=this,s={};return _.forEach(this,(r,o)=>{const i=_.findKey(s,o);if(i){n[i]=Nn(r),delete n[o];return}const l=t?Yu(o):String(o).trim();l!==o&&delete n[o],n[l]=Nn(r),s[l]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){const n=Object.create(null);return _.forEach(this,(s,r)=>{s!=null&&s!==!1&&(n[r]=t&&_.isArray(s)?s.join(", "):s)}),n}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,n])=>t+": "+n).join(` +`)}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...n){const s=new this(t);return n.forEach(r=>s.set(r)),s}static accessor(t){const s=(this[To]=this[To]={accessors:{}}).accessors,r=this.prototype;function o(i){const l=Qt(i);s[l]||(Xu(r,i),s[l]=!0)}return _.isArray(t)?t.forEach(o):o(t),this}}cs.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);_.reduceDescriptors(cs.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(s){this[n]=s}}});_.freezeMethods(cs);const Xe=cs;function As(e,t){const n=this||Sr,s=t||n,r=Xe.from(s.headers);let o=s.data;return _.forEach(e,function(l){o=l.call(n,o,r.normalize(),t?t.status:void 0)}),r.normalize(),o}function Zi(e){return!!(e&&e.__CANCEL__)}function gn(e,t,n){q.call(this,e??"canceled",q.ERR_CANCELED,t,n),this.name="CanceledError"}_.inherits(gn,q,{__CANCEL__:!0});function Qu(e,t,n){const s=n.config.validateStatus;!n.status||!s||s(n.status)?e(n):t(new q("Request failed with status code "+n.status,[q.ERR_BAD_REQUEST,q.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n))}const Zu=He.hasStandardBrowserEnv?{write(e,t,n,s,r,o){const i=[e+"="+encodeURIComponent(t)];_.isNumber(n)&&i.push("expires="+new Date(n).toGMTString()),_.isString(s)&&i.push("path="+s),_.isString(r)&&i.push("domain="+r),o===!0&&i.push("secure"),document.cookie=i.join("; ")},read(e){const t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove(e){this.write(e,"",Date.now()-864e5)}}:{write(){},read(){return null},remove(){}};function ef(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function tf(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}function el(e,t){return e&&!ef(t)?tf(e,t):t}const nf=He.hasStandardBrowserEnv?function(){const t=/(msie|trident)/i.test(navigator.userAgent),n=document.createElement("a");let s;function r(o){let i=o;return t&&(n.setAttribute("href",i),i=n.href),n.setAttribute("href",i),{href:n.href,protocol:n.protocol?n.protocol.replace(/:$/,""):"",host:n.host,search:n.search?n.search.replace(/^\?/,""):"",hash:n.hash?n.hash.replace(/^#/,""):"",hostname:n.hostname,port:n.port,pathname:n.pathname.charAt(0)==="/"?n.pathname:"/"+n.pathname}}return s=r(window.location.href),function(i){const l=_.isString(i)?r(i):i;return l.protocol===s.protocol&&l.host===s.host}}():function(){return function(){return!0}}();function sf(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function rf(e,t){e=e||10;const n=new Array(e),s=new Array(e);let r=0,o=0,i;return t=t!==void 0?t:1e3,function(c){const f=Date.now(),u=s[o];i||(i=f),n[r]=c,s[r]=f;let d=o,g=0;for(;d!==r;)g+=n[d++],d=d%e;if(r=(r+1)%e,r===o&&(o=(o+1)%e),f-i{const o=r.loaded,i=r.lengthComputable?r.total:void 0,l=o-n,c=s(l),f=o<=i;n=o;const u={loaded:o,total:i,progress:i?o/i:void 0,bytes:l,rate:c||void 0,estimated:c&&i&&f?(i-o)/c:void 0,event:r};u[t?"download":"upload"]=!0,e(u)}}const of=typeof XMLHttpRequest<"u",lf=of&&function(e){return new Promise(function(n,s){let r=e.data;const o=Xe.from(e.headers).normalize();let{responseType:i,withXSRFToken:l}=e,c;function f(){e.cancelToken&&e.cancelToken.unsubscribe(c),e.signal&&e.signal.removeEventListener("abort",c)}let u;if(_.isFormData(r)){if(He.hasStandardBrowserEnv||He.hasStandardBrowserWebWorkerEnv)o.setContentType(!1);else if((u=o.getContentType())!==!1){const[C,...D]=u?u.split(";").map($=>$.trim()).filter(Boolean):[];o.setContentType([C||"multipart/form-data",...D].join("; "))}}let d=new XMLHttpRequest;if(e.auth){const C=e.auth.username||"",D=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";o.set("Authorization","Basic "+btoa(C+":"+D))}const g=el(e.baseURL,e.url);d.open(e.method.toUpperCase(),Ji(g,e.params,e.paramsSerializer),!0),d.timeout=e.timeout;function E(){if(!d)return;const C=Xe.from("getAllResponseHeaders"in d&&d.getAllResponseHeaders()),$={data:!i||i==="text"||i==="json"?d.responseText:d.response,status:d.status,statusText:d.statusText,headers:C,config:e,request:d};Qu(function(j){n(j),f()},function(j){s(j),f()},$),d=null}if("onloadend"in d?d.onloadend=E:d.onreadystatechange=function(){!d||d.readyState!==4||d.status===0&&!(d.responseURL&&d.responseURL.indexOf("file:")===0)||setTimeout(E)},d.onabort=function(){d&&(s(new q("Request aborted",q.ECONNABORTED,e,d)),d=null)},d.onerror=function(){s(new q("Network Error",q.ERR_NETWORK,e,d)),d=null},d.ontimeout=function(){let D=e.timeout?"timeout of "+e.timeout+"ms exceeded":"timeout exceeded";const $=e.transitional||Yi;e.timeoutErrorMessage&&(D=e.timeoutErrorMessage),s(new q(D,$.clarifyTimeoutError?q.ETIMEDOUT:q.ECONNABORTED,e,d)),d=null},He.hasStandardBrowserEnv&&(l&&_.isFunction(l)&&(l=l(e)),l||l!==!1&&nf(g))){const C=e.xsrfHeaderName&&e.xsrfCookieName&&Zu.read(e.xsrfCookieName);C&&o.set(e.xsrfHeaderName,C)}r===void 0&&o.setContentType(null),"setRequestHeader"in d&&_.forEach(o.toJSON(),function(D,$){d.setRequestHeader($,D)}),_.isUndefined(e.withCredentials)||(d.withCredentials=!!e.withCredentials),i&&i!=="json"&&(d.responseType=e.responseType),typeof e.onDownloadProgress=="function"&&d.addEventListener("progress",Oo(e.onDownloadProgress,!0)),typeof e.onUploadProgress=="function"&&d.upload&&d.upload.addEventListener("progress",Oo(e.onUploadProgress)),(e.cancelToken||e.signal)&&(c=C=>{d&&(s(!C||C.type?new gn(null,e,d):C),d.abort(),d=null)},e.cancelToken&&e.cancelToken.subscribe(c),e.signal&&(e.signal.aborted?c():e.signal.addEventListener("abort",c)));const A=sf(g);if(A&&He.protocols.indexOf(A)===-1){s(new q("Unsupported protocol "+A+":",q.ERR_BAD_REQUEST,e));return}d.send(r||null)})},zs={http:Iu,xhr:lf};_.forEach(zs,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch{}Object.defineProperty(e,"adapterName",{value:t})}});const Ro=e=>`- ${e}`,cf=e=>_.isFunction(e)||e===null||e===!1,tl={getAdapter:e=>{e=_.isArray(e)?e:[e];const{length:t}=e;let n,s;const r={};for(let o=0;o`adapter ${l} `+(c===!1?"is not supported by the environment":"is not available in the build"));let i=t?o.length>1?`since : +`+o.map(Ro).join(` +`):" "+Ro(o[0]):"as no adapter specified";throw new q("There is no suitable adapter to dispatch the request "+i,"ERR_NOT_SUPPORT")}return s},adapters:zs};function Ts(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new gn(null,e)}function xo(e){return Ts(e),e.headers=Xe.from(e.headers),e.data=As.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),tl.getAdapter(e.adapter||Sr.adapter)(e).then(function(s){return Ts(e),s.data=As.call(e,e.transformResponse,s),s.headers=Xe.from(s.headers),s},function(s){return Zi(s)||(Ts(e),s&&s.response&&(s.response.data=As.call(e,e.transformResponse,s.response),s.response.headers=Xe.from(s.response.headers))),Promise.reject(s)})}const Lo=e=>e instanceof Xe?{...e}:e;function $t(e,t){t=t||{};const n={};function s(f,u,d){return _.isPlainObject(f)&&_.isPlainObject(u)?_.merge.call({caseless:d},f,u):_.isPlainObject(u)?_.merge({},u):_.isArray(u)?u.slice():u}function r(f,u,d){if(_.isUndefined(u)){if(!_.isUndefined(f))return s(void 0,f,d)}else return s(f,u,d)}function o(f,u){if(!_.isUndefined(u))return s(void 0,u)}function i(f,u){if(_.isUndefined(u)){if(!_.isUndefined(f))return s(void 0,f)}else return s(void 0,u)}function l(f,u,d){if(d in t)return s(f,u);if(d in e)return s(void 0,f)}const c={url:o,method:o,data:o,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:l,headers:(f,u)=>r(Lo(f),Lo(u),!0)};return _.forEach(Object.keys(Object.assign({},e,t)),function(u){const d=c[u]||r,g=d(e[u],t[u],u);_.isUndefined(g)&&d!==l||(n[u]=g)}),n}const nl="1.6.8",vr={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{vr[e]=function(s){return typeof s===e||"a"+(t<1?"n ":" ")+e}});const Io={};vr.transitional=function(t,n,s){function r(o,i){return"[Axios v"+nl+"] Transitional option '"+o+"'"+i+(s?". "+s:"")}return(o,i,l)=>{if(t===!1)throw new q(r(i," has been removed"+(n?" in "+n:"")),q.ERR_DEPRECATED);return n&&!Io[i]&&(Io[i]=!0,console.warn(r(i," has been deprecated since v"+n+" and will be removed in the near future"))),t?t(o,i,l):!0}};function af(e,t,n){if(typeof e!="object")throw new q("options must be an object",q.ERR_BAD_OPTION_VALUE);const s=Object.keys(e);let r=s.length;for(;r-- >0;){const o=s[r],i=t[o];if(i){const l=e[o],c=l===void 0||i(l,o,e);if(c!==!0)throw new q("option "+o+" must be "+c,q.ERR_BAD_OPTION_VALUE);continue}if(n!==!0)throw new q("Unknown option "+o,q.ERR_BAD_OPTION)}}const Js={assertOptions:af,validators:vr},it=Js.validators;class Mn{constructor(t){this.defaults=t,this.interceptors={request:new Ao,response:new Ao}}async request(t,n){try{return await this._request(t,n)}catch(s){if(s instanceof Error){let r;Error.captureStackTrace?Error.captureStackTrace(r={}):r=new Error;const o=r.stack?r.stack.replace(/^.+\n/,""):"";s.stack?o&&!String(s.stack).endsWith(o.replace(/^.+\n.+\n/,""))&&(s.stack+=` +`+o):s.stack=o}throw s}}_request(t,n){typeof t=="string"?(n=n||{},n.url=t):n=t||{},n=$t(this.defaults,n);const{transitional:s,paramsSerializer:r,headers:o}=n;s!==void 0&&Js.assertOptions(s,{silentJSONParsing:it.transitional(it.boolean),forcedJSONParsing:it.transitional(it.boolean),clarifyTimeoutError:it.transitional(it.boolean)},!1),r!=null&&(_.isFunction(r)?n.paramsSerializer={serialize:r}:Js.assertOptions(r,{encode:it.function,serialize:it.function},!0)),n.method=(n.method||this.defaults.method||"get").toLowerCase();let i=o&&_.merge(o.common,o[n.method]);o&&_.forEach(["delete","get","head","post","put","patch","common"],A=>{delete o[A]}),n.headers=Xe.concat(i,o);const l=[];let c=!0;this.interceptors.request.forEach(function(C){typeof C.runWhen=="function"&&C.runWhen(n)===!1||(c=c&&C.synchronous,l.unshift(C.fulfilled,C.rejected))});const f=[];this.interceptors.response.forEach(function(C){f.push(C.fulfilled,C.rejected)});let u,d=0,g;if(!c){const A=[xo.bind(this),void 0];for(A.unshift.apply(A,l),A.push.apply(A,f),g=A.length,u=Promise.resolve(n);d{if(!s._listeners)return;let o=s._listeners.length;for(;o-- >0;)s._listeners[o](r);s._listeners=null}),this.promise.then=r=>{let o;const i=new Promise(l=>{s.subscribe(l),o=l}).then(r);return i.cancel=function(){s.unsubscribe(o)},i},t(function(o,i,l){s.reason||(s.reason=new gn(o,i,l),n(s.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;const n=this._listeners.indexOf(t);n!==-1&&this._listeners.splice(n,1)}static source(){let t;return{token:new Er(function(r){t=r}),cancel:t}}}const uf=Er;function ff(e){return function(n){return e.apply(null,n)}}function df(e){return _.isObject(e)&&e.isAxiosError===!0}const Ys={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(Ys).forEach(([e,t])=>{Ys[t]=e});const hf=Ys;function sl(e){const t=new Fn(e),n=Di(Fn.prototype.request,t);return _.extend(n,Fn.prototype,t,{allOwnKeys:!0}),_.extend(n,t,null,{allOwnKeys:!0}),n.create=function(r){return sl($t(e,r))},n}const U=sl(Sr);U.Axios=Fn;U.CanceledError=gn;U.CancelToken=uf;U.isCancel=Zi;U.VERSION=nl;U.toFormData=ls;U.AxiosError=q;U.Cancel=U.CanceledError;U.all=function(t){return Promise.all(t)};U.spread=ff;U.isAxiosError=df;U.mergeConfig=$t;U.AxiosHeaders=Xe;U.formToJSON=e=>Qi(_.isHTMLForm(e)?new FormData(e):e);U.getAdapter=tl.getAdapter;U.HttpStatusCode=hf;U.default=U;function pf(){return rl().__VUE_DEVTOOLS_GLOBAL_HOOK__}function rl(){return typeof navigator<"u"&&typeof window<"u"?window:typeof globalThis<"u"?globalThis:{}}const mf=typeof Proxy=="function",gf="devtools-plugin:setup",_f="plugin:settings:set";let kt,Xs;function bf(){var e;return kt!==void 0||(typeof window<"u"&&window.performance?(kt=!0,Xs=window.performance):typeof globalThis<"u"&&(!((e=globalThis.perf_hooks)===null||e===void 0)&&e.performance)?(kt=!0,Xs=globalThis.perf_hooks.performance):kt=!1),kt}function yf(){return bf()?Xs.now():Date.now()}class Sf{constructor(t,n){this.target=null,this.targetQueue=[],this.onQueue=[],this.plugin=t,this.hook=n;const s={};if(t.settings)for(const i in t.settings){const l=t.settings[i];s[i]=l.defaultValue}const r=`__vue-devtools-plugin-settings__${t.id}`;let o=Object.assign({},s);try{const i=localStorage.getItem(r),l=JSON.parse(i);Object.assign(o,l)}catch{}this.fallbacks={getSettings(){return o},setSettings(i){try{localStorage.setItem(r,JSON.stringify(i))}catch{}o=i},now(){return yf()}},n&&n.on(_f,(i,l)=>{i===this.plugin.id&&this.fallbacks.setSettings(l)}),this.proxiedOn=new Proxy({},{get:(i,l)=>this.target?this.target.on[l]:(...c)=>{this.onQueue.push({method:l,args:c})}}),this.proxiedTarget=new Proxy({},{get:(i,l)=>this.target?this.target[l]:l==="on"?this.proxiedOn:Object.keys(this.fallbacks).includes(l)?(...c)=>(this.targetQueue.push({method:l,args:c,resolve:()=>{}}),this.fallbacks[l](...c)):(...c)=>new Promise(f=>{this.targetQueue.push({method:l,args:c,resolve:f})})})}async setRealTarget(t){this.target=t;for(const n of this.onQueue)this.target.on[n.method](...n.args);for(const n of this.targetQueue)n.resolve(await this.target[n.method](...n.args))}}function vf(e,t){const n=e,s=rl(),r=pf(),o=mf&&n.enableEarlyProxy;if(r&&(s.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__||!o))r.emit(gf,e,t);else{const i=o?new Sf(n,r):null;(s.__VUE_DEVTOOLS_PLUGINS__=s.__VUE_DEVTOOLS_PLUGINS__||[]).push({pluginDescriptor:n,setupFn:t,proxy:i}),i&&t(i.proxiedTarget)}}/*! + * vuex v4.1.0 + * (c) 2022 Evan You + * @license MIT + */var Ef="store";function Wt(e,t){Object.keys(e).forEach(function(n){return t(e[n],n)})}function ol(e){return e!==null&&typeof e=="object"}function Cf(e){return e&&typeof e.then=="function"}function wf(e,t){return function(){return e(t)}}function il(e,t,n){return t.indexOf(e)<0&&(n&&n.prepend?t.unshift(e):t.push(e)),function(){var s=t.indexOf(e);s>-1&&t.splice(s,1)}}function ll(e,t){e._actions=Object.create(null),e._mutations=Object.create(null),e._wrappedGetters=Object.create(null),e._modulesNamespaceMap=Object.create(null);var n=e.state;as(e,n,[],e._modules.root,!0),Cr(e,n,t)}function Cr(e,t,n){var s=e._state,r=e._scope;e.getters={},e._makeLocalGettersCache=Object.create(null);var o=e._wrappedGetters,i={},l={},c=Nl(!0);c.run(function(){Wt(o,function(f,u){i[u]=wf(f,e),l[u]=ki(function(){return i[u]()}),Object.defineProperty(e.getters,u,{get:function(){return l[u].value},enumerable:!0})})}),e._state=zn({data:t}),e._scope=c,e.strict&&xf(e),s&&n&&e._withCommit(function(){s.data=null}),r&&r.stop()}function as(e,t,n,s,r){var o=!n.length,i=e._modules.getNamespace(n);if(s.namespaced&&(e._modulesNamespaceMap[i],e._modulesNamespaceMap[i]=s),!o&&!r){var l=wr(t,n.slice(0,-1)),c=n[n.length-1];e._withCommit(function(){l[c]=s.state})}var f=s.context=Af(e,i,n);s.forEachMutation(function(u,d){var g=i+d;Tf(e,g,u,f)}),s.forEachAction(function(u,d){var g=u.root?d:i+d,E=u.handler||u;Of(e,g,E,f)}),s.forEachGetter(function(u,d){var g=i+d;Rf(e,g,u,f)}),s.forEachChild(function(u,d){as(e,t,n.concat(d),u,r)})}function Af(e,t,n){var s=t==="",r={dispatch:s?e.dispatch:function(o,i,l){var c=$n(o,i,l),f=c.payload,u=c.options,d=c.type;return(!u||!u.root)&&(d=t+d),e.dispatch(d,f)},commit:s?e.commit:function(o,i,l){var c=$n(o,i,l),f=c.payload,u=c.options,d=c.type;(!u||!u.root)&&(d=t+d),e.commit(d,f,u)}};return Object.defineProperties(r,{getters:{get:s?function(){return e.getters}:function(){return cl(e,t)}},state:{get:function(){return wr(e.state,n)}}}),r}function cl(e,t){if(!e._makeLocalGettersCache[t]){var n={},s=t.length;Object.keys(e.getters).forEach(function(r){if(r.slice(0,s)===t){var o=r.slice(s);Object.defineProperty(n,o,{get:function(){return e.getters[r]},enumerable:!0})}}),e._makeLocalGettersCache[t]=n}return e._makeLocalGettersCache[t]}function Tf(e,t,n,s){var r=e._mutations[t]||(e._mutations[t]=[]);r.push(function(i){n.call(e,s.state,i)})}function Of(e,t,n,s){var r=e._actions[t]||(e._actions[t]=[]);r.push(function(i){var l=n.call(e,{dispatch:s.dispatch,commit:s.commit,getters:s.getters,state:s.state,rootGetters:e.getters,rootState:e.state},i);return Cf(l)||(l=Promise.resolve(l)),e._devtoolHook?l.catch(function(c){throw e._devtoolHook.emit("vuex:error",c),c}):l})}function Rf(e,t,n,s){e._wrappedGetters[t]||(e._wrappedGetters[t]=function(o){return n(s.state,s.getters,o.state,o.getters)})}function xf(e){nn(function(){return e._state.data},function(){},{deep:!0,flush:"sync"})}function wr(e,t){return t.reduce(function(n,s){return n[s]},e)}function $n(e,t,n){return ol(e)&&e.type&&(n=t,t=e,e=e.type),{type:e,payload:t,options:n}}var Lf="vuex bindings",Po="vuex:mutations",Os="vuex:actions",Nt="vuex",If=0;function Pf(e,t){vf({id:"org.vuejs.vuex",app:e,label:"Vuex",homepage:"https://next.vuex.vuejs.org/",logo:"https://vuejs.org/images/icons/favicon-96x96.png",packageName:"vuex",componentStateTypes:[Lf]},function(n){n.addTimelineLayer({id:Po,label:"Vuex Mutations",color:ko}),n.addTimelineLayer({id:Os,label:"Vuex Actions",color:ko}),n.addInspector({id:Nt,label:"Vuex",icon:"storage",treeFilterPlaceholder:"Filter stores..."}),n.on.getInspectorTree(function(s){if(s.app===e&&s.inspectorId===Nt)if(s.filter){var r=[];dl(r,t._modules.root,s.filter,""),s.rootNodes=r}else s.rootNodes=[fl(t._modules.root,"")]}),n.on.getInspectorState(function(s){if(s.app===e&&s.inspectorId===Nt){var r=s.nodeId;cl(t,r),s.state=Ff(Df(t._modules,r),r==="root"?t.getters:t._makeLocalGettersCache,r)}}),n.on.editInspectorState(function(s){if(s.app===e&&s.inspectorId===Nt){var r=s.nodeId,o=s.path;r!=="root"&&(o=r.split("/").filter(Boolean).concat(o)),t._withCommit(function(){s.set(t._state.data,o,s.state.value)})}}),t.subscribe(function(s,r){var o={};s.payload&&(o.payload=s.payload),o.state=r,n.notifyComponentUpdate(),n.sendInspectorTree(Nt),n.sendInspectorState(Nt),n.addTimelineEvent({layerId:Po,event:{time:Date.now(),title:s.type,data:o}})}),t.subscribeAction({before:function(s,r){var o={};s.payload&&(o.payload=s.payload),s._id=If++,s._time=Date.now(),o.state=r,n.addTimelineEvent({layerId:Os,event:{time:s._time,title:s.type,groupId:s._id,subtitle:"start",data:o}})},after:function(s,r){var o={},i=Date.now()-s._time;o.duration={_custom:{type:"duration",display:i+"ms",tooltip:"Action duration",value:i}},s.payload&&(o.payload=s.payload),o.state=r,n.addTimelineEvent({layerId:Os,event:{time:Date.now(),title:s.type,groupId:s._id,subtitle:"end",data:o}})}})})}var ko=8702998,kf=6710886,Nf=16777215,al={label:"namespaced",textColor:Nf,backgroundColor:kf};function ul(e){return e&&e!=="root"?e.split("/").slice(-2,-1)[0]:"Root"}function fl(e,t){return{id:t||"root",label:ul(t),tags:e.namespaced?[al]:[],children:Object.keys(e._children).map(function(n){return fl(e._children[n],t+n+"/")})}}function dl(e,t,n,s){s.includes(n)&&e.push({id:s||"root",label:s.endsWith("/")?s.slice(0,s.length-1):s||"Root",tags:t.namespaced?[al]:[]}),Object.keys(t._children).forEach(function(r){dl(e,t._children[r],n,s+r+"/")})}function Ff(e,t,n){t=n==="root"?t:t[n];var s=Object.keys(t),r={state:Object.keys(e.state).map(function(i){return{key:i,editable:!0,value:e.state[i]}})};if(s.length){var o=Uf(t);r.getters=Object.keys(o).map(function(i){return{key:i.endsWith("/")?ul(i):i,editable:!1,value:Qs(function(){return o[i]})}})}return r}function Uf(e){var t={};return Object.keys(e).forEach(function(n){var s=n.split("/");if(s.length>1){var r=t,o=s.pop();s.forEach(function(i){r[i]||(r[i]={_custom:{value:{},display:i,tooltip:"Module",abstract:!0}}),r=r[i]._custom.value}),r[o]=Qs(function(){return e[n]})}else t[n]=Qs(function(){return e[n]})}),t}function Df(e,t){var n=t.split("/").filter(function(s){return s});return n.reduce(function(s,r,o){var i=s[r];if(!i)throw new Error('Missing module "'+r+'" for path "'+t+'".');return o===n.length-1?i:i._children},t==="root"?e:e.root._children)}function Qs(e){try{return e()}catch(t){return t}}var De=function(t,n){this.runtime=n,this._children=Object.create(null),this._rawModule=t;var s=t.state;this.state=(typeof s=="function"?s():s)||{}},hl={namespaced:{configurable:!0}};hl.namespaced.get=function(){return!!this._rawModule.namespaced};De.prototype.addChild=function(t,n){this._children[t]=n};De.prototype.removeChild=function(t){delete this._children[t]};De.prototype.getChild=function(t){return this._children[t]};De.prototype.hasChild=function(t){return t in this._children};De.prototype.update=function(t){this._rawModule.namespaced=t.namespaced,t.actions&&(this._rawModule.actions=t.actions),t.mutations&&(this._rawModule.mutations=t.mutations),t.getters&&(this._rawModule.getters=t.getters)};De.prototype.forEachChild=function(t){Wt(this._children,t)};De.prototype.forEachGetter=function(t){this._rawModule.getters&&Wt(this._rawModule.getters,t)};De.prototype.forEachAction=function(t){this._rawModule.actions&&Wt(this._rawModule.actions,t)};De.prototype.forEachMutation=function(t){this._rawModule.mutations&&Wt(this._rawModule.mutations,t)};Object.defineProperties(De.prototype,hl);var Lt=function(t){this.register([],t,!1)};Lt.prototype.get=function(t){return t.reduce(function(n,s){return n.getChild(s)},this.root)};Lt.prototype.getNamespace=function(t){var n=this.root;return t.reduce(function(s,r){return n=n.getChild(r),s+(n.namespaced?r+"/":"")},"")};Lt.prototype.update=function(t){pl([],this.root,t)};Lt.prototype.register=function(t,n,s){var r=this;s===void 0&&(s=!0);var o=new De(n,s);if(t.length===0)this.root=o;else{var i=this.get(t.slice(0,-1));i.addChild(t[t.length-1],o)}n.modules&&Wt(n.modules,function(l,c){r.register(t.concat(c),l,s)})};Lt.prototype.unregister=function(t){var n=this.get(t.slice(0,-1)),s=t[t.length-1],r=n.getChild(s);r&&r.runtime&&n.removeChild(s)};Lt.prototype.isRegistered=function(t){var n=this.get(t.slice(0,-1)),s=t[t.length-1];return n?n.hasChild(s):!1};function pl(e,t,n){if(t.update(n),n.modules)for(var s in n.modules){if(!t.getChild(s))return;pl(e.concat(s),t.getChild(s),n.modules[s])}}function Bf(e){return new Ae(e)}var Ae=function(t){var n=this;t===void 0&&(t={});var s=t.plugins;s===void 0&&(s=[]);var r=t.strict;r===void 0&&(r=!1);var o=t.devtools;this._committing=!1,this._actions=Object.create(null),this._actionSubscribers=[],this._mutations=Object.create(null),this._wrappedGetters=Object.create(null),this._modules=new Lt(t),this._modulesNamespaceMap=Object.create(null),this._subscribers=[],this._makeLocalGettersCache=Object.create(null),this._scope=null,this._devtools=o;var i=this,l=this,c=l.dispatch,f=l.commit;this.dispatch=function(g,E){return c.call(i,g,E)},this.commit=function(g,E,A){return f.call(i,g,E,A)},this.strict=r;var u=this._modules.root.state;as(this,u,[],this._modules.root),Cr(this,u),s.forEach(function(d){return d(n)})},Ar={state:{configurable:!0}};Ae.prototype.install=function(t,n){t.provide(n||Ef,this),t.config.globalProperties.$store=this;var s=this._devtools!==void 0?this._devtools:!1;s&&Pf(t,this)};Ar.state.get=function(){return this._state.data};Ar.state.set=function(e){};Ae.prototype.commit=function(t,n,s){var r=this,o=$n(t,n,s),i=o.type,l=o.payload,c={type:i,payload:l},f=this._mutations[i];f&&(this._withCommit(function(){f.forEach(function(d){d(l)})}),this._subscribers.slice().forEach(function(u){return u(c,r.state)}))};Ae.prototype.dispatch=function(t,n){var s=this,r=$n(t,n),o=r.type,i=r.payload,l={type:o,payload:i},c=this._actions[o];if(c){try{this._actionSubscribers.slice().filter(function(u){return u.before}).forEach(function(u){return u.before(l,s.state)})}catch{}var f=c.length>1?Promise.all(c.map(function(u){return u(i)})):c[0](i);return new Promise(function(u,d){f.then(function(g){try{s._actionSubscribers.filter(function(E){return E.after}).forEach(function(E){return E.after(l,s.state)})}catch{}u(g)},function(g){try{s._actionSubscribers.filter(function(E){return E.error}).forEach(function(E){return E.error(l,s.state,g)})}catch{}d(g)})})}};Ae.prototype.subscribe=function(t,n){return il(t,this._subscribers,n)};Ae.prototype.subscribeAction=function(t,n){var s=typeof t=="function"?{before:t}:t;return il(s,this._actionSubscribers,n)};Ae.prototype.watch=function(t,n,s){var r=this;return nn(function(){return t(r.state,r.getters)},n,Object.assign({},s))};Ae.prototype.replaceState=function(t){var n=this;this._withCommit(function(){n._state.data=t})};Ae.prototype.registerModule=function(t,n,s){s===void 0&&(s={}),typeof t=="string"&&(t=[t]),this._modules.register(t,n),as(this,this.state,t,this._modules.get(t),s.preserveState),Cr(this,this.state)};Ae.prototype.unregisterModule=function(t){var n=this;typeof t=="string"&&(t=[t]),this._modules.unregister(t),this._withCommit(function(){var s=wr(n.state,t.slice(0,-1));delete s[t[t.length-1]]}),ll(this)};Ae.prototype.hasModule=function(t){return typeof t=="string"&&(t=[t]),this._modules.isRegistered(t)};Ae.prototype.hotUpdate=function(t){this._modules.update(t),ll(this,!0)};Ae.prototype._withCommit=function(t){var n=this._committing;this._committing=!0,t(),this._committing=n};Object.defineProperties(Ae.prototype,Ar);var Ze=gl(function(e,t){var n={};return ml(t).forEach(function(s){var r=s.key,o=s.val;n[r]=function(){var l=this.$store.state,c=this.$store.getters;if(e){var f=_l(this.$store,"mapState",e);if(!f)return;l=f.context.state,c=f.context.getters}return typeof o=="function"?o.call(this,l,c):l[o]},n[r].vuex=!0}),n}),Vf=gl(function(e,t){var n={};return ml(t).forEach(function(s){var r=s.key,o=s.val;n[r]=function(){for(var l=[],c=arguments.length;c--;)l[c]=arguments[c];var f=this.$store.commit;if(e){var u=_l(this.$store,"mapMutations",e);if(!u)return;f=u.context.commit}return typeof o=="function"?o.apply(this,[f].concat(l)):f.apply(this.$store,[o].concat(l))}}),n});function ml(e){return Mf(e)?Array.isArray(e)?e.map(function(t){return{key:t,val:t}}):Object.keys(e).map(function(t){return{key:t,val:e[t]}}):[]}function Mf(e){return Array.isArray(e)||ol(e)}function gl(e){return function(t,n){return typeof t!="string"?(n=t,t=""):t.charAt(t.length-1)!=="/"&&(t+="/"),e(t,n)}}function _l(e,t,n){var s=e._modulesNamespaceMap[n];return s}const et=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},$f={data(){return{artistsArrayList:[],lastClickedItem:null,showDrop:!1}},created(){this.loadList(),U.get("/api/getLastArtist").then(e=>{e.data!==""&&(this.lastClickedItem=e.data)})},computed:{...Ze(["allowButtons","sourceTab","artist"])},watch:{"$store.state.loadListRequest"(e){e&&(this.$store.commit("SET_LOAD_REQUEST",!1),this.loadList())}},methods:{loadList(){U.get("/api/loadList").then(e=>{this.artistsArrayList=e.data}).catch(e=>{console.error(e)})},handleItemClick(e){this.lastClickedItem=e,U.post("/api/listOrTabClick",{item:e,origin:"list"}).then(t=>{this.$store.commit("SET_SELECTED_ARTIST",e),this.$store.commit("SET_TABLE_CONTENT",t.data)}).catch(t=>{console.error(t)})},clickAddArtist(){this.$store.commit("SET_ADD_VIS",!0)},clickDeleteArtist(){this.lastClickedItem!==""&&U.get("/api/clickArtistDelete").then(()=>{this.$store.commit("SET_SELECTED_ARTIST",""),this.$store.commit("SET_SOURCE_TAB","combview"),this.loadList()}).catch(e=>{console.error(e)})},showMore(){this.showDrop=!this.showDrop},deleteUrl(){U.post("/api/deleteUrl").then(()=>{this.handleItemClick(this.lastClickedItem)})}}},jf={class:"buttonspace"},Hf=["disabled"],Kf={key:0,class:"dropdown"},qf=["disabled"],Wf=["disabled"],Gf={class:"artistlist"},zf=["onMousedown"],Jf={class:"listitems"};function Yf(e,t,n,s,r,o){return x(),L(_e,null,[p("div",jf,[p("button",{onMousedown:t[0]||(t[0]=i=>o.clickAddArtist()),class:"addbtn",disabled:!e.allowButtons},"add",40,Hf),p("button",{onClick:t[1]||(t[1]=i=>o.showMore()),class:"morebtn"},"more"),r.showDrop?(x(),L("div",Kf,[p("button",{onClick:t[2]||(t[2]=i=>o.deleteUrl()),disabled:e.sourceTab==null||e.sourceTab=="combview"||e.artist==""||!e.allowButtons,class:"deletebtn"},"delete selected URL",8,qf),p("button",{onClick:t[3]||(t[3]=i=>o.clickDeleteArtist()),disabled:e.artist==""||!e.allowButtons,class:"deletebtn"},"delete artist",8,Wf)])):V("",!0)]),p("div",Gf,[(x(!0),L(_e,null,Ds(r.artistsArrayList,i=>(x(),L("li",{key:i,onMousedown:l=>o.handleItemClick(i),class:ve([{highlighted:i===r.lastClickedItem},"listbtn"])},[p("div",Jf,ze(i),1)],42,zf))),128)),(x(!0),L(_e,null,Ds(r.artistsArrayList,i=>(x(),L("li",{key:i}))),128))])],64)}const Xf=et($f,[["render",Yf],["__scopeId","data-v-18b2502f"]]),Qf="/assets/optionsblack-vjTCXWXl.png",Zf="/assets/optionsdark-ymr6Vwzk.png",ed="/assets/optionslight-B8QchSUy.png",td="/assets/refreshuniversal-3TIkIW2C.png",nd={data(){return{activeTab:"",eventSource:null,scrapeNotice:!1,scrapeLast:"-",isActive:!1}},computed:{...Ze(["sourceTab","allowButtons","primaryColor"])},created(){this.activeTab=this.sourceTab,U.post("/api/fillCombview").catch(e=>{console.error(e)}).then(()=>{this.sourceTab===""?this.setStoreTab("combview"):this.handleSourceClick(this.sourceTab)}),U.get("/api/getScrapeDate").then(e=>{this.scrapeLast=e.data})},watch:{sourceTab(e){this.activeTab=e,e&&this.handleSourceClick(e)}},methods:{setStoreTab(e){this.$store.commit("SET_SOURCE_TAB",e)},handleSourceClick(e){U.post("/api/listOrTabClick",{item:e,origin:"tab"}).then(t=>{this.$store.commit("SET_TABLE_CONTENT",t.data)}).catch(t=>{console.error(t)})},clickScrape(){this.scrapeNotice=!1,this.allowButtons?(this.$store.commit("SET_ALLOW_BUTTONS",!1),this.isActive=!0,this.eventSource=new EventSource("/progress"),this.eventSource.onmessage=t=>{const n=parseFloat(t.data);this.$store.commit("SET_PROGRESS",n)},U.post("/api/clickScrape").then(()=>{this.isActive=!1,this.$store.commit("SET_ALLOW_BUTTONS",!0),this.eventSource.close();let t=new Date().toLocaleString("en-GB",{day:"2-digit",month:"2-digit",hour:"2-digit",minute:"2-digit"}).replace(/\//g,".").replace(",","").replace(/(\d{2})\.(\d{2})/,"$1.$2.");this.scrapeLast=t,this.scrapeNotice=!0,this.handleSourceClick("combview"),U.post("/api/setSetting",{name:"lastScrape",value:t}).catch(n=>{console.error(n)})})):U.post("/api/cancelScrape").then(()=>{this.$store.commit("SET_ALLOW_BUTTONS",!0),this.isActive=!1})},scrapeHover(){this.scrapeNotice=!0},scrapeMouseOff(){this.scrapeNotice=!1},openSettings(){this.$store.commit("SET_SETTINGS_OPEN",!0)}}},sd=e=>(Ht("data-v-bbadd133"),e=e(),Kt(),e),rd={class:"wrapper"},od={class:"tabs"},id=["disabled"],ld={key:0,class:"image",src:Qf,alt:"Settings"},cd={key:1,class:"image",src:Zf,alt:"Settings"},ad={key:2,class:"image",src:ed,alt:"Settings"},ud=sd(()=>p("img",{class:"image",src:td,alt:"Refresh"},null,-1)),fd=[ud];function dd(e,t,n,s,r,o){return x(),L("div",rd,[p("div",od,[p("div",{onMousedown:t[0]||(t[0]=i=>o.setStoreTab("combview")),class:ve([{active:r.activeTab==="combview"},"cvtab"])},"Combined view",34),p("div",{onMousedown:t[1]||(t[1]=i=>o.setStoreTab("beatport")),class:ve([{active:r.activeTab==="beatport"},"stab"])},"BP",34),p("div",{onMousedown:t[2]||(t[2]=i=>o.setStoreTab("musicbrainz")),class:ve([{active:r.activeTab==="musicbrainz"},"stab"])},"MB",34),p("div",{onMousedown:t[3]||(t[3]=i=>o.setStoreTab("junodownload")),class:ve([{active:r.activeTab==="junodownload"},"stab"])},"JD",34),p("div",{onMousedown:t[4]||(t[4]=i=>o.setStoreTab("youtube")),class:ve([{active:r.activeTab==="youtube"},"stab"])},"YT",34)]),p("button",{onClick:t[5]||(t[5]=i=>o.openSettings()),class:"settingsButton",disabled:!e.allowButtons},[e.primaryColor==="Black"?(x(),L("img",ld)):e.primaryColor==="Dark"?(x(),L("img",cd)):e.primaryColor==="Light"?(x(),L("img",ad)):V("",!0)],8,id),p("button",{onClick:t[6]||(t[6]=i=>o.clickScrape()),onMouseover:t[7]||(t[7]=i=>o.scrapeHover()),onMouseleave:t[8]||(t[8]=i=>o.scrapeMouseOff()),class:ve(["scrapeButton",{scrapeActive:r.isActive}])},fd,34),le(gr,{name:"fade"},{default:ai(()=>[r.scrapeNotice?(x(),L("div",{key:0,class:"scrapenotice",onMouseover:t[9]||(t[9]=i=>o.scrapeMouseOff())},[p("p",null,"Last scrape: "+ze(r.scrapeLast),1)],32)):V("",!0)]),_:1})])}const hd=et(nd,[["render",dd],["__scopeId","data-v-bbadd133"]]),pd={mounted(){this.isDateInFuture},computed:{...Ze(["tableData","previewVis","artist","isoDates","sourceTab","urlExists"]),hideArtistColumn(){return this.tableData.some(e=>e.artist===null)},hideTable(){return this.tableData.some(e=>e.song!==null)}},methods:{isDateInFuture(e){return new Date(e)>new Date},formatDate(e){if(this.isoDates)return e;{const t=new Date(e),n=t.getDate(),s=t.getMonth()+1,r=t.getFullYear();return`${n}. ${s}. ${r}`}}}},_n=e=>(Ht("data-v-19adbfff"),e=e(),Kt(),e),md={key:0,class:"table-container"},gd={class:"table-header"},_d=_n(()=>p("th",{class:"song"},"song",-1)),bd={key:0,class:"artist"},yd=_n(()=>p("th",{class:"date"},"date",-1)),Sd={class:"table-body"},vd=_n(()=>p("td",null,[p("br")],-1)),Ed={class:"tdsong"},Cd={key:0,class:"tdartist"},wd={class:"tddate"},Ad={key:1,class:"emptynotice"},Td=_n(()=>p("p",null,"table empty",-1)),Od=[Td],Rd={key:2,class:"quickstart"},xd=_n(()=>p("p",null,[p("span",{class:"title"},"Quickstart guide"),pe(),p("br"),pe(' 1. click "add" to add an artist, select the artist '),p("br"),pe(" 2. click on any BP / MB / JD / YT button at the top to select a source "),p("br"),pe(" 3. find the artist on the website, copy & paste the link or ID "),p("br"),pe(" 4. to scrape, click refresh button in the top right corner "),p("br")],-1)),Ld=[xd];function Id(e,t,n,s,r,o){return x(),L(_e,null,[o.hideTable?(x(),L("div",md,[p("div",gd,[p("table",null,[p("tr",null,[_d,o.hideArtistColumn?V("",!0):(x(),L("th",bd,"artist")),yd])])]),p("div",Sd,[p("table",null,[p("tbody",null,[vd,(x(!0),L(_e,null,Ds(e.tableData,(i,l)=>(x(),L("tr",{key:l,class:ve({"future-date":o.isDateInFuture(i.date)})},[p("td",Ed,ze(i.song),1),o.hideArtistColumn?V("",!0):(x(),L("td",Cd,ze(i.artist),1)),p("td",wd,ze(o.formatDate(i.date)),1)],2))),128))])])])])):V("",!0),e.urlExists&&!o.hideTable&&!e.previewVis&&e.sourceTab!=="combview"?(x(),L("div",Ad,Od)):V("",!0),!e.urlExists&&!o.hideTable&&!e.previewVis&&e.sourceTab==="combview"?(x(),L("div",Rd,Ld)):V("",!0)],64)}const Pd=et(pd,[["render",Id],["__scopeId","data-v-19adbfff"]]),Gt="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAACXBIWXMAAAYCAAAGAgHyxpylAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAABwpJREFUeJzt3UmMFGUYh/FnlBiNGxITTbjoRQ+elBAFObpePLmgLAm7u8ywyQ7KIsuwGRdgALeIaDx4cDfRRGKMRr0YE2+Y6MEtosZoXGgP73ScNDD2VL1vfbX8fxcCTH1dyTz5uqq66uueVquFiLdTUu+A1JPCkhAKS0IoLAmhsCSEwpIQCktCKCwJobAkhMKSEApLQigsCaGwJITCkhAKS0IoLAmhsCSEwpIQCktCKCwJobAkhMKSEApLQigsCaGwJITCkhAKS0IoLAmhsCSEwpIQo1LvgCR1KTABuAD4CjgMfO0xsMJqpsuBXcCkjn8/BrwC9GKhZdajhdca5xbgGeD0YX7mR+Ba4LOsL6KwmuU24Dm6e6f6BrgM+DnLC+ngvTkm031UAGOBhVlfTDNWM0wGnmXkx9RHgIuzvKDCqr/bsahOzbj9GOCnkW6kt8J6u4N8UQGckWUjhVVfU7CzvzxR/QH8kGVDhVVPU4GnyRcVwHvAn1k2VFj1Mw14ivxRAfRn3VBh1ct04AA+UT0GvJN1Y50V1sd0YD8+UT0/ON4/WQdQWPWQ95LCUC9iB/5/5xlEb4XVNwO7ou4R1SEcogKFVXUzgAF8fo+HsLPJ3FGBwqqymfhF9QKOUYHCqqqZwF78opqGY1SgG/2qyDuqqeQ4+zsZzVjVMgu/qA4SFBUorCqZBezB53d2gMCoQGFVxWx8o5qN3d8eRmGV32xgNz6/q/0UEBUorLKbg29UcyggKlBYZTYHeJIKRgUKq6w8Z6p9FBwVKKwymotF1eMw1r7B8QqNChRW2czF3v48ohogUVSgsMpkHr5RzSNRVKCwymIe8AQ+Ue0lcVSgsMrgTnyjupPEUYHCSm0+8Dg1mqnaFFY684Ht+ES1B4uqNPeZK6w0erGoPOzB3v5KExUorBR6gW1OY+2mhFGBwipaH75R3UUJowKFVaQ+cjxZ3GEHJY4KFFZRFuAbVS8ljgoUVhEWAFudxtqORVV6CivWQnyj6nMaK5zCirMQ2OI01jYqFBUorCiL8I1qgdNYhVFY/hYBm53G6qeCUYHC8rYY36gyL4edmsLysxjY5DTWViocFSgsL0vwjWqR01jJKKz8lgCPOI21hRpEBcUvCjIKuBK4ZPDvXwIf4bzSSYG8o1rsNFZyRYV1GnZ20wec3/F/32MHqtuAvwraHw9rgNVOY23GIq2NItYgHQ28Ckz8n587DNxEhq/XSGANimpY0WH1AG8B13T5859g35NX5rjWAqucxtoEPOg0VqlEH7xPofuoAMYBbwPnxexOboqqS9Fh3Zthm3HYLDfaeV/yeghF1bXIt8KzgKNkXyb6Y+C6wTFSexhY4TTWGmzmq7XIGetC8q09Pp5yzFyKKoPIsH53GGM88CZwrsNYWazDL6rVNCQqiH0r7AG+4/jrVll8ip0EFHm2uA5Y7jTWauwYrTEiZ6wW8LLTWFcAr1PczLUev6hW0bCoIP461kXA58CZTuN9CFwP/OI03omsB5Y5jbUKO0ZrnOjLDUewZaS91hO4CngDOMdpvE4b8ItqJQ2NCoq5u+EQvksVTiAmrg3AUqexVmLHaI1V1G0z+/FdXa4d19lO423EL6oVNDwqKPZ+LO/1ML3i2ojfVfAV2DFa46X4hlXPBfEBPgBuAH4d4XY92LN6Dzjtx3Ls7VRIcwep9/qYE7FLESOZuRRVsFS3Jg/gu/zO1XQfVw+2/oFXVMtQVMdJec97e2nDIuNqR3W/02suw47RpEPqhyki4noNu7OiUw+wE7+olqKoTip1WPDfSr9ecU3CZq6hcbWjus/pNZbi9xBFLaU4KzwZz29lALuH/kbgN2AX2W467NTClhHa6TBWrZUpLPBdSB/gfeCLwXHzUlQjULawwM7WvJap9tLCls/elXpHqqIMx1iddlKutaAUVQZFPwndrR2Df3qthZ5VC5tBH028H5VTxhmrbQdpZy5FlUOZwwKbsVIsktHCziIVVUZlDwtsWZ8iF8toAfdgX54kGVUhLLCVWIpY36AF3I1d8pAcyni5YTiea6Z3amHf9rA7aPxGqcqM1daP352eQ7Wwj5UUlZOqhQX2GZ3XAw9g94XNw76eTZxUMSywuwo8nvtrR7XXYSwZoqphgd1cl+fx92PYB98DPrsjQ1U5LLAHF1Zm3HYu9oCHBKh6WGCPWo30wdC1KKpQVbvcMJx+uvsIqP19fxKoTmEB3IxdMhhzgv87il38PFjoHjVU3cJqmwTcCowFvgVeAt5NukcNU9ewJLE6HLxLCSksCaGwJITCkhAKS0IoLAmhsCSEwpIQCktCKCwJobAkhMKSEApLQigsCaGwJITCkhAKS0IoLAmhsCSEwpIQCktCKCwJobAkhMKSEApLQigsCaGwJITCkhAKS0IoLAnxL3WBYWyxSXBfAAAAAElFTkSuQmCC",zt="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJYAAACWCAYAAAA8AXHiAAAACXBIWXMAAAYCAAAGAgHyxpylAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAABw9JREFUeJzt3cmrHFUUx/HvcULBIbpRcKMbXbhSUBHc6l/gbBTU5MUJNM6zRo1Gk5gYccjkjCMuXIkDKjiigjvBnYIKThhBUETfcVH1NDxMeK/6nLq3qn9fqE1e+tbtqg/1uvt13zZ3R6no9ig9ATXOBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEp7lZ6AKpeZHQ2cBBwKfA287+7fhIyt9bGmLzM7FtgEnDzvR7PAq8BKd/96on0I1nRlZqcDTwP77ua//Qyc4u6fd96PYE1PZnYm8CwLewj0LXCMu//aZV968D4lmdlZLBwVwOHANZ33pyvW+GtRPcPin6x95e5HdtqnYI07MzubBtWeHYc4xN1/WeyN9KtwxJnZOUyGCmC/LjcSrJFmZufSPPubBNUfwE9dbihYI8zMlgJPMRkqgHfd/c8uNxSskWVm5wFPMjkqgPVdbyhYI8rMzgeeIAbVw+7+Vue56FnhOGpRPU4MqueA8939787zEazhF/CSws69BJzr7n9NMoh+FQ48M7uA5hX1CFQvEoAKBGvQtai2EXMeXwSWRqACwRpsZnYhcaheIBAVCNYga1FtJQ7VeZGoQO8gHVwJqJZO8uxvV+mKNaDM7CLiUD1PEioQrMHUotpCzDl7gkRUIFiDyMyWEYtqmbvPBoy1ywSr8lpUm4k5V4/TAyoQrKozs+XEolreByoQrGprUT3GAFGBYFVZ8JVqOz2jAsGqLjOboUFlAcNtB2b6RgWCVVUtqseIQbWNQqhAsKrJzFYQi2pFKVQgWFXUonqUGFRbKYwKBKt4ZnYxsaguLo0KBKtoZnYl8AgjulLNJViFalFtIAbVFhpU1bzPXLAKZGYraVBFtIXm1181qECweq9F9UDQcJupEBUIVq+Z2VXEorqkRlQgWL3Vour8yeJ5baRiVKC3JveSmV0NrAsabqO7rwwaKy1dsZILRrVhCKhAsFIzs2uIRXVV0FjpCVZSLaq1QcM9MCRUIFgpmdm1xKK6Omis3hKs4FpU9wcNt36IqECwQjOz64hF1Xk57NIJVlAtqvuChls3ZFQgWCGZ2fXEoro2aKxiCdaEtajWBA23dgyooOdX3s1sL+BE4Kj2n74EPole6aSvElBdFzRW+dw9fQP2AW4EfgR83vYDcD2wdx9zCbxPd/zPfem63Vf6/oQfnx5OwBLggwUc3PeAg0sfEKEaACyad0e+uYiD/FntuIBVgajWlL4/Q4W1tMPBrhaXUNUD6+OOB/1TYEnpgzPvvtwpVAvf0tZ5N7P9gR10Xyb6U+BUd98RN6tumdldwC1Bw93h7quCxqq2zNexDmOytcePB94wsyVB8+mUUHUrE9bvAWMcD7xuZgcFjLXozOxu4lDdPi2oIBfWd3T8rrt5nQC8bWYHB4y14FpUNwcNd7u73xk01iBKg+XNg7dXgoY7DnitryuXma0mDtVt04YKSH9WeATwG3HPpj4CDkye8+rA+d5a+tlZqS1/B3Am8HfgyfowCxdwT+A8byl9ckcNqz1hF9aOS6gGCKs9cRcl4DogaG73Bs7r5tIntYat353F4/pgUlxCNQJY7YlcVgMumj+Qbwycx02lT2ZNW5mdxuN6fzG4hGqksNqTuxyY7RtXi+rBwP3eWPok1riV3XnPuIRqSmAl4XoP2H8XqDYF7ueG0seu5q34BNqTPpOJS6imFFYmrhbVQ0FjzgJXlD5WQ9jS3ujXpeCF9KHB9QWwImAsB1a6+4MBY42+qmABmNkVxC1THZUDV7r7ptITGUrVfRK6vSLUtBaUUHWoOlgA7r4RqGFJRKd5TCVUi6xKWPAvrpJXrjlUDxWcw2CrFhaAu28ASiyS4cDlQtW9qmEBuPs6oM/FMhy4zN0f6XGfo6t6WADuvpZm4ZD0XQGXuvujPexr1FX3csPuCl4zfX5O820Pm5PGn6oGccWay93X0yyHFD40zZcdCVVQg4IF4O5rgJsCh5yl+a6/LYFjTn2DgwXg7vcS87m/OVRbA8ZSOzVIWADufg+Tffx9Fphx921BU1I7NVhYAO6+Gri1481n3H175HzUfw0aFoC73w3ctcibrRKq3Ab1csPuMrP1LOxPQIP4vr+hNxpYAGZ2Gs1X2h7yPz/eQfPi5/P9zmo6GxWsuczsZOAM4HDge+Bld3+n7Kymq1HCUuUb/IN3VWeCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqJcFSKQmWSkmwVEqCpVISLJWSYKmUBEulJFgqpX8Abns5VFEOJoIAAAAASUVORK5CYII=",kd={data:()=>({input:""}),computed:{...Ze(["tableData","sourceTab","allowButtons","artist","addDialogVis","primaryColor","urlExists"])},watch:{tableData(){this.determineDiagShow()}},methods:{clickURL(){const e=encodeURIComponent(this.input);this.input="",e&&U.post("/api/clickAddURL",e).then(()=>{const t=this.artist;U.post("/api/listOrTabClick",{item:t,origin:"list"}).then(n=>{this.$store.commit("SET_TABLE_CONTENT",n.data),this.$store.commit("SET_PREVIEW_VIS",!0)})}).catch(t=>{console.error(t)})},determineDiagShow(){this.tableData.length===0?U.get("/api/checkExistURL").then(e=>{this.$store.commit("SET_URL_EXISTS",e.data)}).catch(e=>{console.error(e)}):this.$store.commit("SET_URL_EXISTS",!0)}}},ae=e=>(Ht("data-v-0fe96286"),e=e(),Kt(),e),Nd={key:0},Fd={key:0,class:"dialog"},Ud=ae(()=>p("h1",null,"MusicBrainz source",-1)),Dd={class:"artist"},Bd=ae(()=>p("p",null,[p("a",{href:"https://musicbrainz.org",target:"_blank"},"https://musicbrainz.org"),pe(" > find artist > copy URL")],-1)),Vd=ae(()=>p("br",null,null,-1)),Md=ae(()=>p("p",null,"Example link:",-1)),$d=ae(()=>p("p",null,[pe("https://musicbrainz.org/artist/"),p("span",{class:"variabletext"},"id/...")],-1)),jd={key:0,class:"image",src:Gt,alt:"OK"},Hd={key:1,class:"image",src:zt,alt:"OK"},Kd={key:1,class:"dialog"},qd=ae(()=>p("h1",null,"Beatport source",-1)),Wd={class:"artist"},Gd=ae(()=>p("p",null,[p("a",{href:"https://beatport.com",target:"_blank"},"https://beatport.com"),pe(" > find artist > copy URL")],-1)),zd=ae(()=>p("br",null,null,-1)),Jd=ae(()=>p("p",null,"Example link:",-1)),Yd=ae(()=>p("p",null,[pe("https://beatport.com/artist/"),p("span",{class:"variabletext"},"artistname/id/...")],-1)),Xd={key:0,class:"image",src:Gt,alt:"OK"},Qd={key:1,class:"image",src:zt,alt:"OK"},Zd={key:2,class:"dialog"},eh=ae(()=>p("h1",null,"Junodownload source",-1)),th={class:"artist"},nh=ae(()=>p("p",null,[p("a",{href:"https://junodownload.com",target:"_blank"},"https://junodownload.com"),pe(" > find artist > copy URL")],-1)),sh=ae(()=>p("br",null,null,-1)),rh=ae(()=>p("p",null,"Example link:",-1)),oh=ae(()=>p("p",null,[pe("https://junodownload.com/artists/"),p("span",{class:"variabletext"},"artistname/...")],-1)),ih={key:0,class:"image",src:Gt,alt:"OK"},lh={key:1,class:"image",src:zt,alt:"OK"},ch={key:3,class:"dialog"},ah=ae(()=>p("h1",null,"Youtube source",-1)),uh={class:"artist"},fh=ae(()=>p("p",null,[p("a",{href:"https://youtube.com",target:"_blank"},"https://youtube.com")],-1)),dh=ae(()=>p("p",null,[pe(' Find an auto-generated channel with "Topic" in its name. '),p("br"),pe("Obtain the ID (share > copy channel ID) or copy URL. "),p("br"),pe("An ID needs to be provided, not a channel handle. ")],-1)),hh=ae(()=>p("p",null,"Example link:",-1)),ph=ae(()=>p("p",null,[pe("https://youtube.com/channel/"),p("span",{class:"variabletext"},"UCwZEU0wAwIyZb...")],-1)),mh={key:0,class:"image",src:Gt,alt:"OK"},gh={key:1,class:"image",src:zt,alt:"OK"};function _h(e,t,n,s,r,o){return!e.urlExists&&e.allowButtons&&e.artist&&!e.addDialogVis?(x(),L("div",Nd,[e.sourceTab==="musicbrainz"?(x(),L("div",Fd,[Ud,p("p",Dd,ze(e.artist),1),Bd,Vd,Md,$d,ie(p("input",{"onUpdate:modelValue":t[0]||(t[0]=i=>e.input=i)},null,512),[[en,e.input]]),p("button",{onClick:t[1]||(t[1]=(...i)=>o.clickURL&&o.clickURL(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",jd)):V("",!0),e.primaryColor==="Light"?(x(),L("img",Hd)):V("",!0)])])):e.sourceTab==="beatport"?(x(),L("div",Kd,[qd,p("p",Wd,ze(e.artist),1),Gd,zd,Jd,Yd,ie(p("input",{"onUpdate:modelValue":t[2]||(t[2]=i=>e.input=i)},null,512),[[en,e.input]]),p("button",{onClick:t[3]||(t[3]=(...i)=>o.clickURL&&o.clickURL(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",Xd)):V("",!0),e.primaryColor==="Light"?(x(),L("img",Qd)):V("",!0)])])):e.sourceTab==="junodownload"?(x(),L("div",Zd,[eh,p("p",th,ze(e.artist),1),nh,sh,rh,oh,ie(p("input",{"onUpdate:modelValue":t[4]||(t[4]=i=>e.input=i)},null,512),[[en,e.input]]),p("button",{onClick:t[5]||(t[5]=(...i)=>o.clickURL&&o.clickURL(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",ih)):V("",!0),e.primaryColor==="Light"?(x(),L("img",lh)):V("",!0)])])):e.sourceTab==="youtube"?(x(),L("div",ch,[ah,p("p",uh,ze(e.artist),1),fh,dh,hh,ph,ie(p("input",{"onUpdate:modelValue":t[6]||(t[6]=i=>e.input=i)},null,512),[[en,e.input]]),p("button",{onClick:t[7]||(t[7]=(...i)=>o.clickURL&&o.clickURL(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",mh)):V("",!0),e.primaryColor==="Light"?(x(),L("img",gh)):V("",!0)])])):V("",!0)])):V("",!0)}const bh=et(kd,[["render",_h],["__scopeId","data-v-0fe96286"]]),Tr="/assets/crossdark-CYntds6r.png",Or="/assets/crosslight-CRspF710.png",yh={data:()=>({input:"",rules:[e=>!!e.trim(),e=>(e||"").length<=25]}),computed:{...Ze(["addDialogVis","primaryColor"]),isValid(){return this.rules.every(e=>e(this.input)===!0)}},methods:{clickAdd(){const e=encodeURIComponent(this.input);U.post("/api/clickArtistAdd",e).then(()=>{this.input="",this.$store.commit("SET_SELECTED_ARTIST",""),this.$store.commit("SET_ADD_VIS",!1),this.$store.commit("SET_LOAD_REQUEST",!0)}).catch(t=>{console.error(t)})},clickClose(){this.$store.commit("SET_ADD_VIS",!1)}}},Sh=e=>(Ht("data-v-cb695d37"),e=e(),Kt(),e),vh={key:0,class:"wrapper"},Eh=Sh(()=>p("div",{class:"card-text"},[p("p",{class:"text--primary"},"Type artist's name and confirm.")],-1)),Ch={class:"diag-actions"},wh={key:0,class:"image",src:Tr,alt:"X"},Ah={key:1,class:"image",src:Or,alt:"X"},Th=["disabled"],Oh={key:0,class:"image",src:Gt,alt:"OK"},Rh={key:1,class:"image",src:zt,alt:"OK"};function xh(e,t,n,s,r,o){return e.addDialogVis?(x(),L("div",vh,[Eh,p("div",Ch,[ie(p("input",{"onUpdate:modelValue":t[0]||(t[0]=i=>e.input=i),class:ve({invalid:!o.isValid})},null,2),[[en,e.input]]),p("button",{onClick:t[1]||(t[1]=(...i)=>o.clickClose&&o.clickClose(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",wh)):V("",!0),e.primaryColor==="Light"?(x(),L("img",Ah)):V("",!0)]),p("button",{onClick:t[2]||(t[2]=(...i)=>o.clickAdd&&o.clickAdd(...i)),class:"imgbutton",disabled:!o.isValid},[e.primaryColor!=="Light"?(x(),L("img",Oh)):V("",!0),e.primaryColor==="Light"?(x(),L("img",Rh)):V("",!0)],8,Th)])])):V("",!0)}const Lh=et(yh,[["render",xh],["__scopeId","data-v-cb695d37"]]),Ih={computed:{...Ze(["progress"])},methods:{...Vf(["setProgress"])}},Ph={class:"progress-container"};function kh(e,t,n,s,r,o){return x(),L("div",Ph,[p("div",{class:"progressbar",style:Wn({width:`${e.progress}%`})},null,4)])}const Nh=et(Ih,[["render",kh],["__scopeId","data-v-d29e2d3a"]]),Fh="/assets/blcktext-QjjfTEs8.png",Uh="/assets/MRTlogo-BpL2l-3G.png",Dh={data(){return{theme:"",accent:"",settingsProtection:!0,dbProtection:!0,filters:{Remix:!1,VIP:!1,Instrumental:!1,Acoustic:!1,Extended:!1,Remaster:!1},theme:{Black:!1,Dark:!1,Light:!1},isoDates:!1,autoTheme:!1}},computed:{...Ze(["primaryColor","accentColor"])},created(){U.get("/api/settingsOpened").then(e=>{this.filters=e.data,this.isoDates=e.data.isoDates,this.autoTheme=e.data.autoTheme}).catch(e=>{console.error(e)}),this.theme=this.primaryColor,this.accent=this.accentColor},methods:{clickClose(){this.$store.commit("SET_SETTINGS_OPEN",!1)},setSetting(e,t){switch(e){case"theme":this.$store.commit("SET_PRIMARY_COLOR",this.theme);case"accent":this.$store.commit("SET_ACCENT_COLOR",this.accent);case"isoDates":this.$store.commit("SET_ISODATES",this.isoDates)}U.post("/api/setSetting",{name:e,value:t}).catch(n=>{console.error(n)})},resetSettings(){this.settingsProtection==!0?this.settingsProtection=!1:U.post("/api/resetSettings").then(()=>{this.clickClose()}).catch(e=>{console.error(e)})},resetDB(){this.dbProtection==!0?this.dbProtection=!1:U.post("/api/resetDB").then(()=>{this.clickClose()}).catch(e=>{console.error(e)})},resetProtection(){this.settingsProtection=!0,this.dbProtection=!0}}},ue=e=>(Ht("data-v-6b545924"),e=e(),Kt(),e),Bh={class:"settings"},Vh={key:0,class:"image",src:Tr,alt:"X"},Mh={key:1,class:"image",src:Or,alt:"X"},$h={class:"filterscont"},jh=ue(()=>p("p",null,[p("span",{class:"title"},"Exclusion filters"),p("br"),pe("Select types of songs to be hidden in Combined view.")],-1)),Hh={class:"filters-buttons"},Kh=ue(()=>p("label",null,"Remix",-1)),qh=ue(()=>p("label",null,"VIP",-1)),Wh=ue(()=>p("label",null,"Instrumental",-1)),Gh=ue(()=>p("label",null,"Acoustic",-1)),zh=ue(()=>p("label",null,"Extended",-1)),Jh=ue(()=>p("label",null,"Remaster",-1)),Yh={class:"appearance"},Xh=ue(()=>p("p",{class:"title"},"Appearance",-1)),Qh={class:"appearancecont"},Zh={class:"theme-buttons"},ep=["disabled"],tp=["disabled"],np=["disabled"],sp=ue(()=>p("div",{class:"colorindicator"},null,-1)),rp={class:"accent-buttons"},op=ue(()=>p("label",null,"Lavender",-1)),ip=ue(()=>p("label",null,"Cactus",-1)),lp=ue(()=>p("label",null,"Rose",-1)),cp=ue(()=>p("label",null,"Warm",-1)),ap=ue(()=>p("label",null,"Cloud",-1)),up=ue(()=>p("label",null,"Ocean",-1)),fp={class:"belowAppearance"},dp=ue(()=>p("label",null,"Match system theme",-1)),hp={class:"other"},pp=ue(()=>p("p",{class:"title"},"Other",-1)),mp={class:"flex-items"},gp={class:"flex-padding"},_p=ue(()=>p("label",null,"Dates in yyyy-MM-dd (ISO 8601)",-1)),bp={class:"danger"},yp=ue(()=>p("p",{class:"title"},"Danger zone",-1)),Sp={class:"dangercont"},vp=ia('
logologo
',1);function Ep(e,t,n,s,r,o){return x(),L("div",Bh,[p("button",{onClick:t[0]||(t[0]=i=>o.clickClose()),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",Vh)):V("",!0),e.primaryColor==="Light"?(x(),L("img",Mh)):V("",!0)]),p("section",$h,[jh,p("div",Hh,[p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[1]||(t[1]=i=>r.filters.Remix=i),onChange:t[2]||(t[2]=i=>o.setSetting("filters.Remix",i.target.checked))},null,544),[[ot,r.filters.Remix]]),Kh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[3]||(t[3]=i=>r.filters.VIP=i),onChange:t[4]||(t[4]=i=>o.setSetting("filters.VIP",i.target.checked))},null,544),[[ot,r.filters.VIP]]),qh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[5]||(t[5]=i=>r.filters.Instrumental=i),onChange:t[6]||(t[6]=i=>o.setSetting("filters.Instrumental",i.target.checked))},null,544),[[ot,r.filters.Instrumental]]),Wh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[7]||(t[7]=i=>r.filters.Acoustic=i),onChange:t[8]||(t[8]=i=>o.setSetting("filters.Acoustic",i.target.checked))},null,544),[[ot,r.filters.Acoustic]]),Gh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[9]||(t[9]=i=>r.filters.Extended=i),onChange:t[10]||(t[10]=i=>o.setSetting("filters.Extended",i.target.checked))},null,544),[[ot,r.filters.Extended]]),zh]),p("div",null,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[11]||(t[11]=i=>r.filters.Remaster=i),onChange:t[12]||(t[12]=i=>o.setSetting("filters.Remaster",i.target.checked))},null,544),[[ot,r.filters.Remaster]]),Jh])])]),p("section",Yh,[Xh,p("div",Qh,[p("div",Zh,[ie(p("input",{type:"radio","onUpdate:modelValue":t[13]||(t[13]=i=>r.theme=i),value:"Black",onChange:t[14]||(t[14]=i=>o.setSetting("theme","Black")),disabled:r.autoTheme},null,40,ep),[[Ge,r.theme]]),p("label",{class:ve({disabled:r.autoTheme})},"Black",2),ie(p("input",{type:"radio","onUpdate:modelValue":t[15]||(t[15]=i=>r.theme=i),value:"Dark",onChange:t[16]||(t[16]=i=>o.setSetting("theme","Dark")),disabled:r.autoTheme},null,40,tp),[[Ge,r.theme]]),p("label",{class:ve({disabled:r.autoTheme})},"Dark",2),ie(p("input",{type:"radio","onUpdate:modelValue":t[17]||(t[17]=i=>r.theme=i),value:"Light",onChange:t[18]||(t[18]=i=>o.setSetting("theme","Light")),disabled:r.autoTheme},null,40,np),[[Ge,r.theme]]),p("label",{class:ve({disabled:r.autoTheme})},"Light",2),sp]),p("div",rp,[ie(p("input",{type:"radio","onUpdate:modelValue":t[19]||(t[19]=i=>r.accent=i),value:"Lavender",onChange:t[20]||(t[20]=i=>o.setSetting("accent","Lavender"))},null,544),[[Ge,r.accent]]),op,ie(p("input",{type:"radio","onUpdate:modelValue":t[21]||(t[21]=i=>r.accent=i),value:"Cactus",onChange:t[22]||(t[22]=i=>o.setSetting("accent","Cactus"))},null,544),[[Ge,r.accent]]),ip,ie(p("input",{type:"radio","onUpdate:modelValue":t[23]||(t[23]=i=>r.accent=i),value:"Rose",onChange:t[24]||(t[24]=i=>o.setSetting("accent","Rose"))},null,544),[[Ge,r.accent]]),lp,ie(p("input",{type:"radio","onUpdate:modelValue":t[25]||(t[25]=i=>r.accent=i),value:"Warm",onChange:t[26]||(t[26]=i=>o.setSetting("accent","Warm"))},null,544),[[Ge,r.accent]]),cp,ie(p("input",{type:"radio","onUpdate:modelValue":t[27]||(t[27]=i=>r.accent=i),value:"Cloud",onChange:t[28]||(t[28]=i=>o.setSetting("accent","Cloud"))},null,544),[[Ge,r.accent]]),ap,ie(p("input",{type:"radio","onUpdate:modelValue":t[29]||(t[29]=i=>r.accent=i),value:"Ocean",onChange:t[30]||(t[30]=i=>o.setSetting("accent","Ocean"))},null,544),[[Ge,r.accent]]),up])]),p("div",fp,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[31]||(t[31]=i=>r.autoTheme=i),onChange:t[32]||(t[32]=i=>o.setSetting("autoTheme",i.target.checked))},null,544),[[ot,r.autoTheme]]),dp])]),p("section",hp,[pp,p("div",mp,[p("div",gp,[ie(p("input",{type:"checkbox","onUpdate:modelValue":t[33]||(t[33]=i=>r.isoDates=i),onChange:t[34]||(t[34]=i=>o.setSetting("isoDates",i.target.checked))},null,544),[[ot,r.isoDates]]),_p])])]),p("section",bp,[yp,p("div",Sp,[r.settingsProtection?(x(),L("button",{key:0,onClick:t[35]||(t[35]=i=>o.resetSettings())},"Reset settings")):V("",!0),r.settingsProtection?V("",!0):(x(),L("button",{key:1,onClick:t[36]||(t[36]=i=>o.resetSettings()),onMouseleave:t[37]||(t[37]=i=>o.resetProtection())},"confirm",32)),r.dbProtection?(x(),L("button",{key:2,onClick:t[38]||(t[38]=i=>o.resetDB())},"Reset database")):V("",!0),r.dbProtection?V("",!0):(x(),L("button",{key:3,onClick:t[39]||(t[39]=i=>o.resetDB()),onMouseleave:t[40]||(t[40]=i=>o.resetProtection())},"confirm",32))])]),vp])}const Cp=et(Dh,[["render",Ep],["__scopeId","data-v-6b545924"]]),wp={computed:{...Ze(["tableData","primaryColor"]),hideTable(){return this.tableData.length==0}},methods:{clickCancel(){U.request("/api/cleanArtistSource").catch(e=>{console.error(e)}),this.$store.commit("SET_PREVIEW_VIS",!1)},clickConfirm(){U.request("/api/saveUrl").catch(e=>{console.error(e)}),this.$store.commit("SET_PREVIEW_VIS",!1)}}},Ap=e=>(Ht("data-v-85018fb6"),e=e(),Kt(),e),Tp={class:"preview"},Op=Ap(()=>p("h1",null,"preview",-1)),Rp={key:0},xp={key:1},Lp=["disabled"],Ip={key:0,class:"image",src:Gt,alt:"OK"},Pp={key:1,class:"image",src:zt,alt:"OK"},kp={key:0,class:"image",src:Tr,alt:"X"},Np={key:1,class:"image",src:Or,alt:"X"};function Fp(e,t,n,s,r,o){return x(),L("div",Tp,[Op,o.hideTable?V("",!0):(x(),L("p",Rp,"Confirm only if the table has usable information.")),o.hideTable?(x(),L("p",xp,"Incorrect link.")):V("",!0),p("button",{onClick:t[0]||(t[0]=(...i)=>o.clickConfirm&&o.clickConfirm(...i)),class:"imgbutton",disabled:o.hideTable},[e.primaryColor!=="Light"?(x(),L("img",Ip)):V("",!0),e.primaryColor==="Light"?(x(),L("img",Pp)):V("",!0)],8,Lp),p("button",{onClick:t[1]||(t[1]=(...i)=>o.clickCancel&&o.clickCancel(...i)),class:"imgbutton"},[e.primaryColor!=="Light"?(x(),L("img",kp)):V("",!0),e.primaryColor==="Light"?(x(),L("img",Np)):V("",!0)])])}const Up=et(wp,[["render",Fp],["__scopeId","data-v-85018fb6"]]);U.defaults.baseURL="http://localhost:57782";const Dp={data(){return{appliedStyles:[],theme:"",accent:""}},components:{ArtistList:Xf,SourceMenu:hd,SourceTable:Pd,DialogsURL:bh,AddArtistDialog:Lh,ProgressBar:Nh,SettingsWindow:Cp,PreviewDialog:Up},created(){this.loadTheme(),this.detectTheme()},computed:{...Ze(["settingsOpen","primaryColor","accentColor","previewVis"])},watch:{primaryColor(e){this.theme=e,this.applyTheme(e,this.accent)},accentColor(e){this.accent=e,this.applyTheme(this.theme,e)}},methods:{loadTheme(){U.get("/api/getThemeConfig").then(e=>{this.$store.commit("SET_PRIMARY_COLOR",e.data.theme),this.$store.commit("SET_ACCENT_COLOR",e.data.accent)}).catch(e=>{console.error(e)})},detectTheme(){U.get("/api/settingsOpened").then(e=>{const t=window.matchMedia("(prefers-color-scheme: dark)");e.data.autoTheme==!0&&(t.matches?this.$store.commit("SET_PRIMARY_COLOR","Black"):this.$store.commit("SET_PRIMARY_COLOR","Light"))}).catch(e=>{console.error(e)})},applyTheme(e,t){this.appliedStyles.forEach(r=>{r.remove()}),this.appliedStyles=[];let n,s;e!==""&&(n=`./primary${e}.css`,s=document.createElement("link"),s.rel="stylesheet",s.href=n,document.head.appendChild(s),this.appliedStyles.push(s)),t!==""&&(n=`./secondary${t}.css`,s=document.createElement("link"),s.rel="stylesheet",s.href=n,document.head.appendChild(s),this.appliedStyles.push(s))}}},Bp={key:0,class:"app"},Vp={class:"list"},Mp={class:"maincontent"},$p={key:0,class:"topbar"},jp={class:"sourcetable"},Hp={key:1,class:"dialogsurl"},Kp={class:"progressbar"},qp={key:1,class:"app"};function Wp(e,t,n,s,r,o){const i=nt("ArtistList"),l=nt("PreviewDialog"),c=nt("SourceMenu"),f=nt("AddArtistDialog"),u=nt("SourceTable"),d=nt("DialogsURL"),g=nt("ProgressBar"),E=nt("SettingsWindow");return x(),L(_e,null,[e.settingsOpen?V("",!0):(x(),L("div",Bp,[p("div",Vp,[e.previewVis?V("",!0):(x(),Hs(i,{key:0})),e.previewVis?(x(),Hs(l,{key:1,class:"preview"})):V("",!0)]),p("div",Mp,[e.previewVis?V("",!0):(x(),L("div",$p,[le(c)])),le(f),p("div",jp,[le(u)]),e.previewVis?V("",!0):(x(),L("div",Hp,[le(d)]))]),p("div",Kp,[le(g)])])),e.settingsOpen?(x(),L("div",qp,[le(E)])):V("",!0)],64)}const Gp=et(Dp,[["render",Wp],["__scopeId","data-v-e34fd722"]]),zp={artist:"",sourceTab:"",tableData:[],addDialogVis:!1,loadListRequest:!1,allowButtons:!0,progress:0,settingsOpen:!1,primaryColor:"",accentColor:"",previewVis:!1,isoDates:!1,urlExists:!1},Jp={SET_SOURCE_TAB(e,t){e.sourceTab=t},SET_SELECTED_ARTIST(e,t){e.artist=t},SET_TABLE_CONTENT(e,t){e.tableData=t,e.addDialogVis=!1},SET_ADD_VIS(e,t){e.addDialogVis=t},SET_LOAD_REQUEST(e,t){e.loadListRequest=t},SET_ALLOW_BUTTONS(e,t){e.allowButtons=t},SET_PROGRESS(e,t){e.progress=t*100,e.progress==100&&(e.progress=0)},SET_SETTINGS_OPEN(e,t){e.settingsOpen=t},SET_PRIMARY_COLOR(e,t){e.primaryColor=t},SET_ACCENT_COLOR(e,t){e.accentColor=t},SET_PREVIEW_VIS(e,t){e.previewVis=t},SET_ISODATES(e,t){e.isoDates=t},SET_URL_EXISTS(e,t){e.urlExists=t}},Yp={},Xp={},Qp=Bf({state:zp,mutations:Jp,actions:Yp,getters:Xp}),bl=za(Gp);bl.use(Qp);bl.mount("#app"); diff --git a/src/main/resources/static/assets/index-DQ2nizA8.css b/src/main/resources/static/assets/index-DQ2nizA8.css new file mode 100644 index 0000000..951191b --- /dev/null +++ b/src/main/resources/static/assets/index-DQ2nizA8.css @@ -0,0 +1 @@ +*[data-v-18b2502f]::-webkit-scrollbar{width:8px;background:transparent}*[data-v-18b2502f]::-webkit-scrollbar-thumb{background-color:var(--dull-color)}.listbtn[data-v-18b2502f]{width:92%;height:28px;border-radius:0;margin:0;display:flex;align-items:center;white-space:nowrap;overflow:hidden;padding-left:7px}.artistlist[data-v-18b2502f]{height:calc(100vh - 40px);overflow-y:scroll}.artistlist li[data-v-18b2502f]{list-style-type:none}.buttonspace[data-v-18b2502f]{margin-bottom:5px}.addbtn[data-v-18b2502f],.morebtn[data-v-18b2502f]{font-size:12px;width:75px;height:28px;border:2px solid var(--dull-color);border-radius:6px;background-color:transparent;color:var(--contrast-color)}.addbtn[data-v-18b2502f]{margin-left:5px}.addbtn[data-v-18b2502f]:hover,.morebtn[data-v-18b2502f]:hover{background-color:var(--accent-color);border:2px solid var(--accent-color);color:var(--accent-contrast)}.addbtn[data-v-18b2502f]:active,.morebtn[data-v-18b2502f]:active{opacity:75%}.morebtn[data-v-18b2502f]{margin-left:5px}.dropdown[data-v-18b2502f]{position:relative;display:grid;grid-template-columns:repeat(1,1fr);background-color:var(--subtle-color);padding-right:10px;padding-left:6px}.dropdown .deletebtn[data-v-18b2502f]{font-size:12px;height:25px;margin-top:3px;border:2px solid var(--dull-color);border-radius:6px;background-color:transparent;color:var(--contrast-color)}.deletebtn[data-v-18b2502f]:hover{background-color:red;border:2px solid red}.listbtn[data-v-18b2502f]:hover{background-color:var(--duller-color)}.highlighted[data-v-18b2502f]{background-color:var(--accent-color);color:var(--accent-contrast)}.highlighted[data-v-18b2502f]:hover{background-color:var(--accent-color)}[data-v-18b2502f]:disabled{opacity:.5;pointer-events:none}.wrapper[data-v-bbadd133]{min-width:500px;width:100%;display:flex;align-items:center;height:38px}.tabs[data-v-bbadd133]{display:flex;text-align:center;font-weight:700;flex-grow:1;height:38px}.image[data-v-bbadd133]{height:32px;width:32px}.settingsButton[data-v-bbadd133],.scrapeButton[data-v-bbadd133]{padding:0;margin-left:8px;margin-top:2px;height:32px;width:32px;border:none}.settingsButton[data-v-bbadd133]:hover,.scrapeButton[data-v-bbadd133]:hover{opacity:70%}.settingsButton[data-v-bbadd133]{height:32px;width:32px;background-color:var(--accent-color)}.scrapeButton[data-v-bbadd133]{background-color:var(--accent-color);margin-right:20px;border-radius:50px}.scrapeActive[data-v-bbadd133]{transition:.75s;rotate:180deg;filter:hue-rotate(120deg)}.scrapeActive[data-v-bbadd133]:hover{opacity:1}.cvtab[data-v-bbadd133]{width:80%;max-width:390px;padding:8px;border:solid 3px transparent;border-bottom:solid 3px var(--accent-color)}.stab[data-v-bbadd133]{width:20%;max-width:110px;padding:8px;border:solid 3px transparent;border-bottom:solid 3px var(--accent-color);white-space:nowrap;overflow:hidden}.tabs[data-v-bbadd133] :hover{border-bottom:solid 3px var(--dull-color)}.active[data-v-bbadd133]{transition:.15s;background-color:var(--accent-color);color:var(--accent-contrast);border-bottom:solid 3px var(--accent-color);border-radius:5px}.active[data-v-bbadd133]:hover{border-bottom:solid 3px var(--accent-color)}.scrapenotice[data-v-bbadd133]{position:absolute;z-index:50;background-color:var(--duller-color);border-radius:5px;padding-right:10px;padding-left:10px;right:14px;top:42px}.fade-enter-from[data-v-bbadd133],.fade-leave-to[data-v-bbadd133]{opacity:0}.fade-enter-active[data-v-bbadd133],.fade-leave-active[data-v-bbadd133]{transition:.15s}[data-v-bbadd133]:disabled{opacity:.5;pointer-events:none}.table-header[data-v-19adbfff]{flex-shrink:0;overflow:hidden;z-index:3;position:fixed;width:calc(100% - 170px)}.table-body[data-v-19adbfff]{flex-grow:1;overflow-y:auto;-webkit-user-select:text;user-select:text;margin-bottom:10vh}table[data-v-19adbfff]{width:100%;min-width:500px;border-collapse:collapse}th[data-v-19adbfff],td[data-v-19adbfff]{padding:4px}th[data-v-19adbfff]{background-color:var(--primary-color);border:none;position:sticky;top:0}.song[data-v-19adbfff],.tdsong[data-v-19adbfff],.artist[data-v-19adbfff],.tdartist[data-v-19adbfff]{width:50%;max-width:120px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.date[data-v-19adbfff],.tddate[data-v-19adbfff]{width:100px;min-width:100px}.future-date[data-v-19adbfff]{opacity:40%}.emptynotice[data-v-19adbfff]{position:absolute;left:40%;top:40%;color:var(--dull-color)}.quickstart[data-v-19adbfff]{position:relative;font-size:15px;line-height:22px;left:5%;top:5%}.quickstart .title[data-v-19adbfff]{font-weight:700}.tddate[data-v-19adbfff]{display:flex;justify-content:flex-end;margin-right:30px}p[data-v-0fe96286]{line-height:1.4}.dialog[data-v-0fe96286]{width:375px;height:280px;background-color:var(--primary-color);border:2px solid var(--contrast-color);border-radius:3px;color:var(--contrast-color);padding:8px}input[data-v-0fe96286]{background-color:var(--duller-color);color:var(--contrast-color);border:none;width:345px;position:absolute;bottom:5px;left:5px;font-size:13px;height:18px}input[data-v-0fe96286]:focus{outline:none}button[data-v-0fe96286]{color:#000;border:none;position:absolute;right:5px;bottom:5px}button[data-v-0fe96286]:hover{opacity:70%}a[data-v-0fe96286]{color:var(--accent-color);font-weight:700;text-decoration:none}a[data-v-0fe96286]:hover{text-decoration:underline}h1[data-v-0fe96286]{font-size:17px;font-weight:400}.variabletext[data-v-0fe96286]{color:var(--accent-color)}.artist[data-v-0fe96286]{-webkit-user-select:text;user-select:text}.imgbutton[data-v-0fe96286],.image[data-v-0fe96286]{height:23px;width:23px;padding:0;float:right;margin-right:2px;background-color:transparent}.imgbutton[data-v-0fe96286]:hover{opacity:50%}[data-v-0fe96286]:disabled{opacity:.5;pointer-events:none}.wrapper[data-v-cb695d37]{top:25%;left:35%;width:325px;height:240px;position:absolute;z-index:3;background-color:var(--primary-color);border:2px solid var(--contrast-color);border-radius:3px;padding:8px}.diag-actions[data-v-cb695d37]{position:absolute;bottom:3px;left:5px}button[data-v-cb695d37]{border:none}input[data-v-cb695d37]{background-color:var(--duller-color);color:var(--contrast-color);width:200px;margin-right:58px;margin-left:10px;border:none}input[data-v-cb695d37]:focus{outline:none}.imgbutton[data-v-cb695d37],.image[data-v-cb695d37]{height:23px;width:23px;padding:0;float:right;margin-left:5px;margin-right:2px;background-color:transparent}.imgbutton[data-v-cb695d37]{position:relative}.imgbutton[data-v-cb695d37]:hover{opacity:50%}[data-v-cb695d37]:disabled{opacity:.3;pointer-events:none}*[data-v-d29e2d3a]{transition:.2s}.progress-container[data-v-d29e2d3a]{background-color:transparent}.progressbar[data-v-d29e2d3a]{height:5px;line-height:5px;text-align:center;background-color:var(--accent-color)}*[data-v-6b545924]{transition:.1s}.title[data-v-6b545924]{font-weight:700}.settings[data-v-6b545924]{font-family:arial,sans-serif;font-size:14px;-webkit-user-select:none;user-select:none;background-color:var(--primary-color);color:var(--contrast-color);overflow-y:scroll;overflow-x:hidden;display:grid;align-content:start;width:100%;justify-content:center;accent-color:var(--contrast-color)}@media screen and (min-width: 950px){.settings[data-v-6b545924]{display:grid;grid-template-columns:repeat(2,0fr)}section[data-v-6b545924]{margin-right:90px}}.filters-buttons[data-v-6b545924]{margin-top:10px;display:grid;grid-template-columns:repeat(2,1fr);grid-gap:10px;max-height:80px}.flex-items[data-v-6b545924]{display:flex;flex-direction:column}.flex-padding[data-v-6b545924]{padding:5px}.appearancecont[data-v-6b545924]{display:flex;accent-color:var(--dull-color)}.theme-buttons[data-v-6b545924]{display:grid;grid-template-columns:repeat(2,1fr);width:30%;padding-right:20px;line-height:18px}.accent-buttons[data-v-6b545924]{display:grid;grid-template-columns:repeat(4,1fr)}.belowAppearance[data-v-6b545924]{margin-left:15px;margin-top:6px}.imgbutton[data-v-6b545924]{position:absolute;right:0;top:0;padding:0;margin:10px;background-color:transparent;border:none;transition:0s}.imgbutton[data-v-6b545924]:hover{opacity:60%}.image[data-v-6b545924]{height:33px}input[data-v-6b545924]{margin-right:5px}section[data-v-6b545924]{position:relative;margin-top:20px;left:40px;padding:1px 15px 10px;background-color:var(--duller-color);border-radius:5px;transition:.15s;width:345px}.self[data-v-6b545924]{justify-self:center;width:280px;background-color:transparent}.blckimg[data-v-6b545924]{height:48px;background-color:#000;border-radius:5px;padding:12px;margin-right:22px}.mrtimg[data-v-6b545924]{height:72px;border-radius:10px}.colorindicator[data-v-6b545924]{position:absolute;right:0;top:0;height:100%;width:8px;background-color:var(--accent-color);border-top-right-radius:5px;border-bottom-right-radius:5px}.dangercont[data-v-6b545924]{display:flex;justify-content:space-evenly}.danger button[data-v-6b545924]{border-radius:5px;background-color:transparent;color:var(--contrast-color);border:2px solid red;padding:4px;width:120px}.danger button[data-v-6b545924]:hover{background-color:red}.disabled[data-v-6b545924]{opacity:.3}.preview[data-v-85018fb6]{width:100%;height:100%;background-color:var(--subtle-color);font-size:15px}h1[data-v-85018fb6]{font-size:18px;color:var(--accent-color)}p[data-v-85018fb6],h1[data-v-85018fb6]{position:relative;left:6px}button[data-v-85018fb6]{margin-left:8px;border:none;border-radius:5px;width:60px}.imgbutton[data-v-85018fb6],.image[data-v-85018fb6]{margin-left:22px;height:26px;width:26px;padding:0;background-color:transparent}.imgbutton[data-v-85018fb6]:hover{opacity:50%}[data-v-85018fb6]:disabled{opacity:.5;pointer-events:none}*[data-v-e34fd722]{scrollbar-color:var(--dull-color) transparent}*[data-v-e34fd722]::-webkit-scrollbar-thumb{background-color:var(--dull-color)}*[data-v-e34fd722]::-webkit-scrollbar{width:8px;background:transparent}.app[data-v-e34fd722]{font-family:arial,sans-serif;font-size:14px;-webkit-user-select:none;user-select:none;display:flex;position:fixed;top:0;left:0;padding-left:5px;padding-top:3px;width:100%;height:100%;background-color:var(--primary-color);color:var(--contrast-color);transition:.15s}.list[data-v-e34fd722]{width:170px;min-width:170px;padding-top:5px;padding-left:2px;top:-3px;left:-5px;position:relative;background-color:var(--subtle-color)}.maincontent[data-v-e34fd722]{flex-grow:1;height:100vh}.topbar[data-v-e34fd722]{left:5px;position:relative}.dialogsurl[data-v-e34fd722]{top:25%;left:35%;position:absolute}.sourcetable[data-v-e34fd722]{position:relative;top:6px;height:100%;overflow-y:scroll;margin-right:4px}.progressbar[data-v-e34fd722]{position:absolute;bottom:3px;left:0;z-index:5;width:100%} diff --git a/vue/src/components/SettingsWindow.vue b/vue/src/components/SettingsWindow.vue index 2081ba3..41ef1f4 100644 --- a/vue/src/components/SettingsWindow.vue +++ b/vue/src/components/SettingsWindow.vue @@ -1,7 +1,7 @@