diff --git a/.github/README.md b/.github/README.md index f5a559d84..2f76cb721 100644 --- a/.github/README.md +++ b/.github/README.md @@ -173,9 +173,6 @@ Recommended tool to develop backend module is IntelliJ IDE, for frontend it migh # Run only backend through CLI $ ./gradlew run -# Run only frontend -$ cd reposilite-frontend && npm i && npm run full - # Run only Reposilite site $ cd reposilite-site/website && npm i && npm run start ``` diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 6d9e7677e..3297c95b4 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,10 +4,6 @@ updates: directory: "/reposilite-backend" schedule: interval: "monthly" - - package-ecosystem: "npm" - directory: "/reposilite-frontend" - schedule: - interval: "monthly" - package-ecosystem: "npm" directory: "/reposilite-site" schedule: diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index f42f99f10..bafe92f9c 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -3,9 +3,9 @@ name: "Reposilite CI" on: push: - branches: [ "main", "3.0" ] + branches: [ "main", "3.0", "4.x" ] pull_request: - branches: [ "main", "3.0" ] + branches: [ "main", "3.0", "4.x" ] jobs: build: diff --git a/Dockerfile b/Dockerfile index 6da75680b..0056e84e9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,8 +2,6 @@ FROM openjdk:21-slim AS build COPY . /home/reposilite-build WORKDIR /home/reposilite-build -RUN \ - rm -rf reposilite-frontend/node_modules RUN \ apt-get update; apt-get install -y curl RUN \ diff --git a/build.gradle.kts b/build.gradle.kts index 43b42550a..15213a39d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -50,8 +50,6 @@ scmVersion { fileUpdate(".github/README.md") { version -> "dzikoysk/reposilite:$version" } fileUpdate("docker-compose.yml") { version -> "image: reposilite:$version" } fileUpdate("reposilite-backend/src/main/kotlin/com/reposilite/Reposilite.kt") { version -> "const val VERSION = \"$version\"" } - fileUpdate("reposilite-frontend/package.json") { version -> "\"version\": \"$version\"" } - fileUpdate("reposilite-frontend/package-lock.json") { version -> "\"version\": \"$version\"" } fileUpdate("reposilite-site/data/guides/developers/endpoints.md") { version -> "\"version\": \"$version\"" } fileUpdate("reposilite-site/data/guides/developers/plugin-api.md") { version -> "\"com.reposilite:reposilite:$version\"" } fileUpdate("reposilite-site/data/guides/installation/docker.md") { version -> version } diff --git a/reposilite-backend/build.gradle.kts b/reposilite-backend/build.gradle.kts index 5f20859c6..27479b2b5 100644 --- a/reposilite-backend/build.gradle.kts +++ b/reposilite-backend/build.gradle.kts @@ -34,8 +34,6 @@ application { } dependencies { - implementation(project(":reposilite-frontend")) - // val detekt = "1.23.5" // detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:$detekt") @@ -45,7 +43,6 @@ dependencies { val javalin = "6.3.0" api("io.javalin:javalin:$javalin") - api("io.javalin.community.ssl:ssl-plugin:$javalin") val javalinOpenApi = "6.3.0" api("io.javalin.community.openapi:javalin-openapi-plugin:$javalinOpenApi") @@ -71,21 +68,15 @@ dependencies { api("info.picocli:picocli:$picocli") val awssdk = "2.28.16" - implementation(platform("software.amazon.awssdk:bom:$awssdk")) implementation("software.amazon.awssdk:s3:$awssdk") - val awsSdkV1 = "1.12.773" - testImplementation("com.amazonaws:aws-java-sdk-s3:$awsSdkV1") - val exposed = "0.55.0" api("org.jetbrains.exposed:exposed-core:$exposed") - api("org.jetbrains.exposed:exposed-dao:$exposed") api("org.jetbrains.exposed:exposed-jdbc:$exposed") api("org.jetbrains.exposed:exposed-java-time:$exposed") // Drivers implementation("com.zaxxer:HikariCP:6.0.0") implementation("org.xerial:sqlite-jdbc:3.46.1.3") - implementation("mysql:mysql-connector-java:8.0.33") implementation("org.mariadb.jdbc:mariadb-java-client:3.4.1") implementation("org.postgresql:postgresql:42.7.4") implementation("com.h2database:h2:2.3.232") @@ -142,7 +133,6 @@ tasks.withType { exclude(dependency("org.eclipse.jetty:.*")) exclude(dependency("org.eclipse.jetty.http2:.*")) exclude(dependency("org.eclipse.jetty.websocket:.*")) - exclude(dependency("org.bouncycastle:.*")) exclude(dependency("com.fasterxml.woodstox:woodstox-core:.*")) exclude(dependency("commons-logging:commons-logging:.*")) exclude(dependency("org.jetbrains.kotlin:kotlin-reflect:.*")) diff --git a/reposilite-backend/src/integration/kotlin/com/reposilite/configuration/SettingsIntegrationTest.kt b/reposilite-backend/src/integration/kotlin/com/reposilite/configuration/SettingsIntegrationTest.kt index a448438b6..cb07935a8 100644 --- a/reposilite-backend/src/integration/kotlin/com/reposilite/configuration/SettingsIntegrationTest.kt +++ b/reposilite-backend/src/integration/kotlin/com/reposilite/configuration/SettingsIntegrationTest.kt @@ -25,7 +25,6 @@ import com.reposilite.auth.application.AuthenticationSettings import com.reposilite.auth.application.LdapSettings import com.reposilite.configuration.shared.SharedConfigurationFacade import com.reposilite.configuration.specification.SettingsIntegrationSpecification -import com.reposilite.frontend.application.FrontendSettings import com.reposilite.maven.application.MavenSettings import com.reposilite.shared.ErrorResponse import com.reposilite.statistics.api.ResolvedRequestsInterval.YEARLY @@ -51,7 +50,6 @@ internal abstract class SettingsIntegrationTest : SettingsIntegrationSpecificati "web" to WebSettings::class, "authentication" to AuthenticationSettings::class, "statistics" to StatisticsSettings::class, - "frontend" to FrontendSettings::class, "maven" to MavenSettings::class ) } @@ -120,7 +118,6 @@ internal abstract class SettingsIntegrationTest : SettingsIntegrationSpecificati "web" to WebSettings(forwardedIp = "test"), "authentication" to AuthenticationSettings(ldap = LdapSettings(enabled = true)), "statistics" to StatisticsSettings(resolvedRequestsInterval = YEARLY), - "frontend" to FrontendSettings(id = "test"), "maven" to MavenSettings(repositories = emptyList()) ) diff --git a/reposilite-backend/src/integration/kotlin/com/reposilite/configuration/StartupParametersIntegrationTest.kt b/reposilite-backend/src/integration/kotlin/com/reposilite/configuration/StartupParametersIntegrationTest.kt deleted file mode 100644 index d297f41f6..000000000 --- a/reposilite-backend/src/integration/kotlin/com/reposilite/configuration/StartupParametersIntegrationTest.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@file:Suppress("FunctionName") - -package com.reposilite.configuration - -import com.reposilite.ReposiliteParameters -import com.reposilite.configuration.shared.SharedConfigurationFacade -import com.reposilite.frontend.application.FrontendSettings -import com.reposilite.RecommendedLocalSpecificationJunitExtension -import com.reposilite.ReposiliteSpecification -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -import java.nio.file.Files - -@ExtendWith(RecommendedLocalSpecificationJunitExtension::class) -internal class StartupParametersIntegrationTest : ReposiliteSpecification() { - - override fun overrideParameters(parameters: ReposiliteParameters) { - // given: a custom shared configuration - parameters.sharedConfigurationPath = reposiliteWorkingDirectory.resolve("custom-shared-configuration.json").toPath() - Files.writeString( - parameters.sharedConfigurationPath, - """ - { - "frontend": { - "id": "test-repository" - } - } - """.trimIndent() - ) - } - - @Test - fun `should load custom shared configuration`() { - // when: modified settings are requested - val sharedConfigurationFacade = reposilite.extensions.facade() - val frontendSettings = sharedConfigurationFacade.getDomainSettings() - - // then: Reposilite should use file-based shared configuration - assertThat(frontendSettings.map { it.id }).isEqualTo("test-repository") - } - -} \ No newline at end of file diff --git a/reposilite-backend/src/integration/kotlin/com/reposilite/token/AccessTokenCommandsIntegrationTest.kt b/reposilite-backend/src/integration/kotlin/com/reposilite/token/AccessTokenCommandsIntegrationTest.kt deleted file mode 100644 index 3634634d4..000000000 --- a/reposilite-backend/src/integration/kotlin/com/reposilite/token/AccessTokenCommandsIntegrationTest.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@file:Suppress("FunctionName") - -package com.reposilite.token - -import com.reposilite.RecommendedLocalSpecificationJunitExtension -import com.reposilite.console.CommandStatus.SUCCEEDED -import com.reposilite.console.ConsoleFacade -import com.reposilite.token.AccessTokenPermission.MANAGER -import com.reposilite.token.RoutePermission.READ -import com.reposilite.token.specification.AccessTokenIntegrationSpecification -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.extension.ExtendWith -import panda.std.ResultAssertions.assertOk - -@ExtendWith(RecommendedLocalSpecificationJunitExtension::class) -internal class LocalAccessTokenCommandsIntegrationTest : AccessTokenCommandsIntegrationTest() - -internal abstract class AccessTokenCommandsIntegrationTest : AccessTokenIntegrationSpecification() { - - private val consoleFacade by lazy { reposilite.extensions.facade() } - - @Test - fun `should modify access token permissions`() { - // given: a token - val (name) = useAuth("name", "secret", listOf(), routes = mapOf("/" to READ)) - - // when: user updates the token - val firstResult = assertOk(consoleFacade.executeCommand("token-modify name m")) - /** - * Make sure that modification of token is properly handled by respecting the UNIQUE constraint - * ~ https://github.com/dzikoysk/reposilite/issues/1321 - */ - val secondResult = assertOk(consoleFacade.executeCommand("token-modify name m")) - - // then: the given token is updated - assertThat(firstResult.status).isEqualTo(SUCCEEDED) - assertThat(secondResult.status).isEqualTo(SUCCEEDED) - assertThat(useExistingToken(name).permissions).isEqualTo(setOf(MANAGER)) - } - - @Test - fun `should regenerate access token secret`() { - // given: a token - val (name) = useAuth("name", "secret", listOf(), routes = mapOf("/" to READ)) - - // when: user updates the token - val firstResult = assertOk(consoleFacade.executeCommand("token-regenerate name -s new-secret")) - - // then: the given token is updated - assertThat(firstResult.status).isEqualTo(SUCCEEDED) - assertThat(useFacade().secretMatches(useExistingToken(name).accessToken.identifier, "new-secret")).isTrue - } - -} \ No newline at end of file diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/console/CommandExecutor.kt b/reposilite-backend/src/main/kotlin/com/reposilite/console/CommandExecutor.kt deleted file mode 100644 index 41b3387ba..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/console/CommandExecutor.kt +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.reposilite.console - -import com.reposilite.VERSION -import com.reposilite.console.CommandStatus.FAILED -import com.reposilite.console.api.ExecutionResponse -import com.reposilite.console.api.ReposiliteCommand -import com.reposilite.journalist.Journalist -import com.reposilite.journalist.Logger -import com.reposilite.status.FailureFacade -import picocli.CommandLine -import picocli.CommandLine.Command -import picocli.CommandLine.MissingParameterException -import picocli.CommandLine.UnmatchedArgumentException -import java.io.InputStream -import java.util.function.Consumer - -@Command(name = "", version = ["Reposilite $VERSION"]) -internal class CommandExecutor( - private val journalist: Journalist, - failureFacade: FailureFacade, - source: InputStream -) : Journalist { - - private val consoleThread = ConsoleThread(this, source, failureFacade) - private val commandLine = CommandLine(this) - - fun execute(command: String): ExecutionResponse = - execute(command) { logger.info(it) } - - fun execute(command: String, outputConsumer: Consumer): ExecutionResponse = - executeCommand(command).also { - it.response.forEach { message -> - message.replace(System.lineSeparator(), "\n").split("\n").toTypedArray().forEach { line -> - outputConsumer.accept(line) - } - } - } - - private fun executeCommand(command: String): ExecutionResponse { - val processedCommand = command.trim() - - if (processedCommand.isEmpty()) { - return ExecutionResponse(FAILED, emptyList()) - } - - val response: MutableList = ArrayList() - - return try { - val parseResult = commandLine.parseArgs(*processedCommand.split(" ").toTypedArray()) - val commandObject = parseResult.subcommand().commandSpec().userObject() as? ReposiliteCommand - - commandObject - ?.let { - val context = CommandContext() - commandObject.execute(context) - ExecutionResponse(context.status, context.output()) - } - ?: ExecutionResponse(FAILED, listOf(commandLine.usageMessage)) - } catch (unmatchedArgumentException: UnmatchedArgumentException) { - ExecutionResponse(FAILED, listOf("Unknown command $processedCommand")) - } catch (missingParameterException: MissingParameterException) { - response.add(missingParameterException.message.toString()) - response.add("") - response.add(missingParameterException.commandLine.usageMessage) - ExecutionResponse(FAILED, response) - } - } - - fun registerCommand(command: ReposiliteCommand): CommandLine = - commandLine.addSubcommand(command) - - fun getCommands(): Map = - commandLine.subcommands - - fun hook() = - consoleThread.start() - - fun stop() = - consoleThread.interrupt() - - override fun getLogger(): Logger = - journalist.logger - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/console/ConsoleFacade.kt b/reposilite-backend/src/main/kotlin/com/reposilite/console/ConsoleFacade.kt deleted file mode 100644 index bd7ecf8b5..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/console/ConsoleFacade.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.console - -import com.reposilite.console.api.ExecutionResponse -import com.reposilite.console.api.ReposiliteCommand -import com.reposilite.journalist.Journalist -import com.reposilite.journalist.Logger -import com.reposilite.plugin.api.Facade -import com.reposilite.shared.ErrorResponse -import com.reposilite.shared.badRequestError -import panda.std.Result -import panda.std.asSuccess -import panda.utilities.StringUtils -import picocli.CommandLine - -const val MAX_COMMAND_LENGTH = 1024 - -class ConsoleFacade internal constructor( - private val journalist: Journalist, - internal val commandExecutor: CommandExecutor -) : Journalist, Facade { - - fun executeCommand(command: String): Result { - if (StringUtils.isEmpty(command)) { - return badRequestError("Missing command") - } - - if (command.length > MAX_COMMAND_LENGTH) { - return badRequestError("The given command exceeds allowed length (${command.length} > $MAX_COMMAND_LENGTH)") - } - - return commandExecutor.execute(command).asSuccess() - } - - fun registerCommand(command: ReposiliteCommand): CommandLine = - commandExecutor.registerCommand(command) - - fun getCommands(): Map = - commandExecutor.getCommands() - - override fun getLogger(): Logger = - journalist.logger - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/console/ConsoleThread.kt b/reposilite-backend/src/main/kotlin/com/reposilite/console/ConsoleThread.kt deleted file mode 100644 index d8d1f8ab9..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/console/ConsoleThread.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.reposilite.console - -import com.reposilite.status.FailureFacade -import java.io.InputStream -import java.util.* - -internal class ConsoleThread( - private val commandExecutor: CommandExecutor, - private val source: InputStream, - private val failureFacade: FailureFacade -) : Thread() { - - init { - name = "Reposilite | Console Thread" - isDaemon = true - } - - override fun run() { - val input = Scanner(source) - - if (!input.hasNextLine()) { - commandExecutor.logger.warn("Interactive CLI is not available in current environment.") - commandExecutor.logger.warn("Solution for Docker users: https://docs.docker.com/engine/reference/run/#foreground") - return - } - - do { - val command = input.nextLine().trim() - - if (command.isEmpty()) { - continue - } - - runCatching { - commandExecutor.logger.info("") - commandExecutor.execute(command) - commandExecutor.logger.info("") - }.onFailure { - failureFacade.throwException("Command: $command", it) - } - } while (!isInterrupted && input.hasNextLine()) - } - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/console/StandardCommands.kt b/reposilite-backend/src/main/kotlin/com/reposilite/console/StandardCommands.kt deleted file mode 100644 index 92dda61f3..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/console/StandardCommands.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.console - -import com.reposilite.Reposilite -import com.reposilite.ReposiliteJournalist -import com.reposilite.console.CommandStatus.FAILED -import com.reposilite.console.api.ReposiliteCommand -import com.reposilite.journalist.Channel -import com.reposilite.shared.extensions.createCommandHelp -import panda.std.Option.ofOptional -import picocli.CommandLine.Command -import picocli.CommandLine.Parameters -import java.util.concurrent.TimeUnit.SECONDS - -@Command(name = "help", aliases = ["?"], helpCommand = true, description = ["List of available commands"]) -internal class HelpCommand(private val consoleFacade: ConsoleFacade) : ReposiliteCommand { - - @Parameters(index = "0", paramLabel = "[]", description = ["Display usage of the given command"], defaultValue = "") - private lateinit var requestedCommand: String - - override fun execute(context: CommandContext) { - createCommandHelp(consoleFacade.getCommands(), requestedCommand) - .peek { context.appendAll(it) } - .onError { - context.append(it) - context.status = FAILED - } - } - -} - -@Command(name = "stop", aliases = ["shutdown"], description = ["Shutdown server"]) -internal class StopCommand(private val reposilite: Reposilite) : ReposiliteCommand { - - override fun execute(context: CommandContext) { - reposilite.logger.warn("The shutdown request has been sent") - reposilite.scheduler.schedule({ reposilite.shutdown() }, 1, SECONDS) - } - -} - -@Command(name = "level", description = ["Change current level of visible logging"]) -internal class LevelCommand(private val journalist: ReposiliteJournalist) : ReposiliteCommand { - - @Parameters(index = "0", paramLabel = "", description = ["The new threshold"], defaultValue = "info") - private lateinit var level: String - - override fun execute(context: CommandContext) { - ofOptional(Channel.of(level)) - .onEmpty { - context.status = FAILED - context.append("The new logging level has been set to $level") - } - .peek { - journalist.setVisibleThreshold(it) - context.append("The new logging level has been set to $level") - } - } - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/console/api/CommandsSetupEvent.kt b/reposilite-backend/src/main/kotlin/com/reposilite/console/api/CommandsSetupEvent.kt deleted file mode 100644 index 4dbed8a26..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/console/api/CommandsSetupEvent.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.console.api - -import com.reposilite.plugin.api.Event - -class CommandsSetupEvent : Event { - - private val commands = mutableListOf() - - fun registerCommand(command: ReposiliteCommand) { - commands.add(command) - } - - fun getCommands(): Collection = - commands - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/console/api/ReposiliteCommand.kt b/reposilite-backend/src/main/kotlin/com/reposilite/console/api/ReposiliteCommand.kt deleted file mode 100644 index 9d6d536d6..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/console/api/ReposiliteCommand.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.reposilite.console.api - -import com.reposilite.console.CommandContext - -interface ReposiliteCommand { - - fun execute(context: CommandContext) - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/console/application/ConsoleComponents.kt b/reposilite-backend/src/main/kotlin/com/reposilite/console/application/ConsoleComponents.kt deleted file mode 100644 index ac52025a0..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/console/application/ConsoleComponents.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.console.application - -import com.reposilite.console.CommandExecutor -import com.reposilite.console.ConsoleFacade -import com.reposilite.journalist.Journalist -import com.reposilite.status.FailureFacade -import java.io.InputStream - -internal class ConsoleComponents( - private val journalist: Journalist, - private val failureFacade: FailureFacade -) { - - private fun consoleInput(): InputStream = - System.`in` - - private fun commandExecutor(): CommandExecutor = - CommandExecutor( - journalist = journalist, - failureFacade = failureFacade, - source = consoleInput() - ) - - fun consoleFacade(commandExecutor: CommandExecutor = commandExecutor()): ConsoleFacade = - ConsoleFacade( - journalist = journalist, - commandExecutor = commandExecutor - ) - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/console/application/ConsolePlugin.kt b/reposilite-backend/src/main/kotlin/com/reposilite/console/application/ConsolePlugin.kt index 8bad340e6..212dda1b0 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/console/application/ConsolePlugin.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/console/application/ConsolePlugin.kt @@ -16,34 +16,23 @@ package com.reposilite.console.application import com.reposilite.configuration.shared.SharedConfigurationFacade -import com.reposilite.console.HelpCommand -import com.reposilite.console.LevelCommand -import com.reposilite.console.StopCommand -import com.reposilite.console.api.CommandsSetupEvent -import com.reposilite.console.infrastructure.ConsoleWebSocketHandler -import com.reposilite.console.infrastructure.ConsoleEndpoint import com.reposilite.console.infrastructure.ConsoleSseHandler import com.reposilite.plugin.api.Facade import com.reposilite.plugin.api.Plugin import com.reposilite.plugin.api.ReposiliteDisposeEvent -import com.reposilite.plugin.api.ReposiliteInitializeEvent import com.reposilite.plugin.api.ReposilitePlugin -import com.reposilite.plugin.api.ReposiliteStartedEvent import com.reposilite.plugin.event import com.reposilite.plugin.facade -import com.reposilite.plugin.parameters import com.reposilite.plugin.reposilite import com.reposilite.web.api.HttpServerInitializationEvent -import com.reposilite.web.api.RoutingSetupEvent import com.reposilite.web.application.WebSettings import io.javalin.http.sse.SseClient @Plugin(name = "console", dependencies = [ "shared-configuration", "failure", "access-token", "authentication" ]) internal class ConsolePlugin : ReposilitePlugin() { - override fun initialize(): Facade { + override fun initialize(): Facade? { val sharedConfigurationFacade = facade() - val consoleFacade = ConsoleComponents(this, facade()).consoleFacade() val client = ConsoleSseHandler( journalist = reposilite().journalist, accessTokenFacade = facade(), @@ -52,37 +41,8 @@ internal class ConsolePlugin : ReposilitePlugin() { scheduler = reposilite().scheduler ) - event { _: ReposiliteInitializeEvent -> - consoleFacade.registerCommand(HelpCommand(consoleFacade)) - consoleFacade.registerCommand(LevelCommand(reposilite().journalist)) - consoleFacade.registerCommand(StopCommand(reposilite())) - - val setup = extensions().emitEvent(CommandsSetupEvent()) - setup.getCommands().forEach { consoleFacade.registerCommand(it) } - - // disable console daemon in tests due to issues with coverage and interrupt method call - // https://github.com/jacoco/jacoco/issues/1066 - if (!parameters().testEnv) { - consoleFacade.commandExecutor.hook() - } - } - - event { event: RoutingSetupEvent -> - event.registerRoutes(ConsoleEndpoint(consoleFacade)) - } - event { event: HttpServerInitializationEvent -> event.config.router.mount { - it.ws( - "/api/console/sock", - ConsoleWebSocketHandler( - journalist = reposilite().journalist, - accessTokenFacade = facade(), - authenticationFacade = facade(), - consoleFacade = consoleFacade, - forwardedIp = sharedConfigurationFacade.getDomainSettings().computed { it.forwardedIp } - ) - ) it.sse( "/api/console/log", client::handleSseLiveLog @@ -90,24 +50,11 @@ internal class ConsolePlugin : ReposilitePlugin() { } } - if (!parameters().testEnv) { - event { _: ReposiliteStartedEvent -> - reposilite().ioService.execute { - logger.info("Collecting status metrics...") - logger.info("") - consoleFacade.executeCommand("status") - logger.info("") - logger.info("For help, type 'help' or '?'") - } - } - } - event { _: ReposiliteDisposeEvent -> - consoleFacade.commandExecutor.stop() client.users.keys.forEach(SseClient::close) } - return consoleFacade + return null } } diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/console/infrastructure/ConsoleEndpoint.kt b/reposilite-backend/src/main/kotlin/com/reposilite/console/infrastructure/ConsoleEndpoint.kt deleted file mode 100644 index 33cb31384..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/console/infrastructure/ConsoleEndpoint.kt +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.reposilite.console.infrastructure - -import com.reposilite.console.ConsoleFacade -import com.reposilite.console.MAX_COMMAND_LENGTH -import com.reposilite.console.api.ExecutionResponse -import com.reposilite.shared.ErrorResponse -import com.reposilite.shared.unauthorizedError -import com.reposilite.web.api.ReposiliteRoute -import com.reposilite.web.api.ReposiliteRoutes -import io.javalin.community.routing.Route -import io.javalin.community.routing.Route.POST -import io.javalin.openapi.HttpMethod -import io.javalin.openapi.OpenApi -import io.javalin.openapi.OpenApiContent -import io.javalin.openapi.OpenApiParam -import io.javalin.openapi.OpenApiResponse - -internal class ConsoleEndpoint(private val consoleFacade: ConsoleFacade) : ReposiliteRoutes() { - - @OpenApi( - path = "/api/console/execute", - methods = [HttpMethod.POST], - summary = "Remote command execution", - description = "Execute command using POST request. The commands are the same as in the console and can be listed using the 'help' command.", - tags = ["Cli"], - headers = [OpenApiParam(name = "Authorization", description = "Name and secret provided as basic auth credentials", required = true)], - responses = [ - OpenApiResponse( - status = "200", - description = "Status of the executed command", - content = [OpenApiContent(from = ExecutionResponse::class)] - ), - OpenApiResponse( - status = "400", - description = "Error message related to the invalid command format (0 < command length < $MAX_COMMAND_LENGTH)", - content = [OpenApiContent(from = ErrorResponse::class)] - ), - OpenApiResponse( - status = "401", - description = "Error message related to the unauthorized access", - content = [OpenApiContent(from = ErrorResponse::class)] - ) - ] - ) - private val executeCommand = ReposiliteRoute("/api/console/execute", POST) { - logger.info("REMOTE EXECUTION $uri from ${ctx.ip()}") - - authenticated { - isManager() - .peek { - logger.info("$name (${ctx.ip()}) requested command: ${ctx.body()}") - response = consoleFacade.executeCommand(ctx.body()) - } - .onError { response = unauthorizedError("Authenticated user is not a manager") } - } - } - - override val routes = routes(executeCommand) - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/console/infrastructure/ConsoleWebSocketHandler.kt b/reposilite-backend/src/main/kotlin/com/reposilite/console/infrastructure/ConsoleWebSocketHandler.kt index 0b2b71471..e76b6ad70 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/console/infrastructure/ConsoleWebSocketHandler.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/console/infrastructure/ConsoleWebSocketHandler.kt @@ -15,27 +15,6 @@ */ package com.reposilite.console.infrastructure -import com.reposilite.ReposiliteJournalist -import com.reposilite.auth.AuthenticationFacade -import com.reposilite.auth.api.Credentials -import com.reposilite.console.ConsoleFacade -import com.reposilite.shared.ErrorResponse -import com.reposilite.shared.extractFromString -import com.reposilite.shared.unauthorized -import com.reposilite.shared.unauthorizedError -import com.reposilite.token.AccessTokenFacade -import com.reposilite.token.AccessTokenPermission.MANAGER -import io.javalin.openapi.HttpMethod -import io.javalin.openapi.OpenApi -import io.javalin.websocket.WsConfig -import io.javalin.websocket.WsContext -import io.javalin.websocket.WsMessageContext -import panda.std.Result -import panda.std.reactive.Reference -import java.nio.channels.ClosedChannelException -import java.util.WeakHashMap -import java.util.function.Consumer - private const val AUTHORIZATION_PREFIX = "Authorization:" private data class WsSession( @@ -43,89 +22,3 @@ private data class WsSession( val subscriberId: Int, ) -internal class ConsoleWebSocketHandler( - private val journalist: ReposiliteJournalist, - private val accessTokenFacade: AccessTokenFacade, - private val authenticationFacade: AuthenticationFacade, - private val consoleFacade: ConsoleFacade, - private val forwardedIp: Reference -) : Consumer { - - private val users: WeakHashMap = WeakHashMap() - - @OpenApi( - path = "/api/console/sock", - methods = [HttpMethod.PATCH], - tags = ["Console"] - ) - override fun accept(ws: WsConfig) { - ws.onMessage { ctx -> - when (val session = users[ctx]) { - null -> - authenticateContext(ctx) - .peek { identifier -> - journalist.logger.info("CLI | $identifier accessed remote console") - - val subscriberId = journalist.subscribe { - try { - ctx.send(it.value) - } catch (ignored: ClosedChannelException) { - journalist.logger.debug("CLI | $identifier tried to write to closed channel") - } - } - - users[ctx] = WsSession(identifier, subscriberId) - - journalist.cachedLogger.messages.forEach { message -> - ctx.send(message.value) - } - } - .onError { - journalist.logger.info("CLI | ${it.message} (${it.status})") - ctx.send(it) - ctx.session.disconnect() - } - else -> - when (val message = ctx.message()) { - "keep-alive" -> ctx.send("keep-alive") - else -> { - journalist.logger.info("CLI | ${session.identifier}> $message") - consoleFacade.executeCommand(message) - } - } - } - } - ws.onClose { ctx -> - val session = users.remove(ctx) ?: return@onClose - journalist.logger.info("CLI | ${session.identifier} closed connection") - journalist.unsubscribe(session.subscriberId) - } - } - - private fun authenticateContext(connection: WsMessageContext): Result { - val authMessage = connection.message() - - if (!authMessage.startsWith(AUTHORIZATION_PREFIX)) { - return unauthorizedError("Unauthorized CLI access request from ${connection.getHost()} (missing credentials)") - } - - return extractFromString(authMessage.replaceFirst(AUTHORIZATION_PREFIX, "")) - .map { (name, secret) -> - Credentials( - host = connection.getHost(), - name = name, - secret = secret - ) - } - .flatMap { authenticationFacade.authenticateByCredentials(it) } - .filter( - { accessTokenFacade.hasPermission(it.identifier, MANAGER) }, - { unauthorized("Unauthorized CLI access request from ${connection.getHost()}") } - ) - .map { "${it.name}@${connection.getHost()}" } - } - - private fun WsContext.getHost(): String = - header(forwardedIp.get()) ?: session.remoteAddress.toString() - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/.gitkeep b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/BasePathFormatter.kt b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/BasePathFormatter.kt deleted file mode 100644 index a785c33a2..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/BasePathFormatter.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.frontend - -import panda.std.letIf - -internal object BasePathFormatter { - - private val pathRegex = Regex("^/|/$") - - fun formatBasePath(originBasePath: String): String = - originBasePath - .letIf({ it.isNotEmpty() && !it.startsWith("/") }, { "/$it" }) - .letIf({ it.isNotEmpty() && !it.endsWith("/")}, { "$it/" }) - - fun formatAsViteBasePath(path: String): String = - path - .takeIf { hasCustomBasePath(it) } - ?.replace(pathRegex, "") // remove first & last slash - ?: "." // no custom base path - - private fun hasCustomBasePath(path: String): Boolean = - path != "" && path != "/" - -} \ No newline at end of file diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/FrontendFacade.kt b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/FrontendFacade.kt deleted file mode 100644 index ab3be327f..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/FrontendFacade.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.reposilite.frontend - -import com.reposilite.frontend.BasePathFormatter.formatAsViteBasePath -import com.reposilite.frontend.application.FrontendSettings -import com.reposilite.plugin.api.Facade -import panda.std.reactive.Reference -import panda.std.reactive.computed -import java.net.URLEncoder -import java.nio.charset.StandardCharsets - -class FrontendFacade internal constructor( - basePath: Reference, - private val frontendSettings: Reference -) : Facade { - - private val resources = HashMap(0) - val formattedBasePath = basePath.computed { BasePathFormatter.formatBasePath(it) } - - init { - computed(basePath, formattedBasePath, frontendSettings) { - resources.clear() - } - } - - fun resolve(uri: String, source: Source): ResourceSupplier? = - resources[uri] ?: createProcessedResource(uri, source) - - private fun createProcessedResource(uri: String, source: Source): ResourceSupplier? = - source.get() - ?.let { createLazyPlaceholderResolver().createProcessedResource(it) } - ?.also { resources[uri] = it } - - private fun createLazyPlaceholderResolver(): LazyPlaceholderResolver = - with (frontendSettings.get()) { - LazyPlaceholderResolver(mapOf( - "{{REPOSILITE.BASE_PATH}}" to formattedBasePath.get(), - URLEncoder.encode("{{REPOSILITE.BASE_PATH}}", StandardCharsets.UTF_8) to formattedBasePath.get(), - - "{{REPOSILITE.VITE_BASE_PATH}}" to formatAsViteBasePath(formattedBasePath.get()), - URLEncoder.encode("{{REPOSILITE.VITE_BASE_PATH}}", StandardCharsets.UTF_8) to formatAsViteBasePath(formattedBasePath.get()), - - "{{REPOSILITE.ID}}" to id, - "{{REPOSILITE.TITLE}}" to title, - "{{REPOSILITE.DESCRIPTION}}" to description, - "{{REPOSILITE.ORGANIZATION_WEBSITE}}" to organizationWebsite, - "{{REPOSILITE.ORGANIZATION_LOGO}}" to organizationLogo, - "{{REPOSILITE.ICP_LICENSE}}" to icpLicense, - )) - } - - fun createNotFoundPage(originUri: String, details: String): String = - NotFoundTemplate.createNotFoundPage(formattedBasePath.get(), originUri, details) - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/LazyPlaceholderResolver.kt b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/LazyPlaceholderResolver.kt deleted file mode 100644 index d22609155..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/LazyPlaceholderResolver.kt +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.frontend - -import panda.std.Result -import java.io.IOException -import java.io.InputStream -import java.io.OutputStream -import java.nio.charset.MalformedInputException -import java.nio.charset.StandardCharsets.UTF_8 -import java.nio.file.Files -import java.nio.file.StandardOpenOption - -internal class LazyPlaceholderResolver(private val placeholders: Map) { - - init { - verifyPlaceholders() - } - - private val theLongestPlaceholderInBytes = placeholders.keys - .maxOfOrNull { it } - ?.toByteArray(Charsets.UTF_8) - ?.size - ?: 0 - - fun createProcessedResource(input: InputStream): ResourceSupplier { - val temporaryResourcePath = Files.createTempFile("reposilite", "frontend-resource") - - input.use { inputStream -> - Files.newOutputStream(temporaryResourcePath, StandardOpenOption.WRITE).use { outputStream -> - process(inputStream, outputStream) - } - } - - return ResourceSupplier { - Result.supplyThrowing(IOException::class.java) { - Files.newInputStream(temporaryResourcePath) - } - } - } - - fun process(input: InputStream, output: OutputStream) { - val buffer = ByteArray(1024) - - while (true) { - var readLength = input.read(buffer) - .takeIf { it != -1 } - ?: break - - // check if current content may end with placeholder - val processedBuffer = when (readLength) { - buffer.size -> loadSlicedPlaceholders(input, buffer).also { readLength = it.size } - else -> buffer - } - - try { - // try to decode content - var content = processedBuffer.decodeToString( - endIndex = readLength, - throwOnInvalidSequence = true - ) - - // resolve placeholders - for ((name, value) in placeholders) { - content = content.replace(name, value) - } - - // save processed content - val resolvedContentAsBytes = content.toByteArray(UTF_8) - output.write(resolvedContentAsBytes, 0, resolvedContentAsBytes.size) - } catch (exception: MalformedInputException) { - // given frame may contain invalid UTF-8 sequence, so we cannot decode it - output.write(processedBuffer, 0, readLength) - } - } - } - - private fun loadSlicedPlaceholders(input: InputStream, buffer: ByteArray): ByteArray { - val borderlineStartIndex = buffer.size - theLongestPlaceholderInBytes + 1 - val positionCount = buffer.size - borderlineStartIndex - - for (index in 0 until positionCount) { - val placeholderStartIndex = borderlineStartIndex + index - val boundaryPlaceholder = buffer.copyOfRange(placeholderStartIndex, buffer.size).decodeToString() // .substring(placeholderStartIndex, content.length) - - for (placeholder in placeholders.keys) { - if (placeholder.startsWith(boundaryPlaceholder)) { - val missingBuffer = ByteArray(theLongestPlaceholderInBytes) - val missingLength = input.read(missingBuffer) - - if (missingLength == -1) { - return buffer - } - - val contentWithMissingPlaceholder = buffer + missingBuffer - return loadSlicedPlaceholders(input, contentWithMissingPlaceholder) - } - } - } - - return buffer - } - - private fun verifyPlaceholders() { - placeholders.keys.forEach { placeholder -> - placeholder.forEach { - if (it.code > Byte.MAX_VALUE) { - throw UnsupportedOperationException("LazyPlaceholderResolve supports only basic placeholders from 1-byte long symbols") - } - } - } - } - -} \ No newline at end of file diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/NotFoundTemplate.kt b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/NotFoundTemplate.kt deleted file mode 100644 index 87b4c31a2..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/NotFoundTemplate.kt +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.frontend - -import org.intellij.lang.annotations.Language - -object NotFoundTemplate { - - private val uriFormatter = Regex("/+") // exclude common typos from URI - private val regexAntiXss = Regex("[^A-Za-z0-9/.\\- ]") // exclude custom non-standard characters from template - - fun createNotFoundPage(basePath: String, originUri: String, details: String): String { - val uri = originUri.replace(uriFormatter, "/") - val dashboardUrl = basePath + (if (basePath.endsWith("/")) "" else "/") + "#" + uri - - @Language("html") - val response = """ - - - - Reposilite - 404 Not Found - - - -
-

- 404︱Resource not found -

- ${if (details.isEmpty()) "" else "

${regexAntiXss.replace(details, "")}

" } -

Looking for a dashboard?

-
-

{\__/}

-

(●ᴗ●)

-

( >🥕

-
-

Visit $dashboardUrl

-
- - - """ - - return response.trimIndent() - } - -} \ No newline at end of file diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/ResourceSupplier.kt b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/ResourceSupplier.kt deleted file mode 100644 index f0fb65f59..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/ResourceSupplier.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.frontend - -import panda.std.Result -import java.io.IOException -import java.io.InputStream - -fun interface Source { - fun get(): InputStream? -} - -fun interface ResourceSupplier { - fun supply(): Result -} \ No newline at end of file diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/application/FrontendComponents.kt b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/application/FrontendComponents.kt deleted file mode 100644 index b75c30c31..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/application/FrontendComponents.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.frontend.application - -import com.reposilite.frontend.FrontendFacade -import com.reposilite.plugin.api.PluginComponents -import panda.std.reactive.Reference - -class FrontendComponents( - private val basePath: Reference, - private val frontendSettings: Reference -) : PluginComponents { - - fun frontendFacade(): FrontendFacade = - FrontendFacade( - basePath = basePath, - frontendSettings = frontendSettings - ) - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/application/FrontendPlugin.kt b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/application/FrontendPlugin.kt deleted file mode 100644 index 846d8a957..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/application/FrontendPlugin.kt +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.frontend.application - -import com.reposilite.Reposilite -import com.reposilite.configuration.local.LocalConfiguration -import com.reposilite.configuration.shared.SharedConfigurationFacade -import com.reposilite.frontend.FrontendFacade -import com.reposilite.frontend.infrastructure.CustomFrontendHandler -import com.reposilite.frontend.infrastructure.NotFoundHandler -import com.reposilite.frontend.infrastructure.ResourcesFrontendHandler -import com.reposilite.plugin.api.Plugin -import com.reposilite.plugin.api.ReposiliteInitializeEvent -import com.reposilite.plugin.api.ReposilitePlugin -import com.reposilite.plugin.event -import com.reposilite.plugin.facade -import com.reposilite.status.FailureFacade -import com.reposilite.web.api.HttpServerInitializationEvent -import com.reposilite.web.api.ReposiliteRoutes -import com.reposilite.web.api.RoutingSetupEvent -import io.javalin.http.NotFoundResponse -import java.nio.file.Files -import java.nio.file.Path -import kotlin.io.path.exists - -@Plugin(name = "frontend", dependencies = ["local-configuration", "shared-configuration", "failure"], settings = FrontendSettings::class) -internal class FrontendPlugin : ReposilitePlugin() { - - internal companion object { - private const val STATIC_DIRECTORY = "static" - private const val FRONTEND_DIRECTORY = "reposilite-frontend" - private const val INDEX = "index.html" - private const val FAVICON = "favicon.png" - } - - override fun initialize(): FrontendFacade { - val localConfiguration = facade() - val failureFacade = facade() - val sharedConfigurationFacade = facade() - val frontendSettings = sharedConfigurationFacade.getDomainSettings() - - val frontendFacade = FrontendComponents( - basePath = localConfiguration.basePath, - frontendSettings = frontendSettings - ).frontendFacade() - - event { event: ReposiliteInitializeEvent -> - val staticDirectory = staticDirectory(event.reposilite) - - staticDirectory - .takeUnless { it.exists() } - ?.also { Files.createDirectory(it) } - ?.also { copyResourceTo(INDEX, it.resolve(INDEX)) } - - staticDirectory.resolve(FAVICON) - .takeUnless { it.exists() } - ?.also { copyResourceTo(FAVICON, it) } - } - - event { event: RoutingSetupEvent -> - val routes = mutableSetOf() - - if (localConfiguration.defaultFrontend.get()) { - routes.add( - ResourcesFrontendHandler( - failureFacade = failureFacade, - frontendFacade = frontendFacade, - resourcesDirectory = FRONTEND_DIRECTORY - ) - ) - } - - routes.add( - CustomFrontendHandler( - failureFacade = failureFacade, - frontendFacade = frontendFacade, - directory = staticDirectory(event.reposilite) - ) - ) - - event.registerRoutes(routes) - } - - event { event: HttpServerInitializationEvent -> - event.config.router.mount { - it.exception(NotFoundResponse::class.java, NotFoundHandler(frontendFacade)) - it.error(404, NotFoundHandler(frontendFacade)) - } - } - - return frontendFacade - } - - private fun copyResourceTo(file: String, to: Path) { - Reposilite::class.java.getResourceAsStream("/$STATIC_DIRECTORY/$file")?.use { - Files.copy(it, to) - } - } - - private fun staticDirectory(reposilite: Reposilite): Path = - reposilite.parameters.workingDirectory.resolve(STATIC_DIRECTORY) - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/application/FrontendSettings.kt b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/application/FrontendSettings.kt deleted file mode 100644 index 3d312d29d..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/application/FrontendSettings.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.frontend.application - -import com.reposilite.configuration.shared.api.Doc -import com.reposilite.configuration.shared.api.SharedSettings -import io.javalin.openapi.JsonSchema - -@JsonSchema(requireNonNulls = false) -@Doc(title = "Frontend", description = "Frontend settings") -data class FrontendSettings( - @get:Doc(title = "Id", description = "Repository id used in Maven repository configuration") - val id: String = "reposilite-repository", - @get:Doc(title = "Title", description = "The title displayed on the frontend homepage.") - val title: String = "Reposilite Repository", - @get:Doc(title = "Description", description = "The description displayed on the frontend homepage.") - val description: String = "Public Maven repository hosted through the Reposilite", - @get:Doc(title = "Organisation Website", description = "Link to organization's website.") - val organizationWebsite: String = "https://reposilite.com", - @get:Doc(title = "Organisation Logo", description = "Link to organization's logo.") - val organizationLogo: String = "https://avatars.githubusercontent.com/u/88636591", - @get:Doc(title = "ICP License", description = """ - Web services in China require ICP license, a permit issued by the Chinese government to permit China-based websites to operate in China. - In order to fulfill the conditions, you should apply for ICP license from your service provider and fill in this parameter. - """) - val icpLicense: String = "", -) : SharedSettings diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/FrontendHandler.kt b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/FrontendHandler.kt deleted file mode 100644 index 0ba5e2987..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/FrontendHandler.kt +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.frontend.infrastructure - -import com.reposilite.frontend.FrontendFacade -import com.reposilite.frontend.Source -import com.reposilite.shared.ErrorResponse -import com.reposilite.shared.extensions.encoding -import com.reposilite.shared.notFoundError -import com.reposilite.status.FailureFacade -import com.reposilite.storage.api.toLocation -import com.reposilite.storage.getExtension -import com.reposilite.storage.getSimpleName -import com.reposilite.storage.inputStream -import com.reposilite.web.api.ReposiliteRoute -import com.reposilite.web.api.ReposiliteRoutes -import io.javalin.community.routing.Route.GET -import io.javalin.http.ContentType -import io.javalin.http.Context -import io.javalin.http.HttpStatus.INTERNAL_SERVER_ERROR -import java.io.InputStream -import java.nio.charset.StandardCharsets.UTF_8 -import java.nio.file.Files -import java.nio.file.Path -import kotlin.io.path.isDirectory -import kotlin.streams.asSequence -import panda.std.Result -import panda.std.asSuccess - -internal sealed class FrontendHandler( - private val frontendFacade: FrontendFacade, - private val failureFacade: FailureFacade, -) : ReposiliteRoutes() { - - protected fun respondWithResource(ctx: Context, uri: String, source: Source): Result { - val contentType = ContentType.getContentTypeByExtension(uri.getExtension()) - ctx.contentType(contentType?.mimeType ?: ContentType.OCTET_STREAM) - - return when (uri.contains(".html") || uri.contains(".js")) { - true -> respondWithProcessedResource(ctx, uri, source) - else -> respondWithRawResource(source) - } - } - - private fun respondWithProcessedResource(ctx: Context, uri: String, source: Source): Result = - frontendFacade.resolve(uri) { source.get() } - ?.let { resource -> - resource - .supply() - .peek { ctx.encoding(UTF_8) } - .onError { failureFacade.throwException(uri, it) } - .mapErr { ErrorResponse(INTERNAL_SERVER_ERROR, "Cannot serve resource") } - } - ?: notFoundError("Resource not found") - - private fun respondWithRawResource(source: Source): Result = - source.get() - ?.asSuccess() - ?: notFoundError("Resource not found") - -} - -internal class ResourcesFrontendHandler( - failureFacade: FailureFacade, - frontendFacade: FrontendFacade, - private val resourcesDirectory: String -) : FrontendHandler(frontendFacade, failureFacade) { - - private val defaultHandler = ReposiliteRoute("/", GET) { - response = respondWithBundledResource(ctx, "index.html") - } - - private val indexHandler = ReposiliteRoute("/index.html", GET) { - response = respondWithBundledResource(ctx, "index.html") - } - - private val assetsHandler = ReposiliteRoute("/assets/", GET) { - response = respondWithBundledResource(ctx, "assets/${ctx.pathParam("path")}") - } - - private fun respondWithBundledResource(ctx: Context, uri: String): Result = - respondWithResource(ctx, uri) { - FrontendFacade::class.java.getResourceAsStream("/$resourcesDirectory/$uri") ?: "".toByteArray().inputStream() - } - - override val routes = routes(defaultHandler, indexHandler, assetsHandler) - -} - -internal class CustomFrontendHandler( - failureFacade: FailureFacade, - frontendFacade: FrontendFacade, - directory: Path -) : FrontendHandler(frontendFacade, failureFacade) { - - private fun rootFileHandler(file: Path) = ReposiliteRoute("/${file.getSimpleName()}", GET) { - response = respondWithResource(ctx, file.getSimpleName()) { - file.inputStream().orNull() - } - } - - private fun directoryHandler(directory: Path) = ReposiliteRoute("/${directory.fileName}/", GET) { - response = respondWithResource(ctx, directory.getSimpleName()) { - parameter("path") - .toLocation() - .toPath() - .map { path -> directory.resolve(path) } - .flatMap { path -> path.inputStream().mapErr { error -> error.message } } - .orNull() - } - } - - private fun indexHandler(directory: Path) = ReposiliteRoute("/", GET) { - response = respondWithResource(ctx, "index.html") { - directory.resolve("index.html") - .inputStream() - .orNull() - } - } - - override val routes = - Files.list(directory).use { staticDirectoryStream -> - staticDirectoryStream.asSequence() - .map { - when { - it.isDirectory() -> directoryHandler(it) - else -> rootFileHandler(it) - } - } - .toMutableSet() - .also { it.add(indexHandler(directory)) } - .let { routes(*it.toTypedArray()) } - } - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/NotFoundHandler.kt b/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/NotFoundHandler.kt deleted file mode 100644 index 53313a3c5..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/frontend/infrastructure/NotFoundHandler.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.frontend.infrastructure - -import com.reposilite.frontend.FrontendFacade -import io.javalin.http.Context -import io.javalin.http.ExceptionHandler -import io.javalin.http.Handler -import io.javalin.http.HttpStatus.NOT_FOUND -import io.javalin.http.NotFoundResponse - -internal class NotFoundHandler(private val frontendFacade: FrontendFacade) : Handler, ExceptionHandler { - - // It does not support async handlers - private val defaultNotFoundHandler: (Context) -> Unit = { ctx -> - if (ctx.resultInputStream() == null) { - ctx.html(frontendFacade.createNotFoundPage(ctx.req().requestURI, "")) - ctx.status(NOT_FOUND) - } - } - - override fun handle(ctx: Context) = - defaultNotFoundHandler(ctx) - - override fun handle(exception: NotFoundResponse, ctx: Context) = - defaultNotFoundHandler(ctx) - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/maven/application/MavenComponents.kt b/reposilite-backend/src/main/kotlin/com/reposilite/maven/application/MavenComponents.kt index d6314b5ed..ae4ab64bd 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/maven/application/MavenComponents.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/maven/application/MavenComponents.kt @@ -17,7 +17,6 @@ package com.reposilite.maven.application import com.reposilite.auth.AuthenticationFacade -import com.reposilite.frontend.application.FrontendSettings import com.reposilite.journalist.Journalist import com.reposilite.maven.LatestService import com.reposilite.maven.MavenFacade @@ -48,7 +47,7 @@ internal class MavenComponents( private val accessTokenFacade: AccessTokenFacade, private val statisticsFacade: StatisticsFacade, private val mavenSettings: Reference, - private val frontendSettings: Reference, + private val id: Reference, ) : PluginComponents { private fun securityProvider(): RepositorySecurityProvider = @@ -82,7 +81,7 @@ internal class MavenComponents( ) private fun latestService(): LatestService = - LatestService(frontendSettings.computed { it.id }) + LatestService(id) fun mavenFacade( securityProvider: RepositorySecurityProvider = securityProvider(), diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/maven/application/MavenPlugin.kt b/reposilite-backend/src/main/kotlin/com/reposilite/maven/application/MavenPlugin.kt index 46b401c0c..b21192def 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/maven/application/MavenPlugin.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/maven/application/MavenPlugin.kt @@ -18,7 +18,6 @@ package com.reposilite.maven.application import com.reposilite.configuration.local.LocalConfiguration import com.reposilite.configuration.shared.SharedConfigurationFacade -import com.reposilite.frontend.application.FrontendSettings import com.reposilite.maven.MavenFacade import com.reposilite.maven.PreservedBuildsListener import com.reposilite.maven.infrastructure.MavenApiEndpoints @@ -32,11 +31,12 @@ import com.reposilite.plugin.facade import com.reposilite.plugin.parameters import com.reposilite.shared.http.HttpRemoteClientProvider import com.reposilite.web.api.RoutingSetupEvent +import panda.std.reactive.Reference import java.time.Clock @Plugin( name = "maven", - dependencies = ["failure", "local-configuration", "shared-configuration", "statistics", "frontend", "authentication", "access-token", "storage"], + dependencies = ["failure", "local-configuration", "shared-configuration", "statistics", "authentication", "access-token", "storage"], settings = MavenSettings::class ) internal class MavenPlugin : ReposilitePlugin() { @@ -57,7 +57,7 @@ internal class MavenPlugin : ReposilitePlugin() { accessTokenFacade = facade(), statisticsFacade = facade(), mavenSettings = sharedConfigurationFacade.getDomainSettings(), - frontendSettings = sharedConfigurationFacade.getDomainSettings() + id = Reference.reference("repository-id"), // todo: get repo id from cfg ).mavenFacade() logger.info("") @@ -68,7 +68,7 @@ internal class MavenPlugin : ReposilitePlugin() { event { event: RoutingSetupEvent -> val localConfiguration = facade() event.registerRoutes(MavenApiEndpoints(mavenFacade)) - event.registerRoutes(MavenEndpoints(mavenFacade, facade(), localConfiguration.compressionStrategy.get())) + event.registerRoutes(MavenEndpoints(mavenFacade, basePath = "/", localConfiguration.compressionStrategy.get())) // todo: check base-path event.registerRoutes(MavenLatestApiEndpoints(mavenFacade, localConfiguration.compressionStrategy.get())) } diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/maven/infrastructure/MavenEndpoints.kt b/reposilite-backend/src/main/kotlin/com/reposilite/maven/infrastructure/MavenEndpoints.kt index 047d7564d..2f28d4b5a 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/maven/infrastructure/MavenEndpoints.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/maven/infrastructure/MavenEndpoints.kt @@ -16,7 +16,6 @@ package com.reposilite.maven.infrastructure -import com.reposilite.frontend.FrontendFacade import com.reposilite.maven.MavenFacade import com.reposilite.maven.api.DeleteRequest import com.reposilite.maven.api.DeployRequest @@ -26,30 +25,20 @@ import com.reposilite.shared.extensions.resultAttachment import com.reposilite.shared.extensions.uri import com.reposilite.storage.api.DirectoryInfo import com.reposilite.storage.api.DocumentInfo -import com.reposilite.storage.api.FileType import com.reposilite.storage.api.Location import com.reposilite.token.AccessTokenIdentifier import com.reposilite.web.api.ReposiliteRoute -import io.javalin.community.routing.Route.DELETE -import io.javalin.community.routing.Route.GET -import io.javalin.community.routing.Route.HEAD -import io.javalin.community.routing.Route.POST -import io.javalin.community.routing.Route.PUT -import io.javalin.http.ContentType +import io.javalin.community.routing.Route.* import io.javalin.http.Context +import io.javalin.openapi.* import io.javalin.openapi.ContentType.FORM_DATA_MULTIPART -import io.javalin.openapi.HttpMethod -import io.javalin.openapi.OpenApi -import io.javalin.openapi.OpenApiContent -import io.javalin.openapi.OpenApiParam -import io.javalin.openapi.OpenApiResponse import panda.std.Result const val X_GENERATE_CHECKSUMS = "X-Generate-Checksums" internal class MavenEndpoints( mavenFacade: MavenFacade, - private val frontendFacade: FrontendFacade, + private val basePath: String, private val compressionStrategy: String ) : MavenRoutes(mavenFacade) { @@ -99,7 +88,7 @@ internal class MavenEndpoints( is DirectoryInfo -> ctx.html( createDirectoryIndexPage( - basePath = frontendFacade.formattedBasePath.get(), + basePath = basePath, uri = ctx.uri(), authenticatedFiles = mavenFacade.getAvailableFiles(request, details), ) @@ -109,7 +98,7 @@ internal class MavenEndpoints( } } .onError { - ctx.status(it.status).html(frontendFacade.createNotFoundPage(ctx.uri(), it.message)) + ctx.status(it.status).html("Reposilite - 404 Not Found") // .html(frontendFacade.createNotFoundPage(ctx.uri(), it.message)) mavenFacade.logger.debug("FIND | Could not find file due to $it") } } diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/redirect/RedirectPlugin.kt b/reposilite-backend/src/main/kotlin/com/reposilite/redirect/RedirectPlugin.kt deleted file mode 100644 index 92ac77515..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/redirect/RedirectPlugin.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.reposilite.redirect - -import com.reposilite.configuration.local.LocalConfiguration -import com.reposilite.frontend.FrontendFacade -import com.reposilite.maven.MavenFacade -import com.reposilite.maven.infrastructure.MavenEndpoints -import com.reposilite.plugin.api.Facade -import com.reposilite.plugin.api.Plugin -import com.reposilite.plugin.api.ReposilitePlugin -import com.reposilite.plugin.event -import com.reposilite.plugin.facade -import com.reposilite.storage.api.Location -import com.reposilite.web.api.ReposiliteRoute -import com.reposilite.web.api.RoutingSetupEvent -import io.javalin.community.routing.Route.GET -import io.javalin.community.routing.Route.HEAD - -@Plugin(name = "redirect", dependencies = ["local-configuration", "frontend", "maven"]) -class RedirectPlugin : ReposilitePlugin() { - - private val redirectTo: String? = System.getProperty("reposilite.redirect.default-repository", "") - - override fun initialize(): Facade? { - if (redirectTo.isNullOrEmpty()) { - return null - } - - val mavenFacade = facade() - - val mavenEndpoints = MavenEndpoints( - mavenFacade = mavenFacade, - frontendFacade = facade(), - compressionStrategy = facade().compressionStrategy.get() - ) - - logger.info("") - logger.info("--- Redirect") - - val redirectedRoutes = mavenFacade.getRepository(redirectTo) - ?.storageProvider - ?.getFiles(Location.of("/")) - ?.orNull() - ?.map { - logger.info("Redirecting /${it.getSimpleName()}/ to /$redirectTo/${it.getSimpleName()}/") - - ReposiliteRoute("/${it.getSimpleName()}/", HEAD, GET) { - accessed { - mavenEndpoints.findFile( - ctx = ctx, - identifier = this?.identifier, - repository = redirectTo, - gav = it.resolve(requireParameter("gav")) - ) - } - } - } - ?: emptyList() - - event { event: RoutingSetupEvent -> - event.register(redirectedRoutes) - } - - return null - } - -} \ No newline at end of file diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/statistics/StatsCommand.kt b/reposilite-backend/src/main/kotlin/com/reposilite/statistics/StatsCommand.kt deleted file mode 100644 index 6dd38fb1e..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/statistics/StatsCommand.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.reposilite.statistics - -import com.reposilite.console.CommandContext -import com.reposilite.console.CommandStatus.FAILED -import com.reposilite.console.api.ReposiliteCommand -import panda.std.Option.supplyThrowing -import panda.std.take -import panda.utilities.console.Effect.BLACK_BOLD -import panda.utilities.console.Effect.RESET -import picocli.CommandLine.Command -import picocli.CommandLine.Parameters - -private const val DEFAULT_TOP_LIMIT = 20 - -@Command(name = "stats", description = ["Display collected metrics"]) -internal class StatsCommand(private val statisticsFacade: StatisticsFacade) : ReposiliteCommand { - - @Parameters(index = "0", paramLabel = "[]", description = ["Repository to search in.", "By default it aggregates results from all repositories."], defaultValue = "") - private lateinit var repository: String - - @Parameters(index = "1", paramLabel = "[]", description = ["Accepts string as pattern and int as limiter"], defaultValue = "") - private lateinit var filter: String - - override fun execute(context: CommandContext) { - context.append("Statistics: ") - context.append(" Unique resolved requests: ${statisticsFacade.countUniqueRecords()}") - context.append(" All resolved requests: ${statisticsFacade.countRecords()}") - - val limiter = supplyThrowing(NumberFormatException::class.java) { filter.toInt() }.orElseGet(DEFAULT_TOP_LIMIT) - val phrase = take(limiter != DEFAULT_TOP_LIMIT, "", filter) - - statisticsFacade.findResolvedRequestsByPhrase(repository, phrase, limiter) - .peek { response -> - context.append("Search results:") - context.append(" Filter: '${highlight(phrase)}' / Limit: $limiter") - if (repository.isNotEmpty()) context.append(" In repository: $repository") - context.append(" Sum of matched requests: ${response.sum}") - context.append(" Records:") - response.requests.forEachIndexed { order, request -> context.append(" ${order + 1}. /${request.gav} (${request.count})") } - if (response.requests.isEmpty()) context.append(" ~ Matching records not found ~") - } - .onError { - context.append("Cannot fetch statistics: $it") - context.status = FAILED - } - } - - private fun highlight(value: Any): String = - BLACK_BOLD.toString() + value.toString() + RESET - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/statistics/application/StatisticsPlugin.kt b/reposilite-backend/src/main/kotlin/com/reposilite/statistics/application/StatisticsPlugin.kt index 0a7fb1b52..e536f31d6 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/statistics/application/StatisticsPlugin.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/statistics/application/StatisticsPlugin.kt @@ -17,7 +17,6 @@ package com.reposilite.statistics.application import com.reposilite.configuration.shared.SharedConfigurationFacade -import com.reposilite.console.ConsoleFacade import com.reposilite.plugin.api.Plugin import com.reposilite.plugin.api.ReposiliteInitializeEvent import com.reposilite.plugin.api.ReposilitePlugin @@ -26,12 +25,11 @@ import com.reposilite.plugin.facade import com.reposilite.plugin.parameters import com.reposilite.plugin.reposilite import com.reposilite.statistics.StatisticsFacade -import com.reposilite.statistics.StatsCommand import com.reposilite.statistics.infrastructure.StatisticsEndpoint import com.reposilite.web.api.RoutingSetupEvent import java.util.concurrent.TimeUnit.SECONDS -@Plugin(name = "statistics", dependencies = ["shared-configuration", "console"], settings = StatisticsSettings::class) +@Plugin(name = "statistics", dependencies = ["shared-configuration"], settings = StatisticsSettings::class) internal class StatisticsPlugin : ReposilitePlugin() { override fun initialize(): StatisticsFacade { @@ -44,9 +42,6 @@ internal class StatisticsPlugin : ReposilitePlugin() { statisticsSettings = settingsFacade.getDomainSettings() ).statisticsFacade() - val consoleFacade = facade() - consoleFacade.registerCommand(StatsCommand(statisticsFacade)) - event { _: ReposiliteInitializeEvent -> reposilite().scheduler.scheduleWithFixedDelay({ if (statisticsFacade.statisticsEnabled().get()) { diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/status/FailuresCommand.kt b/reposilite-backend/src/main/kotlin/com/reposilite/status/FailuresCommand.kt deleted file mode 100644 index b6c89ee73..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/status/FailuresCommand.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.reposilite.status - -import com.reposilite.console.CommandContext -import com.reposilite.console.api.ReposiliteCommand -import picocli.CommandLine.Command - -@Command(name = "failures", description = ["Display all recorded exceptions"]) -internal class FailuresCommand(private val failureFacade: FailureFacade) : ReposiliteCommand { - - override fun execute(context: CommandContext) { - if (!failureFacade.hasFailures()) { - context.append("No exception has occurred yet") - return - } - - context.append("") - context.append("List of cached failures: " + "(" + failureFacade.getFailures().size + ")") - context.append("") - - failureFacade.getFailures() - .map { it.split(System.lineSeparator()) } - .forEach { context.appendAll(it) } - } - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/status/StatusCommand.kt b/reposilite-backend/src/main/kotlin/com/reposilite/status/StatusCommand.kt deleted file mode 100644 index d2358bdd4..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/status/StatusCommand.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.status - -import com.reposilite.VERSION -import com.reposilite.console.CommandContext -import com.reposilite.console.api.ReposiliteCommand -import com.reposilite.shared.extensions.TimeUtils -import panda.utilities.console.Effect.GREEN -import panda.utilities.console.Effect.GREEN_BOLD -import panda.utilities.console.Effect.RED_UNDERLINED -import panda.utilities.console.Effect.RESET -import picocli.CommandLine.Command - -@Command(name = "status", description = ["Display summary status of app health"]) -internal class StatusCommand(private val statusFacade: StatusFacade) : ReposiliteCommand { - - override fun execute(context: CommandContext) { - statusFacade.fetchInstanceStatus().apply { - context.append("Reposilite $VERSION Status") - context.append(" Active: $GREEN_BOLD${statusFacade.isAlive()}$RESET") - context.append(" Uptime: ${TimeUtils.getPrettyUptime(statusFacade.getUptime())}") - context.append(" Memory usage of process: ${TimeUtils.format(usedMemory)}M") - context.append(" Active threads in group: $usedThreads") - context.append(" Recorded failures: $failuresCount") - } - - statusFacade.getLatestVersion() - .fold( - { "${if (VERSION == it) GREEN else RED_UNDERLINED}$it$RESET" }, - { "$RED_UNDERLINED$it${RESET}" } - ) - .let { coloredStatus -> context.append(" Latest version of Reposilite: $coloredStatus") } - } - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/status/application/StatusPlugin.kt b/reposilite-backend/src/main/kotlin/com/reposilite/status/application/StatusPlugin.kt index 6038ffdfb..c07ecefbd 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/status/application/StatusPlugin.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/status/application/StatusPlugin.kt @@ -18,7 +18,6 @@ package com.reposilite.status.application import com.reposilite.VERSION import com.reposilite.configuration.local.LocalConfiguration -import com.reposilite.console.ConsoleFacade import com.reposilite.plugin.api.Plugin import com.reposilite.plugin.api.ReposiliteDisposeEvent import com.reposilite.plugin.api.ReposiliteInitializeEvent @@ -30,8 +29,6 @@ import com.reposilite.plugin.parameters import com.reposilite.plugin.reposilite import com.reposilite.shared.extensions.TimeUtils import com.reposilite.status.FailureFacade -import com.reposilite.status.FailuresCommand -import com.reposilite.status.StatusCommand import com.reposilite.status.StatusFacade import com.reposilite.status.StatusSnapshotScheduler import com.reposilite.status.infrastructure.StatusEndpoints @@ -45,7 +42,7 @@ import panda.std.reactive.Reference.Dependencies.dependencies import panda.std.reactive.Reference.computed import panda.utilities.console.Effect -@Plugin(name = "status", dependencies = ["console", "failure", "local-configuration"]) +@Plugin(name = "status", dependencies = ["failure", "local-configuration"]) internal class StatusPlugin : ReposilitePlugin() { private val remoteVersionEndpoint = "https://maven.reposilite.com/api/maven/latest/version/releases/com/reposilite/reposilite?type=raw" @@ -54,7 +51,6 @@ internal class StatusPlugin : ReposilitePlugin() { val webServer = Completable() val failureFacade = facade() val localConfiguration = facade() - val consoleFacade = facade() val statusFacade = StatusComponents( testEnv = parameters().testEnv, @@ -77,8 +73,6 @@ internal class StatusPlugin : ReposilitePlugin() { event { _: ReposiliteInitializeEvent -> webServer.complete(reposilite().webServer) - consoleFacade.registerCommand(FailuresCommand(failureFacade)) - consoleFacade.registerCommand(StatusCommand(statusFacade)) } event { event: RoutingSetupEvent -> diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/token/ExportService.kt b/reposilite-backend/src/main/kotlin/com/reposilite/token/ExportService.kt index c970d67f1..d0cc158db 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/token/ExportService.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/token/ExportService.kt @@ -18,19 +18,13 @@ package com.reposilite.token import com.fasterxml.jackson.module.kotlin.readValue import com.reposilite.ReposiliteObjectMapper.DEFAULT_OBJECT_MAPPER -import com.reposilite.console.CommandContext -import com.reposilite.console.CommandStatus.FAILED -import com.reposilite.console.api.ReposiliteCommand import com.reposilite.token.api.AccessTokenDetails import panda.std.Result import panda.std.Result.supplyThrowing -import picocli.CommandLine.Command -import picocli.CommandLine.Parameters import java.nio.file.Files import java.nio.file.Path import java.nio.file.StandardOpenOption.CREATE import java.nio.file.StandardOpenOption.TRUNCATE_EXISTING -import kotlin.io.path.absolute import kotlin.io.path.readText class ExportService { @@ -41,43 +35,4 @@ class ExportService { fun importFromFile(fromFile: Path): Result, Exception> = supplyThrowing { DEFAULT_OBJECT_MAPPER.readValue>(fromFile.readText()) } -} - -@Command(name = "token-export", description = ["Export access tokens to file"]) -internal class ExportTokensCommand(val workingDirectory: Path, val accessTokenFacade: AccessTokenFacade) : ReposiliteCommand { - - @Parameters(index = "0", paramLabel = "", description = ["Path to destination JSON file"]) - lateinit var name: String - - override fun execute(context: CommandContext) { - workingDirectory.resolve(name) - .let { accessTokenFacade.exportToFile(it) } - .also { - context.append("${accessTokenFacade.count()} token(s) found.") - context.append("All tokens have been exported to ${it.absolute()} in JSON format.") - } - } - -} - -@Command(name = "token-import", description = ["Import access tokens from file"]) -internal class ImportTokensCommand(val workingDirectory: Path, val accessTokenFacade: AccessTokenFacade) : ReposiliteCommand { - - @Parameters(index = "0", paramLabel = "", description = ["Path to JSON file with access tokens"]) - lateinit var name: String - - override fun execute(context: CommandContext) { - workingDirectory.resolve(name) - .let { accessTokenFacade.importFromFile(it) } - .onError { - context.status = FAILED - context.append("Cannot read JSON file due to: $it") - it.printStackTrace() - } - .orNull() - ?.also { context.append("Importing ${it.size} token(s) from ${workingDirectory.resolve(name).absolute()} file:") } - ?.map { accessTokenFacade.addAccessToken(it) } - ?.forEach { context.append("Access token '${it.name}' has been imported.") } - } - -} +} \ No newline at end of file diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/token/application/AccessTokenPlugin.kt b/reposilite-backend/src/main/kotlin/com/reposilite/token/application/AccessTokenPlugin.kt index 87c24f788..7e40b3b20 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/token/application/AccessTokenPlugin.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/token/application/AccessTokenPlugin.kt @@ -16,7 +16,6 @@ package com.reposilite.token.application -import com.reposilite.console.api.CommandsSetupEvent import com.reposilite.plugin.api.Plugin import com.reposilite.plugin.api.ReposiliteInitializeEvent import com.reposilite.plugin.api.ReposilitePlugin @@ -25,17 +24,7 @@ import com.reposilite.plugin.parameters import com.reposilite.plugin.reposilite import com.reposilite.token.AccessTokenFacade import com.reposilite.token.AccessTokenPermission.MANAGER -import com.reposilite.token.ExportTokensCommand -import com.reposilite.token.ImportTokensCommand -import com.reposilite.token.infrastructure.RouteAdd -import com.reposilite.token.infrastructure.RouteRemove import com.reposilite.token.infrastructure.AccessTokenApiEndpoints -import com.reposilite.token.infrastructure.ChModCommand -import com.reposilite.token.infrastructure.ChNameCommand -import com.reposilite.token.infrastructure.KeygenCommand -import com.reposilite.token.infrastructure.RegenerateCommand -import com.reposilite.token.infrastructure.RevokeCommand -import com.reposilite.token.infrastructure.TokensCommand import com.reposilite.web.api.RoutingSetupEvent @Plugin(name = "access-token") @@ -57,22 +46,6 @@ internal class AccessTokenPlugin : ReposilitePlugin() { accessTokenFacade.addPermission(token.identifier, MANAGER) } - event { event: CommandsSetupEvent -> - event.registerCommand(TokensCommand(accessTokenFacade)) - event.registerCommand(KeygenCommand(accessTokenFacade)) - event.registerCommand(ChNameCommand(accessTokenFacade)) - event.registerCommand(ChModCommand(accessTokenFacade)) - event.registerCommand(RevokeCommand(accessTokenFacade)) - event.registerCommand(RegenerateCommand(accessTokenFacade)) - - event.registerCommand(RouteAdd(accessTokenFacade)) - event.registerCommand(RouteRemove(accessTokenFacade)) - - val workingDirectory = parameters().workingDirectory - event.registerCommand(ExportTokensCommand(workingDirectory, accessTokenFacade)) - event.registerCommand(ImportTokensCommand(workingDirectory, accessTokenFacade)) - } - event { event: RoutingSetupEvent -> event.registerRoutes(AccessTokenApiEndpoints(accessTokenFacade)) } diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/token/infrastructure/AccessTokenCommands.kt b/reposilite-backend/src/main/kotlin/com/reposilite/token/infrastructure/AccessTokenCommands.kt deleted file mode 100644 index 98727f1aa..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/token/infrastructure/AccessTokenCommands.kt +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.token.infrastructure - -import com.reposilite.console.CommandContext -import com.reposilite.console.CommandStatus.FAILED -import com.reposilite.console.api.ReposiliteCommand -import com.reposilite.token.AccessTokenFacade -import com.reposilite.token.AccessTokenPermission -import com.reposilite.token.AccessTokenType.PERSISTENT -import com.reposilite.token.api.CreateAccessTokenRequest -import picocli.CommandLine.Command -import picocli.CommandLine.Option -import picocli.CommandLine.Parameters - -@Command(name = "tokens", description = ["List all generated tokens"]) -internal class TokensCommand(private val accessTokenFacade: AccessTokenFacade) : ReposiliteCommand { - - override fun execute(context: CommandContext) { - context.append("Tokens (${accessTokenFacade.count()})") - - accessTokenFacade.getAccessTokens().forEach { token -> - context.append("- ${token.name}: ${accessTokenFacade.getPermissions(token.identifier)}") - val routes = accessTokenFacade.getRoutes(token.identifier) - - routes.groupBy { it.path } - .forEach { (route, permissions) -> - context.append(" > $route : ${permissions.map { it.permission } }") - } - - if (routes.isEmpty()) { - context.append(" > ~ no routes ~") - } - } - } - -} - -@Command(name = "token-generate", description = ["Generate a new access token"]) -internal class KeygenCommand(private val accessTokenFacade: AccessTokenFacade) : ReposiliteCommand { - - @Option(names = ["--secret", "-s"], description = ["Override generated token with custom secret"], required = false) - var secret: String? = null - - @Parameters(index = "0", paramLabel = "", description = ["Access token name"]) - private lateinit var name: String - - @Parameters(index = "1", paramLabel = "[]", defaultValue = "", description = [ - "Access token permissions, e.g. m, optional. Available permissions", - "m - marks token as management token and grants access to all features and paths by default (access_token:manager)" - ]) - private lateinit var permissions: String - - override fun execute(context: CommandContext) { - val mappedPermissions = mapPermissions(context, permissions) ?: return - - if (name.contains(":")) { - context.status = FAILED - context.append("Token name cannot contain ':' character") - return - } - - val response = accessTokenFacade.createAccessToken( - CreateAccessTokenRequest( - type = PERSISTENT, - name = name, - secret = secret - ) - ) - - mappedPermissions.forEach { - accessTokenFacade.addPermission(response.accessToken.identifier, it) - } - - context.append("Generated new access token for $name with '$permissions' permissions. Secret:") - context.append(response.secret) - } - -} - -@Command(name = "token-modify", description = ["Change token permissions"]) -internal class ChModCommand(private val accessTokenFacade: AccessTokenFacade) : ReposiliteCommand { - - @Parameters(index = "0", paramLabel = "", description = ["Name of token to update"]) - private lateinit var name: String - - @Parameters(index = "1", paramLabel = "", description = ["New permissions"]) - private lateinit var permissions: String - - override fun execute(context: CommandContext) { - val mappedPermissions = mapPermissions(context, permissions) ?: return - - accessTokenFacade.getAccessToken(name) - ?.let { token -> - AccessTokenPermission.entries.forEach { accessTokenFacade.deletePermission(token.identifier, it) } - mappedPermissions.forEach { accessTokenFacade.addPermission(token.identifier, it) } - context.append("Permissions have been changed from to '$permissions'") - } - ?: run { - context.status = FAILED - context.append("Token '$name' not found") - } - } - -} - -private fun mapPermissions(context: CommandContext, permissions: String): Set? { - val mappedPermissions = permissions.toCharArray() - .map { AccessTokenPermission.findAccessTokenPermissionByShortcut(it.toString()) } - .takeIf { it.none { element -> element == null } } - ?.filterNotNull() - ?.toSet() - - if (mappedPermissions == null) { - context.status = FAILED - context.append("Unknown permissions '$permissions'. Type 'help token-generate' to display supported permissions") - return null - } - - return mappedPermissions -} - -@Command(name = "token-rename", description = ["Change token name"]) -internal class ChNameCommand(private val accessTokenFacade: AccessTokenFacade) : ReposiliteCommand { - - @Parameters(index = "0", paramLabel = "", description = ["Name of token to update"]) - private lateinit var name: String - - @Parameters(index = "1", paramLabel = "", description = ["New token name"]) - private lateinit var updatedName: String - - override fun execute(context: CommandContext) { - accessTokenFacade.getAccessToken(name) - ?.let { - accessTokenFacade.updateToken(it.copy(name = updatedName)) - context.append("Token name has been changed from '$name' to '$updatedName'") - } - ?: run { - context.status = FAILED - context.append("Token '$name' not found") - } - } - -} - -@Command(name = "token-revoke", description = ["Revoke token"]) -internal class RevokeCommand(private val accessTokenFacade: AccessTokenFacade) : ReposiliteCommand { - - @Parameters(index = "0", paramLabel = "", description = ["Name of token to revoke"]) - private lateinit var name: String - - override fun execute(context: CommandContext) { - accessTokenFacade.getAccessToken(name)?.also { accessTokenFacade.deleteToken(it.identifier) } - context.append("Token for '$name' has been revoked") - } - -} - -@Command(name = "token-regenerate", description = ["Regenerate token secret"]) -internal class RegenerateCommand(private val accessTokenFacade: AccessTokenFacade) : ReposiliteCommand { - - @Parameters(index = "0", paramLabel = "", description = ["Name of token to revoke"]) - private lateinit var name: String - - @Option(names = ["--secret", "-s"], description = ["Override generated token with custom secret"], required = false) - var secret: String? = null - - override fun execute(context: CommandContext) { - accessTokenFacade.getAccessToken(name) - ?.also { token -> - accessTokenFacade.regenerateAccessToken(token, secret) - .peek { context.append("New secret for '$name': $it") } - .onError { - context.status = FAILED - context.append("Token '$name' not found") - } - } - ?: run { - context.status = FAILED - context.append("Token '$name' not found") - } - } - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/token/infrastructure/RouteCommands.kt b/reposilite-backend/src/main/kotlin/com/reposilite/token/infrastructure/RouteCommands.kt deleted file mode 100644 index 09a8c9b96..000000000 --- a/reposilite-backend/src/main/kotlin/com/reposilite/token/infrastructure/RouteCommands.kt +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.reposilite.token.infrastructure - -import com.reposilite.console.CommandContext -import com.reposilite.console.CommandStatus.FAILED -import com.reposilite.console.api.ReposiliteCommand -import com.reposilite.token.AccessTokenFacade -import com.reposilite.token.Route -import com.reposilite.token.RoutePermission -import picocli.CommandLine.Command -import picocli.CommandLine.Parameters - -@Command(name = "route-add", description = ["Add new route to access token"]) -internal class RouteAdd(private val accessTokenFacade: AccessTokenFacade) : ReposiliteCommand { - - @Parameters(index = "0", paramLabel = "", description = ["Name of access token to modify"]) - private lateinit var name: String - - @Parameters(index = "1", paramLabel = "", description = ["Path to the route, e.g. /releases/com/reposilite"]) - private lateinit var route: String - - @Parameters(index = "2", paramLabel = "", description = [ - "Route permissions, e.g. rw. Available permissions:", - "r - allows token to read resources under the associated path (route:read)", - "w - allows token to write (deploy) resources under the associated path (route:write)" - ]) - private lateinit var permissions: String - - override fun execute(context: CommandContext) { - accessTokenFacade.getAccessToken(name) - ?.also { token -> - val routes = accessTokenFacade.getRoutes(token.identifier) - - if (routes.any { entry -> entry.path == route }) { - context.status = FAILED - context.append("Token $name already has route with path $route") - return - } - - val mappedPermissions = mapPermissions() ?: let { - context.status = FAILED - context.append("Unknown permission shortcuts (${permissions.toCharArray().joinToString()})") - context.append("Available options (${RoutePermission.entries.joinToString { perm -> perm.shortcut }})") - return - } - - if (!route.startsWith("/")) { - route = "/$route" - context.append("Provided route has been prefixed with /") - } - - mappedPermissions.forEach { accessTokenFacade.addRoute(token.identifier, Route(route, it)) } - context.append("Route $route has been added to token ${token.name}") - } - ?: run { - context.status = FAILED - context.append("Token $name not found") - } - } - - private fun mapPermissions(): Set? = - permissions.toCharArray() - .map { RoutePermission.findRoutePermissionByShortcut(it.toString()).orNull() } - .filterNotNull() - .toSet() - .takeIf { it.isNotEmpty() } - -} - -@Command(name = "route-remove", description = ["Remove route from access token"]) -internal class RouteRemove(private val accessTokenFacade: AccessTokenFacade) : ReposiliteCommand { - - @Parameters(index = "0", paramLabel = "", description = ["Name of access token to modify"]) - private lateinit var name: String - - @Parameters(index = "1", paramLabel = "", description = ["Path of route to remove"]) - private lateinit var path: String - - override fun execute(context: CommandContext) { - accessTokenFacade.getAccessToken(name) - ?.also { token -> - RoutePermission.entries.forEach { accessTokenFacade.deleteRoute(token.identifier, Route(path, it)) } - context.append("Routes of token $name has been updated") - } - ?: run { - context.status = FAILED - context.append("Token $name not found") - } - } - -} diff --git a/reposilite-backend/src/main/kotlin/com/reposilite/web/application/JavalinConfiguration.kt b/reposilite-backend/src/main/kotlin/com/reposilite/web/application/JavalinConfiguration.kt index 337212713..a4b0e3774 100644 --- a/reposilite-backend/src/main/kotlin/com/reposilite/web/application/JavalinConfiguration.kt +++ b/reposilite-backend/src/main/kotlin/com/reposilite/web/application/JavalinConfiguration.kt @@ -22,7 +22,6 @@ import com.reposilite.ReposiliteObjectMapper import com.reposilite.VERSION import com.reposilite.configuration.local.LocalConfiguration import com.reposilite.configuration.shared.SharedConfigurationFacade -import com.reposilite.frontend.application.FrontendSettings import com.reposilite.journalist.Journalist import com.reposilite.web.api.HttpServerConfigurationEvent import com.reposilite.web.api.HttpServerStartedEvent @@ -30,11 +29,9 @@ import com.reposilite.web.api.RoutingSetupEvent import com.reposilite.web.infrastructure.ApiCacheBypassHandler import com.reposilite.web.infrastructure.EndpointAccessLoggingHandler import com.reposilite.web.infrastructure.createReposiliteDsl -import io.javalin.community.ssl.SslPlugin import io.javalin.config.JavalinConfig import io.javalin.json.JavalinJackson import io.javalin.openapi.plugin.OpenApiPlugin -import io.javalin.plugin.bundled.SslRedirectPlugin import kotlin.time.Duration.Companion.minutes import org.eclipse.jetty.server.Server import org.eclipse.jetty.server.ServerConnector @@ -51,7 +48,6 @@ internal object JavalinConfiguration { val localConfiguration = reposilite.extensions.facade() val sharedConfigurationFacade = reposilite.extensions.facade() val webSettings = sharedConfigurationFacade.getDomainSettings() - val frontendSettings = sharedConfigurationFacade.getDomainSettings() reposilite.extensions.registerEvent { _: HttpServerStartedEvent -> server.connectors.filterIsInstance().forEach { it.idleTimeout = localConfiguration.idleTimeout.get() } @@ -67,9 +63,8 @@ internal object JavalinConfiguration { configureJavalin(config, localConfiguration, webSettings) configureJsonSerialization(config) - configureSSL(reposilite, localConfiguration, config) configureCors(config) - configureOpenApi(config, frontendSettings.get()) + configureOpenApi(config, "Title", "Description") configureDebug(reposilite, localConfiguration, config) configureRoutingPlugin(config, reposilite) } @@ -122,47 +117,6 @@ internal object JavalinConfiguration { config.jsonMapper(JavalinJackson(objectMapper)) } - private fun configureSSL(reposilite: Reposilite, localConfiguration: LocalConfiguration, config: JavalinConfig) { - if (localConfiguration.sslEnabled.get()) { - reposilite.logger.info("Enabling SSL connector at ::${localConfiguration.sslPort.get()}") - - config.registerPlugin(SslPlugin { - it.insecure = true - it.insecurePort = localConfiguration.port.get() - - it.secure = true - it.securePort = localConfiguration.sslPort.get() - - val keyConfiguration = localConfiguration.keyPath.map { path -> - path.replace( - "\${WORKING_DIRECTORY}", - reposilite.parameters.workingDirectory.toAbsolutePath().toString() - ) - } - val keyPassword = localConfiguration.keyPassword.get() - - when { - keyConfiguration.endsWith(".pem") -> { - val (certPath, keyPath) = keyConfiguration.split(" ") - it.pemFromPath(certPath, keyPath, keyPassword) - } - keyConfiguration.endsWith(".jks") -> it.keystoreFromPath(keyConfiguration, keyPassword) - else -> throw IllegalArgumentException("Provided key extension is not supported.") - } - - it.configConnectors { connector -> connector.idleTimeout = localConfiguration.idleTimeout.get() } - it.sniHostCheck = false - }) - } - - if (localConfiguration.enforceSsl.get()) { - config.registerPlugin(SslRedirectPlugin { - it.redirectOnLocalhost = true - it.sslPort = localConfiguration.sslPort.get() - }) - } - } - private fun configureCors(config: JavalinConfig) { config.bundledPlugins.enableCors { cors -> cors.addRule { @@ -171,12 +125,12 @@ internal object JavalinConfiguration { } } - private fun configureOpenApi(config: JavalinConfig, frontendSettings: FrontendSettings) { + private fun configureOpenApi(config: JavalinConfig, title: String, description: String) { config.registerPlugin(OpenApiPlugin { openapi -> openapi.withDefinitionConfiguration { _, configuration -> configuration.withInfo { - it.title = frontendSettings.title - it.description = frontendSettings.description + it.title = title + it.description = description it.version = VERSION } } diff --git a/reposilite-backend/src/main/resources/META-INF/services/com.reposilite.plugin.api.ReposilitePlugin b/reposilite-backend/src/main/resources/META-INF/services/com.reposilite.plugin.api.ReposilitePlugin index 29a5b1e46..43ec7eb01 100644 --- a/reposilite-backend/src/main/resources/META-INF/services/com.reposilite.plugin.api.ReposilitePlugin +++ b/reposilite-backend/src/main/resources/META-INF/services/com.reposilite.plugin.api.ReposilitePlugin @@ -1,8 +1,6 @@ com.reposilite.auth.application.AuthenticationPlugin com.reposilite.console.application.ConsolePlugin -com.reposilite.frontend.application.FrontendPlugin com.reposilite.maven.application.MavenPlugin -com.reposilite.redirect.RedirectPlugin com.reposilite.javadocs.application.JavadocPlugin com.reposilite.configuration.application.ConfigurationPlugin com.reposilite.configuration.local.LocalConfigurationPlugin diff --git a/reposilite-backend/src/test/kotlin/com/reposilite/frontend/LazyPlaceholderResolverTest.kt b/reposilite-backend/src/test/kotlin/com/reposilite/frontend/LazyPlaceholderResolverTest.kt deleted file mode 100644 index 3d446de21..000000000 --- a/reposilite-backend/src/test/kotlin/com/reposilite/frontend/LazyPlaceholderResolverTest.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.reposilite.frontend - -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows -import java.io.ByteArrayOutputStream - -class LazyPlaceholderResolverTest { - - private val bufferSize = 8192 - private val placeholder = "{{PLACEHOLDER}}" - private val defaultResolver = LazyPlaceholderResolver(mapOf(placeholder to "Reposilite")) - - @Test - fun `should support only 1-byte long symbols in placeholders`() { - assertThrows { - LazyPlaceholderResolver(mapOf("🎃" to "Reposilite")) - } - } - - @Test - fun `should resolve placeholder`() { - val input = placeholder.byteInputStream() - val output = ByteArrayOutputStream() - - defaultResolver.process(input, output) - val result = output.toByteArray().decodeToString() - - assertThat(result).contains("Reposilite") - } - - @Test - fun `should resolve full length placeholder`() { - val placeholderBytes = placeholder.toByteArray() - val input = (ByteArray(bufferSize - placeholderBytes.size + 1) + placeholderBytes + ByteArray(bufferSize - 1)).inputStream() - val output = ByteArrayOutputStream() - - defaultResolver.process(input, output) - val result = output.toByteArray().decodeToString() - - assertThat(result).contains("Reposilite") - } - - @Test - fun `should resolve one byte length placeholder`() { - val placeholderBytes = placeholder.toByteArray() - val input = (ByteArray(bufferSize - 1) + placeholderBytes + ByteArray(bufferSize - 1)).inputStream() - val output = ByteArrayOutputStream() - - defaultResolver.process(input, output) - val result = output.toByteArray().decodeToString() - - assertThat(result).contains("Reposilite") - } - -} \ No newline at end of file diff --git a/reposilite-backend/src/test/kotlin/com/reposilite/maven/specification/MavenSpecification.kt b/reposilite-backend/src/test/kotlin/com/reposilite/maven/specification/MavenSpecification.kt index 64d4439aa..d9aa66c83 100644 --- a/reposilite-backend/src/test/kotlin/com/reposilite/maven/specification/MavenSpecification.kt +++ b/reposilite-backend/src/test/kotlin/com/reposilite/maven/specification/MavenSpecification.kt @@ -18,7 +18,6 @@ package com.reposilite.maven.specification import com.reposilite.auth.application.AuthenticationComponents import com.reposilite.auth.application.AuthenticationSettings -import com.reposilite.frontend.application.FrontendSettings import com.reposilite.journalist.backend.InMemoryLogger import com.reposilite.maven.MavenFacade import com.reposilite.maven.Repository @@ -137,7 +136,7 @@ internal abstract class MavenSpecification { mavenSettings = reference(MavenSettings( repositories = repositories() )), - frontendSettings = reference(FrontendSettings()) + id = reference("test-repository-id") ).mavenFacade() } diff --git a/reposilite-backend/src/test/kotlin/com/reposilite/token/ExportAndImportTest.kt b/reposilite-backend/src/test/kotlin/com/reposilite/token/ExportAndImportTest.kt deleted file mode 100644 index fe2cc6b13..000000000 --- a/reposilite-backend/src/test/kotlin/com/reposilite/token/ExportAndImportTest.kt +++ /dev/null @@ -1,58 +0,0 @@ -package com.reposilite.token - -import com.reposilite.console.CommandContext -import com.reposilite.console.CommandStatus.SUCCEEDED -import com.reposilite.token.AccessTokenPermission.MANAGER -import com.reposilite.token.RoutePermission.READ -import com.reposilite.token.specification.AccessTokenSpecification -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import java.nio.file.Files - -internal class ExportAndImportTest : AccessTokenSpecification() { - - @Test - fun `should export and import tokens`() { - // given: a facade with 3 tokens - val tokens = List(3) { createToken("token-$it", "secret-$it") } - .forEach { - accessTokenFacade.addPermission(it.identifier, MANAGER) - accessTokenFacade.addRoute(it.identifier, Route("/test", READ)) - } - .let { accessTokenFacade.getAccessTokens() } - .map { accessTokenFacade.getAccessTokenDetailsById(it.identifier)!! } - - val fileName = "test.json" - val context = CommandContext() - - // when: tokens are exported to file - val exportCommand = ExportTokensCommand(workingDirectory(), accessTokenFacade).also { it.name = fileName } - exportCommand.execute(context) - - // then: tokens were successfully exported - assertThat(context.status).isEqualTo(SUCCEEDED) - assertThat(Files.exists(workingDirectory.toPath().resolve(fileName))).isTrue - - // given: a facade without tokens - deleteAllTokens() - - // when: exported tokens are imported from the given file - val importCommand = ImportTokensCommand(workingDirectory(), accessTokenFacade).also { it.name = fileName } - importCommand.execute(context) - - // then: the imported tokens match the old ones - assertThat(context.status).isEqualTo(SUCCEEDED) - - tokens.forEach { - val token = accessTokenFacade.getAccessTokenDetailsById(accessTokenFacade.getAccessToken(it.accessToken.name)!!.identifier)!! - assertThat(token.accessToken.copy(identifier = it.accessToken.identifier)).isEqualTo(it.accessToken) - assertThat(token.permissions).isEqualTo(it.permissions) - assertThat(token.routes).isEqualTo(it.routes) - } - - for (message in context.output()) { - println(message) - } - } - -} diff --git a/reposilite-frontend/.gitignore b/reposilite-frontend/.gitignore deleted file mode 100644 index 7bafca9f9..000000000 --- a/reposilite-frontend/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -node_modules -.DS_Store -dist -dist-ssr -*.local -.vsc -stats.html \ No newline at end of file diff --git a/reposilite-frontend/.vscode/extensions.json b/reposilite-frontend/.vscode/extensions.json deleted file mode 100644 index 86c616f02..000000000 --- a/reposilite-frontend/.vscode/extensions.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "recommendations": ["octref.vetur"] -} diff --git a/reposilite-frontend/.vscode/settings.json b/reposilite-frontend/.vscode/settings.json deleted file mode 100644 index 953fe9739..000000000 --- a/reposilite-frontend/.vscode/settings.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "editor.quickSuggestions": { - "strings": true - }, - "css.validate": false, - "css.lint.unknownProperties": "ignore", - "cSpell.words": [ - "Consolas", - "downloadjs", - "monospace", - "mosha", - "rcompare", - "signin", - "signout", - "toastify", - "vueform", - "vueuse", - "windicss" - ], - "vetur.validation.script": false // https://github.com/vuejs/vetur/issues/2296 -} diff --git a/reposilite-frontend/README.md b/reposilite-frontend/README.md deleted file mode 100644 index 90d6eeb11..000000000 --- a/reposilite-frontend/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Reposilite Frontend -Uses [Vue 3](https://v3.vuejs.org/) with [WindiCSS](https://windicss.org/) - -### Running - -``` -# Install dependencies -$ npm install - -# Run only frontend -$ npm run start - -# Run only frontend with fake api (does not require backend) -$ npm run full -``` diff --git a/reposilite-frontend/build.gradle.kts b/reposilite-frontend/build.gradle.kts deleted file mode 100644 index 5c1679597..000000000 --- a/reposilite-frontend/build.gradle.kts +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.github.gradle.node.npm.task.NpmTask - -plugins { - id("com.github.node-gradle.node") version "3.2.1" -} - -node { - version.set("18.16.1") - download.set(true) -} - -//val lintTask = tasks.register("lintFrontend") { -// command.set("eslint") -// args.set(listOf("src/**")) -// args.set(listOf("run", "eslint")) -// dependsOn(tasks.npmInstall) -// inputs.dir("src") -// inputs.dir("node_modules") -// inputs.files("vite.config.js", "windi.config.js", "index.html", "eslint.config.js") -// outputs.upToDateWhen { true } -//} - -val buildTask = tasks.register("buildFrontend") { -// command.set("vite") -// args.set(listOf("build")) - args.set(listOf("run", "build")) -// dependsOn(tasks.npmInstall, lintTask) - dependsOn(tasks.npmInstall) - inputs.dir(project.fileTree("src")) - inputs.dir("node_modules") - inputs.files("vite.config.js", "windi.config.js", "index.html") - outputs.dir("${project.layout.buildDirectory.get()}/frontend") -} - -sourceSets { - java { - main { - resources { - srcDir(buildTask) - } - } - } -} diff --git a/reposilite-frontend/eslint.config.js b/reposilite-frontend/eslint.config.js deleted file mode 100644 index b20531594..000000000 --- a/reposilite-frontend/eslint.config.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import js from "@eslint/js"; -import pluginVue from 'eslint-plugin-vue' - -export default [ - js.configs.recommended, - ...pluginVue.configs['flat/recommended'], - { - languageOptions: { - parserOptions: { - "ecmaVersion": 2020, - "ecmaFeatures": { - "jsx": true - } - }, - }, - rules: { - 'vue/script-setup-uses-vars': 'error', - 'vue/no-setup-props-destructure': 'error', - 'vue/no-unused-vars': 'error', - 'vue/multi-word-component-names': 'error', - 'vue/jsx-uses-vars': 'error', - 'semi': ['error', 'never'], - } - } -] diff --git a/reposilite-frontend/fake-api/extensions.cjs b/reposilite-frontend/fake-api/extensions.cjs deleted file mode 100644 index 08e2d067e..000000000 --- a/reposilite-frontend/fake-api/extensions.cjs +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -const respond = (response) => - (_, res) => res.send(response) - -const basicAuth = (req) => { - const b64auth = (req.get('Authorization') || '').split(' ')[1] || '' - return Buffer.from(b64auth, 'base64').toString().split(':') -} - -const authorized = (req, success, failure) => { - const [login, password] = basicAuth(req) - - if (login === 'name' && password === 'secret') { - console.log('Authorization successful for request ' + req.url) - success() - } else failure && failure() -} - -const invalidCredentials = (res) => - res.status(401).send({message:'Invalid credentials'}) - -const sendMessage = (connection, message) => - connection.send(`${new Date().toDateString()} ${message}`) - -const createFileDetails = (name, contentType, contentLength) => - ({ type: 'FILE', name, contentType, contentLength }) - -const createDirectoryDetails = (name, files) => - ({ type: 'DIRECTORY', name, files }) - -const generateDayWiseTimeSeries = (baseval, count, yrange) => { - let i = 0 - const series = [] - while (i < count) { - series.push({ - date: baseval, - count: Math.floor(Math.random() * (yrange.max - yrange.min + 1)) + yrange.min - }) - baseval += 86400000 - i++ - } - return series -} - -module.exports = { - respond, - basicAuth, - authorized, - invalidCredentials, - sendMessage, - createFileDetails, - createDirectoryDetails, - generateDayWiseTimeSeries -} diff --git a/reposilite-frontend/fake-api/fake-reposilite-backend.js b/reposilite-frontend/fake-api/fake-reposilite-backend.js deleted file mode 100644 index dc646287e..000000000 --- a/reposilite-frontend/fake-api/fake-reposilite-backend.js +++ /dev/null @@ -1,348 +0,0 @@ -/* eslint-disable no-unused-vars */ - -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createRequire } from "module" -const require = createRequire(import.meta.url) - -const express = require("express") -const expressWs = require("express-ws") -const bodyParser = require('body-parser') -const crypto = require("crypto") - -const { - respond, - authorized, - invalidCredentials, - sendMessage, - createFileDetails, - createDirectoryDetails, - generateDayWiseTimeSeries -} = require("./extensions.cjs") - -const application = express() -expressWs(application) - -let uploadedFiles = [] -let mavenSettingsSchema = require('./maven-settings-schema.json') -let mavenSettingsEntity = require('./maven-settings-entity.json') - -let uptime = 1000 -let memory = 20 -let threads = 10 -let failures = 0 - -setInterval(() => { - memory += Math.random() * 10 - threads += 1 - uptime += 5000 - failures += 1 -}, 5000) - -const statisticsSeries = [ - { - name: 'Releases', - data: generateDayWiseTimeSeries(new Date('11 Feb 2022 GMT').getTime(), 20, { - min: 10, - max: 60 - }) - }, - { - name: 'Snapshots', - data: generateDayWiseTimeSeries(new Date('11 Feb 2022 GMT').getTime(), 20, { - min: 10, - max: 20 - }) - }, - { - name: 'Maven Central', - data: generateDayWiseTimeSeries(new Date('11 Feb 2022 GMT').getTime(), 20, { - min: 10, - max: 15 - }) - } -] - -application - .get("/", (req, res) => res.send("Reposilite stub API")) - .use((req, res, next) => { - console.log("Requested fake " + req.method + " " + req.url) - res.setHeader("Access-Control-Allow-Origin", "*") - res.setHeader("Access-Control-Allow-Headers", "*") - res.setHeader( - "Access-Control-Allow-Methods", - "PUT, POST, GET, HEAD, DELETE, OPTIONS" - ) - next() - }) - .use(express.text()) - .use(bodyParser.raw({ limit: '100mb', extended: true })) - .use(bodyParser.json()) - .get('/api/settings/domains', (req, res) => res.send(['maven'])) - .get('/api/settings/schema/maven', (req, res) => res.send(mavenSettingsSchema)) - .get('/api/settings/domain/maven', (req, res) => res.send(mavenSettingsEntity)) - .put('/api/settings/domain/maven', (req, res) => { mavenSettingsEntity = req.body; res.send("") }) - .get( - "/api/maven/details/snapshots", - respond(createDirectoryDetails("/snapshot", [])) - ) - .get("/api/maven/details/private", (req, res) => { - authorized( - req, - () => - res.send( - createDirectoryDetails("/private", [createDirectoryDetails("1.0.0")]) - ), - () => invalidCredentials(res) - ) - }) - .get("/private/maven-metadata.xml", (req, res) => { - authorized( - req, - () => - res.send(` - - default - private - - 1.0.0 - - 1.0.0 - - - - `), - () => invalidCredentials(res) - ) - }) - .get( - "/api/maven/details/filled", - respond( - createDirectoryDetails( - "/filled", - Array(80) - .fill(undefined) - .map(() => { - const a = crypto.randomBytes(10).toString('hex').substring(0, 1 + Math.round(1 * Math.random())) - const b = crypto.randomBytes(10).toString('hex').substring(0, 1 + Math.round(3 * Math.random())) - const c = crypto.randomBytes(10).toString('hex').substring(0, 1 + Math.round(6 * Math.random())) - const d = crypto.randomBytes(10).toString('hex').substring(0, 1 + Math.round(9 * Math.random())) - return createDirectoryDetails(a + '-' + b + '-' + c + '-' + d) - }) - .concat( - Array(10) - .fill(undefined) - .map(() => createFileDetails(crypto.randomBytes(7).toString('hex'),"text/html", 4096)) - ) - ) - ) - ) - .get( - "/api/maven/details/releases", - respond( - createDirectoryDetails("/releases", [createDirectoryDetails("gav")]) - ) - ) - .get( - "/api/maven/details/releases/gav", - respond( - createDirectoryDetails("/releases/gav", [ - createDirectoryDetails("0.1.0"), - createDirectoryDetails("1.0.0"), - createFileDetails("maven-metadata.xml", "text/xml", 4096), - ]) - ) - ) - .get( - "/api/maven/details/releases/gav/1.0.0", - respond( - createDirectoryDetails("/releases/gav/1.0.0", [ - createFileDetails("gav-1.0.0.jar", "application/jar-archive", 1337), - createFileDetails("gav-1.0.0.jar.md5", "text/plain", 5), - ]) - ) - ) - .get( - "/api/maven/details/releases/gav/0.1.0", - respond( - createDirectoryDetails("/releases/gav/0.1.0", [ - createFileDetails("gav-0.1.0.jar", "application/jar-archive", 1337), - ]) - ) - ) - .get("/releases/gav/1.0.0/gav-1.0.0.jar", respond("content")) - .get("/releases/gav/0.1.0/gav-0.1.0.jar", respond("content")) - .get( - "/releases/gav/maven-metadata.xml", - respond(` - - g.a.v - gav - - 1.0.0 - - 0.1.0 - 1.0.0 - - - - `) - ) - .get("/api/auth/me", (req, res) => { - authorized( - req, - () => - res.send({ - accessToken: { - id: 1, - name: "name", - createdAt: Date.now(), - description: "Description", - }, - permissions: [ - { - identifier: "access-token:manager" - } - ], - routes: [ - { - path: "/", - permission: { - identifier: "route:read", - }, - }, - { - path: "/", - permission: { - identifier: "route:write", - }, - }, - ], - }), - () => invalidCredentials(res) - ) - }) - .get("/api/status/instance", (req, res) => { - authorized( - req, - () => { - res.send({ - version: '3.2.0', - latestVersion: '', - uptime: uptime, - usedMemory: memory, - maxMemory: '32', - usedThreads: threads, - maxThreads: 64, - failuresCount: failures - }) - }, - () => invalidCredentials(res) - ) - }) - .get("/api/status/snapshots", (req, res) => { - authorized( - req, - () => { - res.send([ - { - at: new Date().getTime() - (1000 * 60), - memory: 20, - threads: 11 - }, - { - at: new Date().getTime(), - memory: 10, - threads: 5 - } - ]) - }, - () => invalidCredentials(res) - ) - }) - .get("/api/statistics/resolved/all", (req, res) => { - authorized( - req, - () => - res.send({ - statisticsEnabled: true, - repositories: statisticsSeries - }), - () => invalidCredentials(res) - ) - }) - .ws("/api/console/sock", (connection) => { - let authenticated = false - - connection.on("message", (message) => { - if (message == "Authorization:name:secret") { - sendMessage(connection, "DEBUG | Authorized") - authenticated = true - } - - if (!authenticated || message == "stop") { - sendMessage(connection, "Connection closed") - connection.close() - return - } - - sendMessage(connection, "INFO | Response: " + message) - }) - }) - .get("/api/maven/details", (req, res) => { - const repositories = createDirectoryDetails("/", [ - createDirectoryDetails("releases"), - createDirectoryDetails("snapshots"), - createDirectoryDetails("filled"), - ]) - authorized(req, () => - repositories.files.push(createDirectoryDetails("private")) - ) - res.send(repositories) - }) - .put("*", (req, res) => { - authorized( - req, - () => { - uploadedFiles.push({ - file: req.url, - content: req.body - }) - console.log(`File ${req.url} has been uploaded`) - }, - () => invalidCredentials(res) - ) - }) - .delete("*", (req, res) => { - authorized( - req, - () => { - uploadedFiles = uploadedFiles.filter(entry => entry.file == req.url) - console.log(`File ${req.url} has been deleted`) - }, - () => invalidCredentials(res) - ) - }) - .get("*", (req, res) => - res.status(404).send({ - status: 404, - message: "Not found", - }) - ) - .listen(8080) - -console.log("Reposilite stub API started on port 80") diff --git a/reposilite-frontend/fake-api/maven-settings-entity.json b/reposilite-frontend/fake-api/maven-settings-entity.json deleted file mode 100644 index b05b37f77..000000000 --- a/reposilite-frontend/fake-api/maven-settings-entity.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "repositories": [ - { - "id": "releases", - "visibility": "PUBLIC", - "redeployment": false, - "preserveSnapshots": false, - "storageProvider": { "type": "s3", "bucketName": "test" }, - "proxied": [ - { - "reference": "https://jitpack.io", - "store": true, - "allowedGroups": [], - "connectTimeout": 3, - "readTimeout": 15, - "httpProxy": "" - } - ] - } - ] -} diff --git a/reposilite-frontend/fake-api/maven-settings-schema.json b/reposilite-frontend/fake-api/maven-settings-schema.json deleted file mode 100644 index c87b8c31a..000000000 --- a/reposilite-frontend/fake-api/maven-settings-schema.json +++ /dev/null @@ -1,174 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "properties": { - "repositories": { - "title": "Repositories", - "description": "List of Maven repositories.", - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string", - "title": "Id", - "description": "The id of this repository." - }, - "visibility": { - "type": "string", - "enum": ["PUBLIC", "HIDDEN", "PRIVATE"], - "title": "Visibility", - "description": "The visibility of this repository." - }, - "redeployment": { - "type": "boolean", - "title": "Redeployment", - "description": "Does this repository accept redeployment of the same artifact version." - }, - "preserveSnapshots": { - "type": "boolean", - "title": "Preserved snapshots", - "description": "By default Reposilite deletes all deprecated build files. If you'd like to preserve them, set this property to true." - }, - "storageProvider": { - "oneOf": [ - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "fs" - }, - "quota": { - "type": "string", - "title": "Quota", - "description": "Control the maximum amount of data stored in this repository. Supported formats: 90%, 500MB, 10GB (optional, by default: unlimited)" - }, - "mount": { - "type": "string", - "title": "Mount", - "description": "Use custom directory to locate the repository data (optional, by default it's './repositories/{name}')" - } - }, - "title": "File system Storage Provider", - "description": "Local file system (disk) storage provider settings", - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "s3" - }, - "bucketName": { - "type": "string", - "title": "Bucket", - "description": "The selected AWS bucket" - }, - "endpoint": { - "type": "string", - "title": "Endpoint", - "description": "Overwrite the AWS endpoint (optional)" - }, - "accessKey": { - "type": "string", - "title": "Access Key", - "description": "Overwrite AWS access-key used to authenticate (optional)" - }, - "secretKey": { - "type": "string", - "title": "Secret Key", - "description": "Overwrite AWS secret-key used to authenticate (optional)" - }, - "region": { - "type": "string", - "title": "Region", - "description": "Overwrite AWS region (optional)" - } - }, - "title": "S3 Storage Provider", - "description": "Amazon S3 storage provider settings", - "additionalProperties": false - } - ] - }, - "proxied": { - "title": "Mirrored repositories", - "description": "List of mirrored repositories associated with this repository.", - "type": "array", - "items": { - "type": "object", - "properties": { - "reference": { - "type": "string", - "title": "Link", - "description": "Either the id of other local repository or the URL of a remote repository." - }, - "store": { - "type": "boolean", - "title": "Store", - "description": "Reposilite can store proxied artifacts locally to reduce response time and improve stability." - }, - "allowedGroups": { - "title": "Allowed Groups", - "description": "Allowed artifact groups. If none are given, all artifacts can be obtained from this proxy.", - "type": "array", - "items": { - "type": "string", - "title": "Allowed Groups", - "description": "Allowed artifact groups. If none are given, all artifacts can be obtained from this proxy." - } - }, - "connectTimeout": { - "type": "integer", - "format": "int32", - "title": "Connect Timeout", - "description": "How long Reposilite can wait for establishing the connection with a remote host." - }, - "readTimeout": { - "type": "integer", - "format": "int32", - "title": "Read Timeout", - "description": "How long Reposilite can read data from remote proxy." - }, - "authorization": { - "type": ["object", "null"], - "properties": { - "login": { - "type": "string", - "title": "Login", - "description": "Login to use by proxied HTTP client" - }, - "password": { - "type": "string", - "title": "Password", - "description": "Raw password used by proxied HTTP client to connect to the given repository" - } - }, - "title": "Proxied credentials", - "description": "The authorization credentials used to access proxied repository.", - "additionalProperties": false - }, - "httpProxy": { - "type": "string", - "title": "HTTP Proxy", - "description": "Custom proxy configuration for HTTP/SOCKS client used by Reposilite. Examples:
\nHTTP 127.0.0.1:1081
\nSOCKS 127.0.0.1:1080 login password " - } - }, - "title": "Mirrored Maven Repository", - "description": "Configuration of proxied host", - "additionalProperties": false - } - } - }, - "title": "Maven Repository", - "description": "Settings for a given repository.", - "additionalProperties": false - } - } - }, - "title": "Maven", - "description": "Repositories settings", - "additionalProperties": false -} diff --git a/reposilite-frontend/index.html b/reposilite-frontend/index.html deleted file mode 100644 index 81f045f39..000000000 --- a/reposilite-frontend/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - {{REPOSILITE.TITLE}} - - - - - - - - - - - - -
- - - diff --git a/reposilite-frontend/package-lock.json b/reposilite-frontend/package-lock.json deleted file mode 100644 index ccb80cdd8..000000000 --- a/reposilite-frontend/package-lock.json +++ /dev/null @@ -1,6283 +0,0 @@ -{ - "name": "reposilite-frontend", - "version": "3.4.7", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "reposilite-frontend", - "version": "3.4.7", - "license": "Apache-2.0", - "dependencies": { - "@dzikoysk/vue-vanilla": "^3.1.0", - "@jsonforms/core": "^3.1.0", - "@jsonforms/vue": "^3.1.0", - "@vueform/toggle": "^2.1.4", - "@vueuse/core": "^11.1.0", - "@vueuse/head": "^2.0.0", - "ansi-to-html": "^0.7.2", - "apexcharts": "^3.54.0", - "axios": "^1.7.7", - "downloadjs": "^1.4.7", - "extended-eventsource": "^1.7.0", - "mime-types": "^2.1.35", - "mosha-vue-toastify": "^1.0.23", - "pretty-bytes": "^6.1.1", - "vue": "^3.5.11", - "vue-axios": "^3.5.2", - "vue-final-modal": "^4.5.5", - "vue-float-menu": "^1.9.1", - "vue-router": "^4.4.5", - "vue-upload-component": "^3.1.17", - "vue3-apexcharts": "^1.6.0", - "vue3-tabs": "^0.1.13-beta.3" - }, - "devDependencies": { - "@vitejs/plugin-vue": "^5.1.4", - "@vitejs/plugin-vue-jsx": "^4.0.1", - "@vue/compiler-sfc": "^3.5.11", - "body-parser": "^1.20.3", - "concurrently": "^9.0.1", - "eslint": "9.12.0", - "eslint-plugin-vue": "^9.28.0", - "express": "^4.21.0", - "express-ws": "^5.0.2", - "globals": "^15.10.0", - "jsdoc": "^4.0.3", - "json-server": "^0.17.4", - "nodemon": "^3.1.7", - "rollup-plugin-visualizer": "^5.12.0", - "vite": "^5.4.8", - "vite-plugin-windicss": "^1.9.3", - "windicss": "^3.5.6", - "ws": "^8.18.0" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=9.5.0" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@antfu/utils": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.7.tgz", - "integrity": "sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", - "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", - "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", - "dev": true, - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-module-transforms": "^7.25.2", - "@babel/helpers": "^7.25.0", - "@babel/parser": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.2", - "@babel/types": "^7.25.2", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@babel/core/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", - "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.25.0", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz", - "integrity": "sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", - "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", - "dev": true, - "dependencies": { - "@babel/compat-data": "^7.25.2", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.0.tgz", - "integrity": "sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/helper-replace-supers": "^7.25.0", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/traverse": "^7.25.0", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz", - "integrity": "sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.8" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz", - "integrity": "sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==", - "dev": true, - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz", - "integrity": "sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==", - "dev": true, - "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.24.8", - "@babel/helper-optimise-call-expression": "^7.24.7", - "@babel/traverse": "^7.25.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz", - "integrity": "sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==", - "dev": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", - "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", - "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", - "dependencies": { - "@babel/types": "^7.25.2" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz", - "integrity": "sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==", - "dev": true, - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.24.7", - "@babel/helper-create-class-features-plugin": "^7.25.0", - "@babel/helper-plugin-utils": "^7.24.8", - "@babel/helper-skip-transparent-expression-wrappers": "^7.24.7", - "@babel/plugin-syntax-typescript": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", - "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.2", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/traverse/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@babel/types": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", - "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", - "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@dzikoysk/vue-vanilla": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@dzikoysk/vue-vanilla/-/vue-vanilla-3.1.0.tgz", - "integrity": "sha512-kDJ5M+knHNq86Ax9u05h7WyEZeDiKZCcpHcR74lWcvSWGBxe+qzCo2MD0h9QFdNypc8HqdL/rPdqs+dYDrJ7tA==", - "dependencies": { - "lodash": "^4.17.15" - }, - "peerDependencies": { - "@jsonforms/core": "3.1.0", - "@jsonforms/vue": "3.1.0", - "vue": "^3.2.26" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.4", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-array/node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@eslint/config-array/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@eslint/core": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", - "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@eslint/js": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", - "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", - "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", - "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.5", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", - "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.0", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jsdoc/salty": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.6.tgz", - "integrity": "sha512-aA+awb5yoml8TQ3CzI5Ue7sM3VMRC4l1zJJW4fgZ8OCL1wshJZhNzaf0PL85DSnOUw6QuFgeHGD/eq/xwwAF2g==", - "dev": true, - "dependencies": { - "lodash": "^4.17.21" - }, - "engines": { - "node": ">=v12.0.0" - } - }, - "node_modules/@jsonforms/core": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jsonforms/core/-/core-3.1.0.tgz", - "integrity": "sha512-Whs6+VBNhQyMFoPjLCltS4KzcRskayBPYkj7zZaPgA/piPLQXAglAsz5jd5SK7bncYy+dGQSB/6LPzP1QhRxqw==", - "dependencies": { - "@types/json-schema": "^7.0.3", - "ajv": "^8.6.1", - "ajv-formats": "^2.1.0", - "lodash": "^4.17.15" - } - }, - "node_modules/@jsonforms/vue": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jsonforms/vue/-/vue-3.1.0.tgz", - "integrity": "sha512-Jx6vVebjPeRdHK4WzX1+Fz4ADLrbgTtrbduFJqvQtUrPmjKqdGcOFUWofnYlM8BIWawOBqSv2r1PxWqFQqopVw==", - "dependencies": { - "lodash": "^4.17.15" - }, - "peerDependencies": { - "@jsonforms/core": "3.1.0", - "vue": "^3.2.26" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "license": "MIT" - }, - "node_modules/@types/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", - "dev": true - }, - "node_modules/@types/markdown-it": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.1.tgz", - "integrity": "sha512-4NpsnpYl2Gt1ljyBGrKMxFYAYvpqbnnkgP/i/g+NLpjEUa3obn1XJCur9YbEXKDAkaXqsR1LbDnGEJ0MmKFxfg==", - "dev": true, - "dependencies": { - "@types/linkify-it": "^5", - "@types/mdurl": "^2" - } - }, - "node_modules/@types/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", - "dev": true - }, - "node_modules/@types/web-bluetooth": { - "version": "0.0.20", - "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", - "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==" - }, - "node_modules/@unhead/dom": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@unhead/dom/-/dom-1.7.4.tgz", - "integrity": "sha512-xanQMtGmgikqTvDtuyJy6GXgqvUXOdrdnIyqAabpeS8goD8udxo0stzjtbT8ERbMQibzPGSGcN+Ux+MKoWzrjQ==", - "dependencies": { - "@unhead/schema": "1.7.4", - "@unhead/shared": "1.7.4" - }, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - } - }, - "node_modules/@unhead/schema": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@unhead/schema/-/schema-1.7.4.tgz", - "integrity": "sha512-wUL4CK0NSEm3KH4kYsiqVYQw5xBk1hpBi5tiNj0BTZgpQVrRufICdK5EHA9Fh7OIAR6tOTWwTvsf5+nK0BgQDA==", - "dependencies": { - "hookable": "^5.5.3", - "zhead": "^2.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - } - }, - "node_modules/@unhead/shared": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@unhead/shared/-/shared-1.7.4.tgz", - "integrity": "sha512-YUNA2UxAuDPnDps41BQ8aEIY5hdyvruSB1Vs3AALhRo07MxMivSq5DjNKfYr/JvRN6593RtfI1NHnP9x5M57xA==", - "dependencies": { - "@unhead/schema": "1.7.4" - }, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - } - }, - "node_modules/@unhead/ssr": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@unhead/ssr/-/ssr-1.7.4.tgz", - "integrity": "sha512-2QqaHdC48XJGP9Pd0F2fblPv9/6G4IU04iZ5qLRAs6MFFmFEzrdvoooFlcwdcoH/WDGRnpYBmo+Us2nzQz1MMQ==", - "dependencies": { - "@unhead/schema": "1.7.4", - "@unhead/shared": "1.7.4" - }, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - } - }, - "node_modules/@unhead/vue": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@unhead/vue/-/vue-1.7.4.tgz", - "integrity": "sha512-ZfgzOhg1Bxo9xwp3upawqerw4134hc9Lhz6t005ixcBwPX+39Wpgc9dC3lf+owFQEVuWkf8F+eAwK2sghVBK4A==", - "dependencies": { - "@unhead/schema": "1.7.4", - "@unhead/shared": "1.7.4", - "hookable": "^5.5.3", - "unhead": "1.7.4" - }, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - }, - "peerDependencies": { - "vue": ">=2.7 || >=3" - } - }, - "node_modules/@vitejs/plugin-vue": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz", - "integrity": "sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "vite": "^5.0.0", - "vue": "^3.2.25" - } - }, - "node_modules/@vitejs/plugin-vue-jsx": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-4.0.1.tgz", - "integrity": "sha512-7mg9HFGnFHMEwCdB6AY83cVK4A6sCqnrjFYF4WIlebYAQVVJ/sC/CiTruVdrRlhrFoeZ8rlMxY9wYpPTIRhhAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.24.7", - "@babel/plugin-transform-typescript": "^7.24.7", - "@vue/babel-plugin-jsx": "^1.2.2" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "vite": "^5.0.0", - "vue": "^3.0.0" - } - }, - "node_modules/@vue/babel-helper-vue-transform-on": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.2.2.tgz", - "integrity": "sha512-nOttamHUR3YzdEqdM/XXDyCSdxMA9VizUKoroLX6yTyRtggzQMHXcmwh8a7ZErcJttIBIc9s68a1B8GZ+Dmvsw==", - "dev": true - }, - "node_modules/@vue/babel-plugin-jsx": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.2.2.tgz", - "integrity": "sha512-nYTkZUVTu4nhP199UoORePsql0l+wj7v/oyQjtThUVhJl1U+6qHuoVhIvR3bf7eVKjbCK+Cs2AWd7mi9Mpz9rA==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "~7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.23.3", - "@babel/template": "^7.23.9", - "@babel/traverse": "^7.23.9", - "@babel/types": "^7.23.9", - "@vue/babel-helper-vue-transform-on": "1.2.2", - "@vue/babel-plugin-resolve-type": "1.2.2", - "camelcase": "^6.3.0", - "html-tags": "^3.3.1", - "svg-tags": "^1.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - } - } - }, - "node_modules/@vue/babel-plugin-jsx/node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@vue/babel-plugin-resolve-type": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.2.2.tgz", - "integrity": "sha512-EntyroPwNg5IPVdUJupqs0CFzuf6lUrVvCspmv2J1FITLeGnUCuoGNNk78dgCusxEiYj6RMkTJflGSxk5aIC4A==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/helper-module-imports": "~7.22.15", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/parser": "^7.23.9", - "@vue/compiler-sfc": "^3.4.15" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@vue/babel-plugin-resolve-type/node_modules/@babel/helper-module-imports": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.15" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@vue/compiler-core": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.11.tgz", - "integrity": "sha512-PwAdxs7/9Hc3ieBO12tXzmTD+Ln4qhT/56S+8DvrrZ4kLDn4Z/AMUr8tXJD0axiJBS0RKIoNaR0yMuQB9v9Udg==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.25.3", - "@vue/shared": "3.5.11", - "entities": "^4.5.0", - "estree-walker": "^2.0.2", - "source-map-js": "^1.2.0" - } - }, - "node_modules/@vue/compiler-core/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/@vue/compiler-dom": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.11.tgz", - "integrity": "sha512-pyGf8zdbDDRkBrEzf8p7BQlMKNNF5Fk/Cf/fQ6PiUz9at4OaUfyXW0dGJTo2Vl1f5U9jSLCNf0EZJEogLXoeew==", - "license": "MIT", - "dependencies": { - "@vue/compiler-core": "3.5.11", - "@vue/shared": "3.5.11" - } - }, - "node_modules/@vue/compiler-sfc": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.11.tgz", - "integrity": "sha512-gsbBtT4N9ANXXepprle+X9YLg2htQk1sqH/qGJ/EApl+dgpUBdTv3yP7YlR535uHZY3n6XaR0/bKo0BgwwDniw==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.25.3", - "@vue/compiler-core": "3.5.11", - "@vue/compiler-dom": "3.5.11", - "@vue/compiler-ssr": "3.5.11", - "@vue/shared": "3.5.11", - "estree-walker": "^2.0.2", - "magic-string": "^0.30.11", - "postcss": "^8.4.47", - "source-map-js": "^1.2.0" - } - }, - "node_modules/@vue/compiler-ssr": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.11.tgz", - "integrity": "sha512-P4+GPjOuC2aFTk1Z4WANvEhyOykcvEd5bIj2KVNGKGfM745LaXGr++5njpdBTzVz5pZifdlR1kpYSJJpIlSePA==", - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.11", - "@vue/shared": "3.5.11" - } - }, - "node_modules/@vue/devtools-api": { - "version": "6.6.4", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", - "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", - "license": "MIT" - }, - "node_modules/@vue/reactivity": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.11.tgz", - "integrity": "sha512-Nqo5VZEn8MJWlCce8XoyVqHZbd5P2NH+yuAaFzuNSR96I+y1cnuUiq7xfSG+kyvLSiWmaHTKP1r3OZY4mMD50w==", - "license": "MIT", - "dependencies": { - "@vue/shared": "3.5.11" - } - }, - "node_modules/@vue/runtime-core": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.11.tgz", - "integrity": "sha512-7PsxFGqwfDhfhh0OcDWBG1DaIQIVOLgkwA5q6MtkPiDFjp5gohVnJEahSktwSFLq7R5PtxDKy6WKURVN1UDbzA==", - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.5.11", - "@vue/shared": "3.5.11" - } - }, - "node_modules/@vue/runtime-dom": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.11.tgz", - "integrity": "sha512-GNghjecT6IrGf0UhuYmpgaOlN7kxzQBhxWEn08c/SQDxv1yy4IXI1bn81JgEpQ4IXjRxWtPyI8x0/7TF5rPfYQ==", - "license": "MIT", - "dependencies": { - "@vue/reactivity": "3.5.11", - "@vue/runtime-core": "3.5.11", - "@vue/shared": "3.5.11", - "csstype": "^3.1.3" - } - }, - "node_modules/@vue/server-renderer": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.11.tgz", - "integrity": "sha512-cVOwYBxR7Wb1B1FoxYvtjJD8X/9E5nlH4VSkJy2uMA1MzYNdzAAB//l8nrmN9py/4aP+3NjWukf9PZ3TeWULaA==", - "license": "MIT", - "dependencies": { - "@vue/compiler-ssr": "3.5.11", - "@vue/shared": "3.5.11" - }, - "peerDependencies": { - "vue": "3.5.11" - } - }, - "node_modules/@vue/shared": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.11.tgz", - "integrity": "sha512-W8GgysJVnFo81FthhzurdRAWP/byq3q2qIw70e0JWblzVhjgOMiC2GyovXrZTFQJnFVryYaKGP3Tc9vYzYm6PQ==", - "license": "MIT" - }, - "node_modules/@vueform/toggle": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@vueform/toggle/-/toggle-2.1.4.tgz", - "integrity": "sha512-tEITFf5wlqIWoCYZXJdoXvCnrc97weOu2csR/BEoROVvFu1zRsoK0wY1pJG7BR+g5zpGJneGSdLhMUsbx8y1yw==" - }, - "node_modules/@vueuse/core": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.1.0.tgz", - "integrity": "sha512-P6dk79QYA6sKQnghrUz/1tHi0n9mrb/iO1WTMk/ElLmTyNqgDeSZ3wcDf6fRBGzRJbeG1dxzEOvLENMjr+E3fg==", - "license": "MIT", - "dependencies": { - "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "11.1.0", - "@vueuse/shared": "11.1.0", - "vue-demi": ">=0.14.10" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/core/node_modules/@vueuse/shared": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.1.0.tgz", - "integrity": "sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w==", - "license": "MIT", - "dependencies": { - "vue-demi": ">=0.14.10" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", - "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/@vueuse/head": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@vueuse/head/-/head-2.0.0.tgz", - "integrity": "sha512-ykdOxTGs95xjD4WXE4na/umxZea2Itl0GWBILas+O4oqS7eXIods38INvk3XkJKjqMdWPcpCyLX/DioLQxU1KA==", - "dependencies": { - "@unhead/dom": "^1.7.0", - "@unhead/schema": "^1.7.0", - "@unhead/ssr": "^1.7.0", - "@unhead/vue": "^1.7.0" - }, - "peerDependencies": { - "vue": ">=2.7 || >=3" - } - }, - "node_modules/@vueuse/integrations": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-10.6.0.tgz", - "integrity": "sha512-4RsM5+HF2IUOCFngdyQyvhDEFjus2gzOnPR2FbX4l+pQ4KPMMqzic1AFIq4bMYaVp32p/HF+pidTXwLJIZSQtA==", - "dependencies": { - "@vueuse/core": "10.6.0", - "@vueuse/shared": "10.6.0", - "vue-demi": ">=0.14.6" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "async-validator": "*", - "axios": "*", - "change-case": "*", - "drauu": "*", - "focus-trap": "*", - "fuse.js": "*", - "idb-keyval": "*", - "jwt-decode": "*", - "nprogress": "*", - "qrcode": "*", - "sortablejs": "*", - "universal-cookie": "*" - }, - "peerDependenciesMeta": { - "async-validator": { - "optional": true - }, - "axios": { - "optional": true - }, - "change-case": { - "optional": true - }, - "drauu": { - "optional": true - }, - "focus-trap": { - "optional": true - }, - "fuse.js": { - "optional": true - }, - "idb-keyval": { - "optional": true - }, - "jwt-decode": { - "optional": true - }, - "nprogress": { - "optional": true - }, - "qrcode": { - "optional": true - }, - "sortablejs": { - "optional": true - }, - "universal-cookie": { - "optional": true - } - } - }, - "node_modules/@vueuse/integrations/node_modules/@vueuse/core": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.6.0.tgz", - "integrity": "sha512-+Yee+g9+9BEbvkyGdn4Bf4yZx9EfocAytpV2ZlrlP7xcz+qznLmZIDqDroTvc5vtMkWZicisgEv8dt3+jL+HQg==", - "dependencies": { - "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "10.6.0", - "@vueuse/shared": "10.6.0", - "vue-demi": ">=0.14.6" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/integrations/node_modules/@vueuse/metadata": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.6.0.tgz", - "integrity": "sha512-mzKHkHoiK6xVz01VzQjM2l6ofUanEaofgEGPgDHcAzlvOTccPRTIdEuzneOUTYxgfm1vkDikS6rtrEw/NYlaTQ==", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/integrations/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/@vueuse/metadata": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.1.0.tgz", - "integrity": "sha512-l9Q502TBTaPYGanl1G+hPgd3QX5s4CGnpXriVBR5fEZ/goI6fvDaVmIl3Td8oKFurOxTmbXvBPSsgrd6eu6HYg==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/shared": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.6.0.tgz", - "integrity": "sha512-0t4MVE18sO+/4Gh0jfeOXBTjKeV4606N9kIrDOLPjFl8Rwnlodn+QC5A4LfJuysK7aOsTMjF3KnzNeueaI0xlQ==", - "dependencies": { - "vue-demi": ">=0.14.6" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@vueuse/shared/node_modules/vue-demi": { - "version": "0.14.6", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.6.tgz", - "integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==", - "hasInstallScript": true, - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/@windicss/config": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@windicss/config/-/config-1.9.3.tgz", - "integrity": "sha512-u8GUjsfC9r5X1AGYhzb1lX3zZj8wqk6SH1DYex8XUGmZ1M2UpvnUPOFi63XFViduspQ6l2xTX84QtG+lUzhEoQ==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "jiti": "^1.18.2", - "windicss": "^3.5.6" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@windicss/config/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@windicss/config/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@windicss/plugin-utils": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@windicss/plugin-utils/-/plugin-utils-1.9.3.tgz", - "integrity": "sha512-3VG5HEGeuIfG/9iTwLyzWWm/aGKNTbtSVkpkAabdRuDP/2lEmf6Hpo4uo5drwE+2O9gXfc6nSYgAwBjotx5CfQ==", - "dev": true, - "dependencies": { - "@antfu/utils": "^0.7.2", - "@windicss/config": "1.9.3", - "debug": "^4.3.4", - "fast-glob": "^3.2.12", - "magic-string": "^0.30.0", - "micromatch": "^4.0.5", - "windicss": "^3.5.6" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/@windicss/plugin-utils/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/@windicss/plugin-utils/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/@yr/monotone-cubic-spline": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@yr/monotone-cubic-spline/-/monotone-cubic-spline-1.0.3.tgz", - "integrity": "sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==" - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/ansi-to-html": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ansi-to-html/-/ansi-to-html-0.7.2.tgz", - "integrity": "sha512-v6MqmEpNlxF+POuyhKkidusCHWWkaLcGRURzivcU3I9tv7k4JVhFcnukrM5Rlk2rUywdZuzYAZ+kbZqWCnfN3g==", - "dependencies": { - "entities": "^2.2.0" - }, - "bin": { - "ansi-to-html": "bin/ansi-to-html" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/apexcharts": { - "version": "3.54.0", - "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.54.0.tgz", - "integrity": "sha512-ZgI/seScffjLpwNRX/gAhIkAhpCNWiTNsdICv7qxnF0xisI23XSsaENUKIcMlyP1rbe8ECgvybDnp7plZld89A==", - "license": "MIT", - "dependencies": { - "@yr/monotone-cubic-spline": "^1.0.3", - "svg.draggable.js": "^2.2.2", - "svg.easing.js": "^2.0.0", - "svg.filter.js": "^2.0.2", - "svg.pathmorphing.js": "^0.1.3", - "svg.resize.js": "^1.4.3", - "svg.select.js": "^3.0.1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dev": true, - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/basic-auth/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001646", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001646.tgz", - "integrity": "sha512-dRg00gudiBDDTmUhClSdv3hqRfpbOnU28IpI1T6PBTLWa+kOj0681C8uML3PifYfREuBrVjDGhL3adYpBT6spw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ] - }, - "node_modules/catharsis": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", - "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/chokidar": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/compression/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/concurrently": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.0.1.tgz", - "integrity": "sha512-wYKvCd/f54sTXJMSfV6Ln/B8UrfLBKOYa+lzc6CHay3Qek+LorVSBdMVfyewFhRbH0Rbabsk4D+3PL/VjQ5gzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "lodash": "^4.17.21", - "rxjs": "^7.8.1", - "shell-quote": "^1.8.1", - "supports-color": "^8.1.1", - "tree-kill": "^1.2.2", - "yargs": "^17.7.2" - }, - "bin": { - "conc": "dist/bin/concurrently.js", - "concurrently": "dist/bin/concurrently.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" - } - }, - "node_modules/connect-pause": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/connect-pause/-/connect-pause-0.1.1.tgz", - "integrity": "sha512-a1gSWQBQD73krFXdUEYJom2RTFrWUL3YvXDCRkyv//GVXc79cdW9MngtRuN9ih4FDKBtfJAJId+BbDuX+1rh2w==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "dev": true - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dev": true, - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "license": "MIT" - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/downloadjs": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/downloadjs/-/downloadjs-1.4.7.tgz", - "integrity": "sha1-9p+W+UDg0FU9rCkROYZaPNAQHjw=" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "node_modules/electron-to-chromium": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.4.tgz", - "integrity": "sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==", - "dev": true - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/errorhandler": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", - "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", - "dev": true, - "dependencies": { - "accepts": "~1.3.7", - "escape-html": "~1.0.3" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", - "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.6.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.12.0", - "@eslint/plugin-kit": "^0.2.0", - "@humanfs/node": "^0.16.5", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.1", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.1.0", - "eslint-visitor-keys": "^4.1.0", - "espree": "^10.2.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-vue": { - "version": "9.28.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.28.0.tgz", - "integrity": "sha512-ShrihdjIhOTxs+MfWun6oJWuk+g/LAhN+CiuOl/jjkG3l0F2AuK5NMTaWqyvBgkFtpYmyks6P4603mLmhNJW8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "globals": "^13.24.0", - "natural-compare": "^1.4.0", - "nth-check": "^2.1.1", - "postcss-selector-parser": "^6.0.15", - "semver": "^7.6.3", - "vue-eslint-parser": "^9.4.3", - "xml-name-validator": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-vue/node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-scope": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", - "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz", - "integrity": "sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/eslint/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", - "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/eslint/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/espree": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", - "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.12.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", - "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express": { - "version": "4.21.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz", - "integrity": "sha512-VqcNGcj/Id5ZT1LZ/cfihi3ttTn+NJmkli2eZADigjq29qTlWi/hAQ43t/VLPq8+UX06FCEx3ByOYet6ZFblng==", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.6.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express-urlrewrite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/express-urlrewrite/-/express-urlrewrite-1.4.0.tgz", - "integrity": "sha512-PI5h8JuzoweS26vFizwQl6UTF25CAHSggNv0J25Dn/IKZscJHWZzPrI5z2Y2jgOzIaw2qh8l6+/jUcig23Z2SA==", - "dev": true, - "dependencies": { - "debug": "*", - "path-to-regexp": "^1.0.3" - } - }, - "node_modules/express-urlrewrite/node_modules/path-to-regexp": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "isarray": "0.0.1" - } - }, - "node_modules/express-ws": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/express-ws/-/express-ws-5.0.2.tgz", - "integrity": "sha512-0uvmuk61O9HXgLhGl3QhNSEtRsQevtmbL94/eILaliEADZBHZOQUAiHFrGPrgsjikohyrmSG5g+sCfASTt0lkQ==", - "dev": true, - "dependencies": { - "ws": "^7.4.6" - }, - "engines": { - "node": ">=4.5.0" - }, - "peerDependencies": { - "express": "^4.0.0 || ^5.0.0-alpha.1" - } - }, - "node_modules/express-ws/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/extended-eventsource": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extended-eventsource/-/extended-eventsource-1.7.0.tgz", - "integrity": "sha512-s8rtvZuYcKBpzytHb5g95cHbZ1J99WeMnV18oKc5wKoxkHzlzpPc/bNAm7Da2Db0BDw0CAu1z3LpH+7UsyzIpw==", - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", - "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "node_modules/focus-trap": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.4.tgz", - "integrity": "sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==", - "dependencies": { - "tabbable": "^6.2.0" - } - }, - "node_modules/focus-visible": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/focus-visible/-/focus-visible-5.2.0.tgz", - "integrity": "sha512-Rwix9pBtC1Nuy5wysTmKy+UjbDJpIfg8eHjw0rjZ1mX4GNLz1Bmd16uDpI3Gk1i70Fgcs8Csg2lPm8HULFg9DQ==" - }, - "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "15.10.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.10.0.tgz", - "integrity": "sha512-tqFIbz83w4Y5TCbtgjZjApohbuh7K9BxGYFm7ifwDR240tvdb7P9x+/9VvUKlmkPoiknoJtanI8UOrqxS3a7lQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hookable": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", - "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==" - }, - "node_modules/html-tags": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", - "dev": true, - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/jju": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", - "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", - "dev": true - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/js2xmlparser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", - "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", - "dev": true, - "dependencies": { - "xmlcreate": "^2.0.4" - } - }, - "node_modules/jsdoc": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.3.tgz", - "integrity": "sha512-Nu7Sf35kXJ1MWDZIMAuATRQTg1iIPdzh7tqJ6jjvaU/GfDf+qi5UV8zJR3Mo+/pYFvm8mzay4+6O5EWigaQBQw==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.20.15", - "@jsdoc/salty": "^0.2.1", - "@types/markdown-it": "^14.1.1", - "bluebird": "^3.7.2", - "catharsis": "^0.9.0", - "escape-string-regexp": "^2.0.0", - "js2xmlparser": "^4.0.2", - "klaw": "^3.0.0", - "markdown-it": "^14.1.0", - "markdown-it-anchor": "^8.6.7", - "marked": "^4.0.10", - "mkdirp": "^1.0.4", - "requizzle": "^0.2.3", - "strip-json-comments": "^3.1.0", - "underscore": "~1.13.2" - }, - "bin": { - "jsdoc": "jsdoc.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/jsdoc/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-parse-helpfulerror": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz", - "integrity": "sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==", - "dev": true, - "dependencies": { - "jju": "^1.1.0" - } - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" - }, - "node_modules/json-server": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/json-server/-/json-server-0.17.4.tgz", - "integrity": "sha512-bGBb0WtFuAKbgI7JV3A864irWnMZSvBYRJbohaOuatHwKSRFUfqtQlrYMrB6WbalXy/cJabyjlb7JkHli6dYjQ==", - "dev": true, - "dependencies": { - "body-parser": "^1.19.0", - "chalk": "^4.1.2", - "compression": "^1.7.4", - "connect-pause": "^0.1.1", - "cors": "^2.8.5", - "errorhandler": "^1.5.1", - "express": "^4.17.1", - "express-urlrewrite": "^1.4.0", - "json-parse-helpfulerror": "^1.0.3", - "lodash": "^4.17.21", - "lodash-id": "^0.14.1", - "lowdb": "^1.0.0", - "method-override": "^3.0.0", - "morgan": "^1.10.0", - "nanoid": "^3.1.23", - "please-upgrade-node": "^3.2.0", - "pluralize": "^8.0.0", - "server-destroy": "^1.0.1", - "yargs": "^17.0.1" - }, - "bin": { - "json-server": "lib/cli/bin.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/klaw": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", - "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.9" - } - }, - "node_modules/kolorist": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", - "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", - "dev": true - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/linkify-it": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", - "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", - "dev": true, - "dependencies": { - "uc.micro": "^2.0.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash-id": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/lodash-id/-/lodash-id-0.14.1.tgz", - "integrity": "sha512-ikQPBTiq/d5m6dfKQlFdIXFzvThPi2Be9/AHxktOnDSfSxE1j9ICbBT5Elk1ke7HSTgM38LHTpmJovo9/klnLg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lowdb": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz", - "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.3", - "is-promise": "^2.1.0", - "lodash": "4", - "pify": "^3.0.0", - "steno": "^0.4.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/markdown-it": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", - "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1", - "entities": "^4.4.0", - "linkify-it": "^5.0.0", - "mdurl": "^2.0.0", - "punycode.js": "^2.3.1", - "uc.micro": "^2.1.0" - }, - "bin": { - "markdown-it": "bin/markdown-it.mjs" - } - }, - "node_modules/markdown-it-anchor": { - "version": "8.6.7", - "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", - "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", - "dev": true, - "peerDependencies": { - "@types/markdown-it": "*", - "markdown-it": "*" - } - }, - "node_modules/markdown-it/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/marked": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", - "dev": true, - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/mdurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/method-override": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz", - "integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==", - "dev": true, - "dependencies": { - "debug": "3.1.0", - "methods": "~1.1.2", - "parseurl": "~1.3.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/method-override/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/morgan": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", - "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", - "dev": true, - "dependencies": { - "basic-auth": "~2.0.1", - "debug": "2.6.9", - "depd": "~2.0.0", - "on-finished": "~2.3.0", - "on-headers": "~1.0.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/morgan/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/mosha-vue-toastify": { - "version": "1.0.23", - "resolved": "https://registry.npmjs.org/mosha-vue-toastify/-/mosha-vue-toastify-1.0.23.tgz", - "integrity": "sha512-K9fij3e3H+E/Lj82ISrgmyKrtM5RNmtZC/KG/KH47+oZGmzAkN/Zuz39kBdT/Mp8OxaHuIWQntEUMP+HdmK1xA==" - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true - }, - "node_modules/nodemon": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.7.tgz", - "integrity": "sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^4", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^7.5.3", - "simple-update-notifier": "^2.0.0", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/nodemon/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/nodemon/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nodemon/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", - "dev": true, - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", - "dev": true, - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dev": true, - "dependencies": { - "semver-compare": "^1.0.0" - } - }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.0", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.15", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", - "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/pretty-bytes": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", - "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==", - "engines": { - "node": "^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "dev": true - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/punycode.js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", - "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requizzle": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", - "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.21" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rollup": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.6" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.0", - "@rollup/rollup-android-arm64": "4.24.0", - "@rollup/rollup-darwin-arm64": "4.24.0", - "@rollup/rollup-darwin-x64": "4.24.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", - "@rollup/rollup-linux-arm-musleabihf": "4.24.0", - "@rollup/rollup-linux-arm64-gnu": "4.24.0", - "@rollup/rollup-linux-arm64-musl": "4.24.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", - "@rollup/rollup-linux-riscv64-gnu": "4.24.0", - "@rollup/rollup-linux-s390x-gnu": "4.24.0", - "@rollup/rollup-linux-x64-gnu": "4.24.0", - "@rollup/rollup-linux-x64-musl": "4.24.0", - "@rollup/rollup-win32-arm64-msvc": "4.24.0", - "@rollup/rollup-win32-ia32-msvc": "4.24.0", - "@rollup/rollup-win32-x64-msvc": "4.24.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-visualizer": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-visualizer/-/rollup-plugin-visualizer-5.12.0.tgz", - "integrity": "sha512-8/NU9jXcHRs7Nnj07PF2o4gjxmm9lXIrZ8r175bT9dK8qoLlvKTwRMArRCMgpMGlq8CTLugRvEmyMeMXIU2pNQ==", - "dev": true, - "dependencies": { - "open": "^8.4.0", - "picomatch": "^2.3.1", - "source-map": "^0.7.4", - "yargs": "^17.5.1" - }, - "bin": { - "rollup-plugin-visualizer": "dist/bin/cli.js" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "rollup": "2.x || 3.x || 4.x" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/rollup-plugin-visualizer/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true - }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "dev": true, - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==", - "dev": true - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/simple-update-notifier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", - "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", - "dev": true, - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/steno": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz", - "integrity": "sha512-EEHMVYHNXFHfGtgjNITnka0aHhiAlo93F7z2/Pwd+g0teG9CnM3JIINM7hVVB5/rhw9voufD7Wukwgtw2uqh6w==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.3" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", - "dev": true - }, - "node_modules/svg.draggable.js": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz", - "integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==", - "dependencies": { - "svg.js": "^2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svg.easing.js": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz", - "integrity": "sha512-//ctPdJMGy22YoYGV+3HEfHbm6/69LJUTAqI2/5qBvaNHZ9uUFVC82B0Pl299HzgH13rKrBgi4+XyXXyVWWthA==", - "dependencies": { - "svg.js": ">=2.3.x" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svg.filter.js": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz", - "integrity": "sha512-xkGBwU+dKBzqg5PtilaTb0EYPqPfJ9Q6saVldX+5vCRy31P6TlRCP3U9NxH3HEufkKkpNgdTLBJnmhDHeTqAkw==", - "dependencies": { - "svg.js": "^2.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svg.js": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz", - "integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA==" - }, - "node_modules/svg.pathmorphing.js": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz", - "integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==", - "dependencies": { - "svg.js": "^2.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svg.resize.js": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz", - "integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==", - "dependencies": { - "svg.js": "^2.6.5", - "svg.select.js": "^2.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svg.resize.js/node_modules/svg.select.js": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz", - "integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==", - "dependencies": { - "svg.js": "^2.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/svg.select.js": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz", - "integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==", - "dependencies": { - "svg.js": "^2.6.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/tabbable": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", - "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/touch": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", - "dev": true, - "dependencies": { - "nopt": "~1.0.10" - }, - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "bin": { - "tree-kill": "cli.js" - } - }, - "node_modules/tslib": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz", - "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/uc.micro": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "dev": true - }, - "node_modules/underscore": { - "version": "1.13.6", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", - "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", - "dev": true - }, - "node_modules/unhead": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/unhead/-/unhead-1.7.4.tgz", - "integrity": "sha512-oOv+9aQS85DQUd0f1uJBtb2uG3SKwCURSTuUWp9WKKzANCb1TjW2dWp5TFmJH5ILF6urXi4uUQfjK+SawzBJAA==", - "dependencies": { - "@unhead/dom": "1.7.4", - "@unhead/schema": "1.7.4", - "@unhead/shared": "1.7.4", - "hookable": "^5.5.3" - }, - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vite": { - "version": "5.4.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", - "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-plugin-windicss": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/vite-plugin-windicss/-/vite-plugin-windicss-1.9.3.tgz", - "integrity": "sha512-PqNiIsrEftCrgn0xIpj8ZMSdpz8NZn+OJ3gKXnOF+hFzbHFrKGJA49ViOUKCHDOquxoGBZMmTjepWr8GrftKcQ==", - "dev": true, - "dependencies": { - "@windicss/plugin-utils": "1.9.3", - "debug": "^4.3.4", - "kolorist": "^1.8.0", - "windicss": "^3.5.6" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "vite": "^2.0.1 || ^3.0.0 || ^4.0.0 || ^5.0.0" - } - }, - "node_modules/vite-plugin-windicss/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/vite-plugin-windicss/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/vue": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.11.tgz", - "integrity": "sha512-/8Wurrd9J3lb72FTQS7gRMNQD4nztTtKPmuDuPuhqXmmpD6+skVjAeahNpVzsuky6Sy9gy7wn8UadqPtt9SQIg==", - "license": "MIT", - "dependencies": { - "@vue/compiler-dom": "3.5.11", - "@vue/compiler-sfc": "3.5.11", - "@vue/runtime-dom": "3.5.11", - "@vue/server-renderer": "3.5.11", - "@vue/shared": "3.5.11" - }, - "peerDependencies": { - "typescript": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/vue-axios": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/vue-axios/-/vue-axios-3.5.2.tgz", - "integrity": "sha512-GP+dct7UlAWkl1qoP3ppw0z6jcSua5/IrMpjB5O8bh089iIiJ+hdxPYH2NPEpajlYgkW5EVMP95ttXWdas1O0g==", - "peerDependencies": { - "axios": "*", - "vue": "^3.0.0 || ^2.0.0" - } - }, - "node_modules/vue-eslint-parser": { - "version": "9.4.3", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz", - "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", - "esquery": "^1.4.0", - "lodash": "^4.17.21", - "semver": "^7.3.6" - }, - "engines": { - "node": "^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/vue-eslint-parser/node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/vue-eslint-parser/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/vue-eslint-parser/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/vue-eslint-parser/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/vue-final-modal": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/vue-final-modal/-/vue-final-modal-4.5.5.tgz", - "integrity": "sha512-A6xgsXqE6eLw9e6Tq/W6pxDBmimPuSuvq20WL9TOZpZy7itPdGeNn8e1P15PCGqP2yHM3q2gJIchPY9ZJd8YsA==", - "license": "MIT", - "dependencies": { - "@vueuse/core": "^10.5.0", - "@vueuse/integrations": "^10.5.0", - "focus-trap": "^7.5.4" - }, - "peerDependencies": { - "@vueuse/core": ">=10.0.0", - "@vueuse/integrations": ">=10.0.0", - "focus-trap": ">=7.2.0", - "vue": ">=3.2.0" - } - }, - "node_modules/vue-final-modal/node_modules/@vueuse/core": { - "version": "10.11.1", - "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.11.1.tgz", - "integrity": "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==", - "license": "MIT", - "dependencies": { - "@types/web-bluetooth": "^0.0.20", - "@vueuse/metadata": "10.11.1", - "@vueuse/shared": "10.11.1", - "vue-demi": ">=0.14.8" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/vue-final-modal/node_modules/@vueuse/core/node_modules/vue-demi": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", - "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/vue-final-modal/node_modules/@vueuse/metadata": { - "version": "10.11.1", - "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.11.1.tgz", - "integrity": "sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/vue-final-modal/node_modules/@vueuse/shared": { - "version": "10.11.1", - "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.11.1.tgz", - "integrity": "sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==", - "license": "MIT", - "dependencies": { - "vue-demi": ">=0.14.8" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/vue-final-modal/node_modules/@vueuse/shared/node_modules/vue-demi": { - "version": "0.14.10", - "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz", - "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "vue-demi-fix": "bin/vue-demi-fix.js", - "vue-demi-switch": "bin/vue-demi-switch.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - }, - "peerDependencies": { - "@vue/composition-api": "^1.0.0-rc.1", - "vue": "^3.0.0-0 || ^2.6.0" - }, - "peerDependenciesMeta": { - "@vue/composition-api": { - "optional": true - } - } - }, - "node_modules/vue-float-menu": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/vue-float-menu/-/vue-float-menu-1.9.1.tgz", - "integrity": "sha512-qLPADW51429C0sssVHxPMblA9wkY5mbGbszwdOKSws7Xy1KUu08uMkK7BPiXdhXET19hvAys4G80aghX7XBkLg==", - "dependencies": { - "focus-visible": "^5.2.0" - }, - "peerDependencies": { - "@vue/compiler-sfc": "^3.0.4", - "vue": "^3.0.4" - } - }, - "node_modules/vue-router": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.5.tgz", - "integrity": "sha512-4fKZygS8cH1yCyuabAXGUAsyi1b2/o/OKgu/RUb+znIYOxPRxdkytJEx+0wGcpBE1pX6vUgh5jwWOKRGvuA/7Q==", - "license": "MIT", - "dependencies": { - "@vue/devtools-api": "^6.6.4" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "vue": "^3.2.0" - } - }, - "node_modules/vue-upload-component": { - "version": "3.1.17", - "resolved": "https://registry.npmjs.org/vue-upload-component/-/vue-upload-component-3.1.17.tgz", - "integrity": "sha512-1orTC5apoFzBz4ku2HAydpviaAOck+ABc83rGypIK/Bgl+TqhtoWsQOhXqbb7vDv7pKlvRVWwml9PM224HyhkA==" - }, - "node_modules/vue3-apexcharts": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/vue3-apexcharts/-/vue3-apexcharts-1.6.0.tgz", - "integrity": "sha512-gemKFXpw4TuVcllwyKJGYjTwiJQxxCUwbXsiiEEZjs0zc9jvOHvreN8frXz7QbnYqMqOHF9D1TBqwENvoPNjLw==", - "license": "MIT", - "peerDependencies": { - "apexcharts": "> 3.0.0", - "vue": "> 3.0.0" - } - }, - "node_modules/vue3-tabs": { - "version": "0.1.13-beta.3", - "resolved": "https://registry.npmjs.org/vue3-tabs/-/vue3-tabs-0.1.13-beta.3.tgz", - "integrity": "sha512-tWIQ9lG8sTkk7o91nsdQv1/0hgQaKv/AMDFlV3tAreYYAGI1stkH5KtEiEWqtZsi6dVIVOGiGsi7+Um6dWUQ3Q==" - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/windicss": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/windicss/-/windicss-3.5.6.tgz", - "integrity": "sha512-P1mzPEjgFMZLX0ZqfFht4fhV/FX8DTG7ERG1fBLiWvd34pTLVReS5CVsewKn9PApSgXnVfPWwvq+qUsRwpnwFA==", - "dev": true, - "bin": { - "windicss": "cli/index.js" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/xmlcreate": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", - "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", - "dev": true - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zhead": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/zhead/-/zhead-2.1.1.tgz", - "integrity": "sha512-FRmjAFioi07R+bmL+fqbkXF/pCbC9PwcKQ8RDluC5xTaVbNBgYRQ4eKuS1C8c7Sil//UIxet/AGp7D6royoHhA==", - "funding": { - "url": "https://github.com/sponsors/harlan-zw" - } - } - } -} diff --git a/reposilite-frontend/package.json b/reposilite-frontend/package.json deleted file mode 100644 index a56f2da75..000000000 --- a/reposilite-frontend/package.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "reposilite-frontend", - "version": "3.4.7", - "repository": "https://github.com/dzikoysk/reposilite", - "license": "Apache-2.0", - "type": "module", - "scripts": { - "dev": "vite", - "eslint": "eslint \"src/**\"", - "build": "vite build", - "serve": "vite preview", - "fake-api": "nodemon fake-api/fake-reposilite-backend.js", - "full": "concurrently -k \"npm run fake-api\" \"vite\"" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=9.5.0" - }, - "dependencies": { - "@dzikoysk/vue-vanilla": "^3.1.0", - "@jsonforms/core": "^3.1.0", - "@jsonforms/vue": "^3.1.0", - "@vueform/toggle": "^2.1.4", - "@vueuse/core": "^11.1.0", - "@vueuse/head": "^2.0.0", - "ansi-to-html": "^0.7.2", - "apexcharts": "^3.54.0", - "axios": "^1.7.7", - "downloadjs": "^1.4.7", - "extended-eventsource": "^1.7.0", - "mime-types": "^2.1.35", - "mosha-vue-toastify": "^1.0.23", - "pretty-bytes": "^6.1.1", - "vue": "^3.5.11", - "vue-axios": "^3.5.2", - "vue-final-modal": "^4.5.5", - "vue-float-menu": "^1.9.1", - "vue-router": "^4.4.5", - "vue-upload-component": "^3.1.17", - "vue3-apexcharts": "^1.6.0", - "vue3-tabs": "^0.1.13-beta.3" - }, - "devDependencies": { - "@vitejs/plugin-vue": "^5.1.4", - "@vitejs/plugin-vue-jsx": "^4.0.1", - "@vue/compiler-sfc": "^3.5.11", - "body-parser": "^1.20.3", - "concurrently": "^9.0.1", - "eslint": "9.12.0", - "eslint-plugin-vue": "^9.28.0", - "express": "^4.21.0", - "express-ws": "^5.0.2", - "globals": "^15.10.0", - "jsdoc": "^4.0.3", - "json-server": "^0.17.4", - "nodemon": "^3.1.7", - "rollup-plugin-visualizer": "^5.12.0", - "vite": "^5.4.8", - "vite-plugin-windicss": "^1.9.3", - "windicss": "^3.5.6", - "ws": "^8.18.0" - } -} diff --git a/reposilite-frontend/src/App.vue b/reposilite-frontend/src/App.vue deleted file mode 100644 index d332cca7c..000000000 --- a/reposilite-frontend/src/App.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - diff --git a/reposilite-frontend/src/components/browser/AdjustmentsModal.vue b/reposilite-frontend/src/components/browser/AdjustmentsModal.vue deleted file mode 100644 index 4735a5022..000000000 --- a/reposilite-frontend/src/components/browser/AdjustmentsModal.vue +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - diff --git a/reposilite-frontend/src/components/browser/BreadcrumbNavigation.vue b/reposilite-frontend/src/components/browser/BreadcrumbNavigation.vue deleted file mode 100644 index a77826823..000000000 --- a/reposilite-frontend/src/components/browser/BreadcrumbNavigation.vue +++ /dev/null @@ -1,54 +0,0 @@ - - - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/browser/DeleteEntryModal.vue b/reposilite-frontend/src/components/browser/DeleteEntryModal.vue deleted file mode 100644 index 6e411867f..000000000 --- a/reposilite-frontend/src/components/browser/DeleteEntryModal.vue +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - diff --git a/reposilite-frontend/src/components/browser/DetailedListEntry.vue b/reposilite-frontend/src/components/browser/DetailedListEntry.vue deleted file mode 100644 index 1933a4278..000000000 --- a/reposilite-frontend/src/components/browser/DetailedListEntry.vue +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/browser/FileBrowserView.vue b/reposilite-frontend/src/components/browser/FileBrowserView.vue deleted file mode 100644 index 5b6c0c580..000000000 --- a/reposilite-frontend/src/components/browser/FileBrowserView.vue +++ /dev/null @@ -1,160 +0,0 @@ - - - - - diff --git a/reposilite-frontend/src/components/browser/FileList.vue b/reposilite-frontend/src/components/browser/FileList.vue deleted file mode 100644 index cf3098e88..000000000 --- a/reposilite-frontend/src/components/browser/FileList.vue +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - diff --git a/reposilite-frontend/src/components/browser/FileUpload.vue b/reposilite-frontend/src/components/browser/FileUpload.vue deleted file mode 100644 index e1931de50..000000000 --- a/reposilite-frontend/src/components/browser/FileUpload.vue +++ /dev/null @@ -1,209 +0,0 @@ - - - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/card/ArtifactSnippet.vue b/reposilite-frontend/src/components/card/ArtifactSnippet.vue deleted file mode 100644 index 1c2b0bcf0..000000000 --- a/reposilite-frontend/src/components/card/ArtifactSnippet.vue +++ /dev/null @@ -1,57 +0,0 @@ - - - - - diff --git a/reposilite-frontend/src/components/card/CardMenu.vue b/reposilite-frontend/src/components/card/CardMenu.vue deleted file mode 100644 index 0d4134ed1..000000000 --- a/reposilite-frontend/src/components/card/CardMenu.vue +++ /dev/null @@ -1,80 +0,0 @@ - - - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/card/CodeBrackets.vue b/reposilite-frontend/src/components/card/CodeBrackets.vue deleted file mode 100644 index 2f0bef33e..000000000 --- a/reposilite-frontend/src/components/card/CodeBrackets.vue +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/card/CodeString.vue b/reposilite-frontend/src/components/card/CodeString.vue deleted file mode 100644 index 53ec6900a..000000000 --- a/reposilite-frontend/src/components/card/CodeString.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/card/RepositorySnippet.vue b/reposilite-frontend/src/components/card/RepositorySnippet.vue deleted file mode 100644 index cd7a165bd..000000000 --- a/reposilite-frontend/src/components/card/RepositorySnippet.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - - - diff --git a/reposilite-frontend/src/components/card/SnippetsCard.vue b/reposilite-frontend/src/components/card/SnippetsCard.vue deleted file mode 100644 index f15229029..000000000 --- a/reposilite-frontend/src/components/card/SnippetsCard.vue +++ /dev/null @@ -1,196 +0,0 @@ - - - - - - - diff --git a/reposilite-frontend/src/components/card/XmlTag.vue b/reposilite-frontend/src/components/card/XmlTag.vue deleted file mode 100644 index b35d953f2..000000000 --- a/reposilite-frontend/src/components/card/XmlTag.vue +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/console/ConsoleView.vue b/reposilite-frontend/src/components/console/ConsoleView.vue deleted file mode 100644 index a40209ffb..000000000 --- a/reposilite-frontend/src/components/console/ConsoleView.vue +++ /dev/null @@ -1,114 +0,0 @@ - - - - - diff --git a/reposilite-frontend/src/components/dashboard/DashboardBox.vue b/reposilite-frontend/src/components/dashboard/DashboardBox.vue deleted file mode 100644 index 1ee6a0de5..000000000 --- a/reposilite-frontend/src/components/dashboard/DashboardBox.vue +++ /dev/null @@ -1,31 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/dashboard/DashboardView.vue b/reposilite-frontend/src/components/dashboard/DashboardView.vue deleted file mode 100644 index 34361bc78..000000000 --- a/reposilite-frontend/src/components/dashboard/DashboardView.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/dashboard/InstanceStatusCharts.vue b/reposilite-frontend/src/components/dashboard/InstanceStatusCharts.vue deleted file mode 100644 index 0b22e2501..000000000 --- a/reposilite-frontend/src/components/dashboard/InstanceStatusCharts.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/dashboard/ResolvedRequestsChart.vue b/reposilite-frontend/src/components/dashboard/ResolvedRequestsChart.vue deleted file mode 100644 index 4f2aa8655..000000000 --- a/reposilite-frontend/src/components/dashboard/ResolvedRequestsChart.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/dashboard/StatusSnapshotsChart.vue b/reposilite-frontend/src/components/dashboard/StatusSnapshotsChart.vue deleted file mode 100644 index a3c8a4b34..000000000 --- a/reposilite-frontend/src/components/dashboard/StatusSnapshotsChart.vue +++ /dev/null @@ -1,95 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/header/DefaultHeader.vue b/reposilite-frontend/src/components/header/DefaultHeader.vue deleted file mode 100644 index bda8919c1..000000000 --- a/reposilite-frontend/src/components/header/DefaultHeader.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/header/HeaderHero.vue b/reposilite-frontend/src/components/header/HeaderHero.vue deleted file mode 100644 index 1f5674035..000000000 --- a/reposilite-frontend/src/components/header/HeaderHero.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - - - diff --git a/reposilite-frontend/src/components/header/LoginModal.vue b/reposilite-frontend/src/components/header/LoginModal.vue deleted file mode 100644 index d1a534db4..000000000 --- a/reposilite-frontend/src/components/header/LoginModal.vue +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/header/MenuButton.vue b/reposilite-frontend/src/components/header/MenuButton.vue deleted file mode 100644 index 239aabfa9..000000000 --- a/reposilite-frontend/src/components/header/MenuButton.vue +++ /dev/null @@ -1,21 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/header/MenuPanel.vue b/reposilite-frontend/src/components/header/MenuPanel.vue deleted file mode 100644 index 41419f47c..000000000 --- a/reposilite-frontend/src/components/header/MenuPanel.vue +++ /dev/null @@ -1,74 +0,0 @@ - - - - - diff --git a/reposilite-frontend/src/components/icons/AdjustmentsIcon.vue b/reposilite-frontend/src/components/icons/AdjustmentsIcon.vue deleted file mode 100644 index 4592113ae..000000000 --- a/reposilite-frontend/src/components/icons/AdjustmentsIcon.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/icons/CloseIcon.vue b/reposilite-frontend/src/components/icons/CloseIcon.vue deleted file mode 100644 index a21ed99cb..000000000 --- a/reposilite-frontend/src/components/icons/CloseIcon.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/icons/CopyIcon.vue b/reposilite-frontend/src/components/icons/CopyIcon.vue deleted file mode 100644 index d93f043b7..000000000 --- a/reposilite-frontend/src/components/icons/CopyIcon.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - diff --git a/reposilite-frontend/src/components/icons/DownIcon.vue b/reposilite-frontend/src/components/icons/DownIcon.vue deleted file mode 100644 index 807cc306b..000000000 --- a/reposilite-frontend/src/components/icons/DownIcon.vue +++ /dev/null @@ -1,30 +0,0 @@ - - - diff --git a/reposilite-frontend/src/components/icons/EyeIcon.vue b/reposilite-frontend/src/components/icons/EyeIcon.vue deleted file mode 100644 index 8dcd9ba87..000000000 --- a/reposilite-frontend/src/components/icons/EyeIcon.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/icons/GlobeIcon.vue b/reposilite-frontend/src/components/icons/GlobeIcon.vue deleted file mode 100644 index ae534c7f1..000000000 --- a/reposilite-frontend/src/components/icons/GlobeIcon.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/icons/HashtagIcon.vue b/reposilite-frontend/src/components/icons/HashtagIcon.vue deleted file mode 100644 index fab4064b6..000000000 --- a/reposilite-frontend/src/components/icons/HashtagIcon.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/icons/JavaDocsIcon.vue b/reposilite-frontend/src/components/icons/JavaDocsIcon.vue deleted file mode 100644 index b8927ea89..000000000 --- a/reposilite-frontend/src/components/icons/JavaDocsIcon.vue +++ /dev/null @@ -1,34 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/icons/LinkIcon.vue b/reposilite-frontend/src/components/icons/LinkIcon.vue deleted file mode 100644 index 203c55162..000000000 --- a/reposilite-frontend/src/components/icons/LinkIcon.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - diff --git a/reposilite-frontend/src/components/icons/LogoutIcon.vue b/reposilite-frontend/src/components/icons/LogoutIcon.vue deleted file mode 100644 index 356abf20c..000000000 --- a/reposilite-frontend/src/components/icons/LogoutIcon.vue +++ /dev/null @@ -1,29 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/icons/MoonIcon.vue b/reposilite-frontend/src/components/icons/MoonIcon.vue deleted file mode 100644 index ad8b36a1a..000000000 --- a/reposilite-frontend/src/components/icons/MoonIcon.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/icons/SortDescending.vue b/reposilite-frontend/src/components/icons/SortDescending.vue deleted file mode 100644 index 11e76cf79..000000000 --- a/reposilite-frontend/src/components/icons/SortDescending.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/icons/SunIcon.vue b/reposilite-frontend/src/components/icons/SunIcon.vue deleted file mode 100644 index ecb676716..000000000 --- a/reposilite-frontend/src/components/icons/SunIcon.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/icons/TrashIcon.vue b/reposilite-frontend/src/components/icons/TrashIcon.vue deleted file mode 100644 index 2b40310d2..000000000 --- a/reposilite-frontend/src/components/icons/TrashIcon.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/icons/ViewGrid.vue b/reposilite-frontend/src/components/icons/ViewGrid.vue deleted file mode 100644 index 09cc8619c..000000000 --- a/reposilite-frontend/src/components/icons/ViewGrid.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - diff --git a/reposilite-frontend/src/components/icons/ViewList.vue b/reposilite-frontend/src/components/icons/ViewList.vue deleted file mode 100644 index f2ab15716..000000000 --- a/reposilite-frontend/src/components/icons/ViewList.vue +++ /dev/null @@ -1,33 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/renderers/AllOfRenderer.vue b/reposilite-frontend/src/components/renderers/AllOfRenderer.vue deleted file mode 100644 index b06222aac..000000000 --- a/reposilite-frontend/src/components/renderers/AllOfRenderer.vue +++ /dev/null @@ -1,62 +0,0 @@ - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/renderers/ArrayListElement.vue b/reposilite-frontend/src/components/renderers/ArrayListElement.vue deleted file mode 100644 index cedea9d21..000000000 --- a/reposilite-frontend/src/components/renderers/ArrayListElement.vue +++ /dev/null @@ -1,113 +0,0 @@ - - - diff --git a/reposilite-frontend/src/components/renderers/ArrayListRenderer.vue b/reposilite-frontend/src/components/renderers/ArrayListRenderer.vue deleted file mode 100644 index b68ae0a11..000000000 --- a/reposilite-frontend/src/components/renderers/ArrayListRenderer.vue +++ /dev/null @@ -1,178 +0,0 @@ - - - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/renderers/ConstantRenderer.vue b/reposilite-frontend/src/components/renderers/ConstantRenderer.vue deleted file mode 100644 index 6e2333831..000000000 --- a/reposilite-frontend/src/components/renderers/ConstantRenderer.vue +++ /dev/null @@ -1,40 +0,0 @@ - - - - - diff --git a/reposilite-frontend/src/components/renderers/ObjectRenderer.vue b/reposilite-frontend/src/components/renderers/ObjectRenderer.vue deleted file mode 100644 index becf54d24..000000000 --- a/reposilite-frontend/src/components/renderers/ObjectRenderer.vue +++ /dev/null @@ -1,70 +0,0 @@ - - - - - diff --git a/reposilite-frontend/src/components/renderers/OneOfRenderer.vue b/reposilite-frontend/src/components/renderers/OneOfRenderer.vue deleted file mode 100644 index 106a7429d..000000000 --- a/reposilite-frontend/src/components/renderers/OneOfRenderer.vue +++ /dev/null @@ -1,182 +0,0 @@ - - - - - diff --git a/reposilite-frontend/src/components/renderers/OptionalRenderer.vue b/reposilite-frontend/src/components/renderers/OptionalRenderer.vue deleted file mode 100644 index e58ed9a77..000000000 --- a/reposilite-frontend/src/components/renderers/OptionalRenderer.vue +++ /dev/null @@ -1,73 +0,0 @@ - - - - - diff --git a/reposilite-frontend/src/components/renderers/util.js b/reposilite-frontend/src/components/renderers/util.js deleted file mode 100644 index d17ca527e..000000000 --- a/reposilite-frontend/src/components/renderers/util.js +++ /dev/null @@ -1,12 +0,0 @@ -import {inject, provide} from 'vue' - -export const useNested = (element) => { - const nestedInfo = inject('jsonforms.nestedInfo', { level: 0 }) - if (element) { - provide('jsonforms.nestedInfo', { - level: nestedInfo.level + 1, - parentElement: element, - }) - } - return nestedInfo -} diff --git a/reposilite-frontend/src/components/settings/FactoryResetModal.vue b/reposilite-frontend/src/components/settings/FactoryResetModal.vue deleted file mode 100644 index 3b8ce795f..000000000 --- a/reposilite-frontend/src/components/settings/FactoryResetModal.vue +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/reposilite-frontend/src/components/settings/SettingsView.vue b/reposilite-frontend/src/components/settings/SettingsView.vue deleted file mode 100644 index a15888329..000000000 --- a/reposilite-frontend/src/components/settings/SettingsView.vue +++ /dev/null @@ -1,295 +0,0 @@ - - - - - - - - - - - diff --git a/reposilite-frontend/src/components/util/DialogWrapper.vue b/reposilite-frontend/src/components/util/DialogWrapper.vue deleted file mode 100644 index 7832a17de..000000000 --- a/reposilite-frontend/src/components/util/DialogWrapper.vue +++ /dev/null @@ -1,41 +0,0 @@ - - - diff --git a/reposilite-frontend/src/helpers/toast.js b/reposilite-frontend/src/helpers/toast.js deleted file mode 100644 index 8a7091d14..000000000 --- a/reposilite-frontend/src/helpers/toast.js +++ /dev/null @@ -1,16 +0,0 @@ -import { createToast } from 'mosha-vue-toastify' - -const createInfoToast = (message) => - createToast(message, { type: 'info' }) - -const createSuccessToast = (message) => - createToast(message, { type: 'success' }) - -const createErrorToast = (message) => - createToast(message, { type: 'danger' }) - -export { - createInfoToast, - createSuccessToast, - createErrorToast -} \ No newline at end of file diff --git a/reposilite-frontend/src/helpers/vue-extensions.js b/reposilite-frontend/src/helpers/vue-extensions.js deleted file mode 100644 index 7cfaabd27..000000000 --- a/reposilite-frontend/src/helpers/vue-extensions.js +++ /dev/null @@ -1,6 +0,0 @@ -const property = (type, required) => - ({ type, required }) - -export { - property -} diff --git a/reposilite-frontend/src/main.js b/reposilite-frontend/src/main.js deleted file mode 100644 index 02c7a1797..000000000 --- a/reposilite-frontend/src/main.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createApp } from 'vue' -import { createHead } from '@vueuse/head' -import axios from 'axios' -import VueAxios from 'vue-axios' -import Tabs from 'vue3-tabs' -import App from './App.vue' -import router from './router' - -import 'virtual:windi.css' -import 'mosha-vue-toastify/dist/style.css' -import 'vue-final-modal/style.css' - -const app = createApp(App) - -// app.config.globalProperties.append = (path, pathToAppend) => - // path + (path.endsWith('/') ? '' : '/') + pathToAppend - -app.config.globalProperties.drop = (path) => - (path.endsWith('/') ? path.slice(0, -1) : path).split("/") - .slice(0, -1) - .join('/') - -app - .use(createHead()) - .use(VueAxios, axios) - .use(Tabs) - .use(router) - .mount('#app') diff --git a/reposilite-frontend/src/pages/IndexPage.vue b/reposilite-frontend/src/pages/IndexPage.vue deleted file mode 100644 index e968e6d5a..000000000 --- a/reposilite-frontend/src/pages/IndexPage.vue +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - diff --git a/reposilite-frontend/src/router.js b/reposilite-frontend/src/router.js deleted file mode 100644 index 376f61ffd..000000000 --- a/reposilite-frontend/src/router.js +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { createWebHashHistory, createRouter } from "vue-router" -import IndexPage from "./pages/IndexPage.vue" - -const router = createRouter({ - history: createWebHashHistory(), - routes: [ - { - path: "/:qualifier(.*)", - name: "Index", - component: IndexPage, - } - ] -}) - -export default router \ No newline at end of file diff --git a/reposilite-frontend/src/store/adjustments.js b/reposilite-frontend/src/store/adjustments.js deleted file mode 100644 index c366937b0..000000000 --- a/reposilite-frontend/src/store/adjustments.js +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ref, watchEffect } from 'vue' -import { createSemverComparator } from '../store/maven/semver' - -const reversedFileOrder = ref(localStorage.getItem('reversedFileOrder') === 'true') -watchEffect(() => localStorage.setItem('reversedFileOrder', reversedFileOrder.value)) - -const displayHashFiles = ref(localStorage.getItem('displayHashFiles') === 'true') -watchEffect(() => localStorage.setItem('displayHashFiles', displayHashFiles.value)) - -export function useAdjustments() { - const applyAdjustments = (files) => { - if (!displayHashFiles.value) { - files = files.filter(file => - !['.asc', '.md5', '.sha1', '.sha256', '.sha512'].some(ext => file.name.endsWith(ext)) - ) - } - - if (reversedFileOrder.value) { - const semverComparator = createSemverComparator( - true, - (a, b) => a.type === 'DIRECTORY' && b.type === 'DIRECTORY', - (file) => file.name, - ) - - files = files.sort(semverComparator) - } - - return files - } - - return { - reversedFileOrder, - displayHashFiles, - applyAdjustments - } -} \ No newline at end of file diff --git a/reposilite-frontend/src/store/client.js b/reposilite-frontend/src/store/client.js deleted file mode 100644 index 659ffb408..000000000 --- a/reposilite-frontend/src/store/client.js +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import axios from "axios" -import usePlaceholders from "./placeholders" - -const { baseUrl } = usePlaceholders() - -const createURL = (endpoint) => - baseUrl + endpoint - -const createClient = (defaultName, defaultSecret) => { - const defaultAuthorization = () => - defaultName && defaultSecret - ? authorization(defaultName, defaultSecret) - : {} - - const authorization = (name, secret) => ({ - headers: { - Authorization: `xBasic ${btoa(`${name}:${secret}`)}`, - }, - }) - - const get = (endpoint, credentials) => - axios.get(createURL(endpoint), { - ...(credentials || defaultAuthorization()), - }) - - return { - auth: { - me() { - return get("/api/auth/me") - }, - }, - console: { - execute(command) { - return axios.post( - createURL(`/api/console/execute`), command, { - headers: { - ...defaultAuthorization().headers, - } - } - ) - } - }, - status: { - instance() { - return get("/api/status/instance") - }, - snapshots() { - return get("/api/status/snapshots") - } - }, - statistics: { - allResolved() { - return get("/api/statistics/resolved/all") - } - }, - maven: { - content(gav) { - return get(`/${gav}`) - }, - details(gav) { - return get(`/api/maven/details/${gav || ""}`) - }, - download(gav) { - return get(`/${gav}`, { - responseType: "blob", - ...defaultAuthorization(), - }) - }, - deploy(gav, file, generateChecksums) { - return axios.put(createURL(`/${gav}`), file, { - headers: { - "Content-Type": "application/octet-stream", - "X-Generate-Checksums": generateChecksums, - ...defaultAuthorization().headers, - } - }) - }, - generatePom(gav, groupId, artifactId, version) { - return axios.post( - createURL(`/api/maven/generate/pom/${gav}/${artifactId}-${version}.pom`), - { - groupId, - artifactId, - version - }, { - headers: { - "Content-Type": "application/json", - ...defaultAuthorization().headers, - } - } - ) - }, - delete(gav) { - return axios.delete(createURL(`/${gav}`), { - ...defaultAuthorization(), - }) - } - }, - settings: { - domains() { - return axios.get(createURL("/api/settings/domains"), { - headers: { - Accepts: "application/json", - ...defaultAuthorization().headers, - }, - }) - }, - schema(name) { - return axios.get(createURL(`/api/settings/schema/${name}`), { - headers: { - Accepts: "application/json", - ...defaultAuthorization().headers, - }, - }) - }, - fetch(name) { - return axios.get(createURL(`/api/settings/domain/${name}`), { - headers: { - Accepts: "application/json", - ...defaultAuthorization().headers, - }, - }) - }, - update(name, content) { - return axios.put(createURL(`/api/settings/domain/${name}`), content, { - headers: { - "Content-Type": "application/json", - Accepts: "application/json", - ...defaultAuthorization().headers, - }, - }) - }, - }, - } -} - -export { - createURL, - createClient -} diff --git a/reposilite-frontend/src/store/configuration.js b/reposilite-frontend/src/store/configuration.js deleted file mode 100644 index f5735345d..000000000 --- a/reposilite-frontend/src/store/configuration.js +++ /dev/null @@ -1,93 +0,0 @@ -import {computed, markRaw, ref, toRaw} from 'vue' -import { useSession } from './session' -import { createToast } from 'mosha-vue-toastify' -import { createAjv } from '@jsonforms/core' -import { vanillaRenderers } from '@dzikoysk/vue-vanilla' -import { default as ObjectRenderer, tester as objectTester } from '../components/renderers/ObjectRenderer.vue' -import { default as AllOfRenderer, tester as allOfTester } from '../components/renderers/AllOfRenderer.vue' -import { default as ArrayListRenderer, tester as arrayListTester } from '../components/renderers/ArrayListRenderer.vue' -import { default as OneOfRenderer, tester as oneOfTester } from '../components/renderers/OneOfRenderer.vue' -import { default as ConstantRenderer, tester as constantTester } from '../components/renderers/ConstantRenderer.vue' -import { default as OptionalRenderer, tester as optionalTester } from '../components/renderers/OptionalRenderer.vue' - -const { client } = useSession() -const domains = ref([]) -const schemas = ref({}) -const configurations = ref({}) -const selectedDomain = ref('') - -const fetchConfiguration = () => { - return client.value.settings.domains() - .then(domainsResponse => domains.value = domainsResponse.data) - .then(() => Promise.all(domains.value.map(domain => - client.value.settings.schema(domain) - .then(schemaResponse => schemas.value[domain] = schemaResponse.data) - .then(() => client.value.settings.fetch(domain)) - .then(configurationResponse => configurations.value[domain] = configurationResponse.data))) - ) - .then(() => selectedDomain.value = domains.value[0]) - .then(() => createToast('Configuration loaded', { type: 'success' })) - .catch(error => createToast(`${error || ''}`, { type: 'danger' })) -} - -const updateConfiguration = () => { - const updates = domains.value.map(domain => { - client.value.settings.update(domain, toRaw(configurations.value[domain])) - .then(() => client.value.settings.fetch(domain)) - .then(response => { configurations[domain] = response.data }) - }) - - return Promise.all(updates) - .then(() => createToast('Configuration updated', { type: 'success' })) - .catch(error => createToast(`Failed to update ${error.join(', ')}`, { type: 'danger' })) -} - -const renderers = markRaw([ - { tester: arrayListTester, renderer: ArrayListRenderer }, - { tester: allOfTester, renderer: AllOfRenderer }, - { tester: oneOfTester, renderer: OneOfRenderer }, - { tester: constantTester, renderer: ConstantRenderer }, - { tester: optionalTester, renderer: OptionalRenderer }, - { - // needed because without it hangs TODO find out why - tester: (uischema, schema) => { - let rank = objectTester(uischema, schema) - return rank === -1 || schema.title === 'Proxied Maven Repository' ? -1 : rank - }, - renderer: ObjectRenderer - }, - ...vanillaRenderers, -]) - -const configurationValidator = computed(() => { - const ajv = createAjv({ - useDefaults: true, - removeAdditional: false, - formats: { - 'repositories.storageProvider.quota': /^([1-9]\d*)([KkMmGg][Bb]|%)$/, - 'repositories.id': { - type: 'string', - validate: (name) => name in configurations.value['maven'].repositories || name.startsWith(' ') || name.endsWith(' ') - }, - 'repositories.proxied.allowedGroups': /^(\w+\.)*\w+$/, - } - }) - ajv.addFormat("repositories.id", { - type: "string", - validate: (value) => !value.endsWith(' ') - }) - return ajv -}) - -export function useConfiguration() { - return { - fetchConfiguration, - updateConfiguration, - renderers, - configurationValidator, - domains, - configurations, - schemas, - selectedDomain - } -} \ No newline at end of file diff --git a/reposilite-frontend/src/store/console/connection.js b/reposilite-frontend/src/store/console/connection.js deleted file mode 100644 index 297b2af42..000000000 --- a/reposilite-frontend/src/store/console/connection.js +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ref } from "vue" -import { createURL } from '../client' -import { EventSource as Eventsource } from 'extended-eventsource'; -import { useSession } from "../session.js"; - -const { client } = useSession() - -const connection = ref() -const command = ref("") - -export default function useConsole() { - const consoleAddress = createURL("/api/console/log"); - - const isConnected = () => { - // using built-in EventSource for readystate constants - // the ones from extended-eventsource return undefined for some reason - return connection.value?.readyState === EventSource.OPEN - } - - const close = () => { - if (isConnected()) - connection.value.close() - } - - const history = ref(['']) - const historyIdx = ref(0) - - const addCommandToHistory = (command) => { - if (history.value[history.value.length - 1] == '') - history.value.pop() - history.value.push(command) - historyIdx.value = history.value.length - 1 - } - - const execute = () => { - addCommandToHistory(command.value) - client.value.console.execute(command.value) - command.value = '' - } - - const previousCommand = () => - traverseHistory(-1) - - const nextCommand = () => - traverseHistory(1) - - const traverseHistory = (direction) => { - const currentCommand = command.value - const commands = history.value - const lastCommandIdx = commands.length - 1 - - if (lastCommandIdx === historyIdx.value && commands[lastCommandIdx] !== currentCommand) - addCommandToHistory(currentCommand) - - historyIdx.value = Math.max(0, Math.min(commands.length - 1, historyIdx.value + direction)) - command.value = history.value[historyIdx.value] - } - - const onOpen = ref() - const onMessage = ref() - const onError = ref() - const onClose = ref() - - const connect = (token) => { - try { - connection.value = new Eventsource(consoleAddress, { - headers: { - Authorization: `xBasic ${btoa(`${token.name}:${token.secret}`)}` - }, - disableRetry: true - }) - - connection.value.onopen = () => { - // this is needed to stop an error from appearing in console when - // switching/refreshing the page without closing the connection - window.onbeforeunload = function () { - close(); - }; - - onOpen?.value() - } - - connection.value.addEventListener("log", (event) => { - if (!event.data.toString().includes("GET /api/status/instance from")) - onMessage?.value(event.data) - }) - - connection.value.onerror = (error) => { - onError?.value(error) - } - - connection.value.onclose = () => - onClose?.value() - - } catch (error) { - onError?.value(error) - } - } - - return { - connection, - connect, - close, - onOpen, - onMessage, - onError, - onClose, - command, - execute, - previousCommand, - nextCommand, - isConnected - } -} diff --git a/reposilite-frontend/src/store/console/log.js b/reposilite-frontend/src/store/console/log.js deleted file mode 100644 index 893a80de4..000000000 --- a/reposilite-frontend/src/store/console/log.js +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { computed, ref, reactive } from 'vue' -import Convert from 'ansi-to-html' - -const levelNames = ['Other', 'Trace', 'Debug', 'Info', 'Warn', 'Error'] -const levels = reactive({}) -const filter = ref('') -const id = ref(0) -const rawLog = reactive([]) -const convert = new Convert() - -const getLevel = message => - levelNames.find(level => message.includes(`${level.toUpperCase()} | `)) ?? 'Other' - -const sanitizeMessage = (message) => convert.toHtml( - message - .replaceAll('<', '<') - .replaceAll('>', '>') - .replaceAll(' ', ' ') -) - -export default function useLog() { - levelNames.forEach(level => { - levels[level] = { - name: level, - enabled: true, - count: computed(() => rawLog.reduce((accumulator, entry) => accumulator + (entry.level === level), 0)) - } - }) - - const log = computed(() => { - return rawLog - .filter(entry => entry.message.toLowerCase().includes(filter.value.toLowerCase())) - .filter(entry => levels[entry.level].enabled) - }) - - const logMessage = value => { - rawLog.push({ id: id.value++, message: sanitizeMessage(value), level: getLevel(value) }) - } - - const clearLog = () => { - rawLog.length = 0 - } - - return { - levels, - log, - filter, - sanitizeMessage, - logMessage, - clearLog - } -} diff --git a/reposilite-frontend/src/store/maven/metadata.js b/reposilite-frontend/src/store/maven/metadata.js deleted file mode 100644 index b9d914b0c..000000000 --- a/reposilite-frontend/src/store/maven/metadata.js +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -const parser = new DOMParser() - -export default function useMetadata() { - const groupId = (metadata) => - metadata - ?.getElementsByTagName('groupId')[0] - ?.firstChild - ?.nodeValue - - const artifactId = (metadata) => - metadata - ?.getElementsByTagName('artifactId')[0] - ?.firstChild - ?.nodeValue - - const versions = (metadata) => { - return [...metadata.querySelector('versioning versions').children] - ?.map(node => node.firstChild.nodeValue) - ?? ['{unknown}'] - } - - const parseMetadata = (source) => { - const metadata = parser.parseFromString(source, 'text/xml') - const availableVersions = versions(metadata) - - return { - metadata, - groupId: groupId(metadata), - artifactId: artifactId(metadata), - versions: availableVersions - } - } - - return { - parseMetadata, - groupId, - artifactId, - versions - } -} \ No newline at end of file diff --git a/reposilite-frontend/src/store/maven/repository.js b/reposilite-frontend/src/store/maven/repository.js deleted file mode 100644 index 528305ce3..000000000 --- a/reposilite-frontend/src/store/maven/repository.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { computed } from "vue" -import usePlaceholders from "../../store/placeholders" - -export default function useRepository() { - const { basePath, id, title } = usePlaceholders() - - const createRepositories = (qualifier) => { - const repository = computed(() => qualifier.path.split("/")[0]) - const repoId = id + (qualifier.path ? `-${repository.value}` : "") - const domain = - location.protocol + - "//" + - location.host + - basePath + - (basePath.endsWith("/") ? "" : "/") + - (qualifier.path ? `${repository.value}` : "") - - return { type: "repository", repoId, title, domain } - } - - return { - createRepositories - } -} diff --git a/reposilite-frontend/src/store/maven/semver.js b/reposilite-frontend/src/store/maven/semver.js deleted file mode 100644 index dacecdaa2..000000000 --- a/reposilite-frontend/src/store/maven/semver.js +++ /dev/null @@ -1,33 +0,0 @@ -const createSemverComparator = (reversed, filter, toSemver) => { - // Semver sorting - // ~ https://github.com/substack/semver-compare/issues/1#issuecomment-594765531 - const compare = (rawA, rawB) => { - const a = rawA.split('-') - const b = rawB.split('-') - const pa = a[0].split('.') - const pb = b[0].split('.') - - for (let idx = 0; idx < 3; idx++) { - const na = Number(pa[idx]) - const nb = Number(pb[idx]) - if (na > nb) return 1 - if (nb > na) return -1 - if (!isNaN(na) && isNaN(nb)) return 1 - if (isNaN(na) && !isNaN(nb)) return -1 - } - if (a[1] && b[1]) { - return a[1] > b[1] ? 1 : (a[1] < b[1] ? -1 : 0) - } - return !a[1] && b[1] ? 1 : (a[1] && !b[1] ? -1 : 0) - } - - return (a, b) => { - if (!filter(a, b)) return 0 - const result = compare(toSemver(a), toSemver(b)) - return reversed ? -result : result - } -} - -export { - createSemverComparator -} \ No newline at end of file diff --git a/reposilite-frontend/src/store/placeholders.js b/reposilite-frontend/src/store/placeholders.js deleted file mode 100644 index abbc098a2..000000000 --- a/reposilite-frontend/src/store/placeholders.js +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export default function usePlaceholders() { - const available = !'{{REPOSILITE.BASE_PATH}}'.includes('REPOSILITE.BASE_PATH') - const basePath = available ? '{{REPOSILITE.BASE_PATH}}' : '/' - const id = available ? '{{REPOSILITE.ID}}' : 'reposilite-repository' - const title = available ? '{{REPOSILITE.TITLE}}' : 'Reposilite Repository' - const description = available ? '{{REPOSILITE.DESCRIPTION}}' : 'Public Maven repository hosted through the Reposilite' - const organizationWebsite = available ? '{{REPOSILITE.ORGANIZATION_WEBSITE}}' : location.protocol + '//' + location.host + basePath - const organizationLogo = available ? '{{REPOSILITE.ORGANIZATION_LOGO}}' : 'https://avatars.githubusercontent.com/u/75123628?s=200&v=4' - const icpLicense = available ? '{{REPOSILITE.ICP_LICENSE}}' : '国ICP备000000000号' - - const productionUrl = - window.location.protocol + '//' + location.host + basePath - - const baseUrl = - process.env.NODE_ENV === 'production' - ? (productionUrl.endsWith('/') ? productionUrl.slice(0, -1) : productionUrl) - : 'http://localhost:8080' - - return { - available, - basePath, - id, - title, - description, - organizationWebsite, - organizationLogo, - icpLicense, - productionUrl, - baseUrl - } -} diff --git a/reposilite-frontend/src/store/qualifier.js b/reposilite-frontend/src/store/qualifier.js deleted file mode 100644 index c3e641c2f..000000000 --- a/reposilite-frontend/src/store/qualifier.js +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { watch, reactive } from 'vue' -import { useRoute, useRouter } from 'vue-router' -import { useSession } from './session' - -const qualifier = reactive({ - watchable: 0, - path: '' -}) - -const refreshQualifier = () => - qualifier.watchable++ - -const getParentPath = () => - `/${(qualifier.path.endsWith('/') ? qualifier.path.slice(0, -1) : qualifier.path)}` - .split("/") - .slice(0, -1) - .join('/') || '/' - -const { details } = useSession() - -watch( - () => details.value, - () => refreshQualifier() -) - -export default function useQualifier() { - const route = useRoute() - const router = useRouter() - - const redirectTo = (path) => { - router.push(path) - } - - watch( - () => route.params.qualifier, - newQualifier => { - qualifier.path = newQualifier - refreshQualifier() - }, - { immediate: true } - ) - - return { - qualifier, - getParentPath, - refreshQualifier, - redirectTo - } -} \ No newline at end of file diff --git a/reposilite-frontend/src/store/session.js b/reposilite-frontend/src/store/session.js deleted file mode 100644 index 1084eb3b9..000000000 --- a/reposilite-frontend/src/store/session.js +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { computed, ref, watchEffect } from "vue" -import { createClient } from './client' - -const token = ref({ - name: localStorage.getItem('token-name') || '', - secret: localStorage.getItem('token-secret') || '', -}) -const setToken = (name, secret) => { - token.value = { name, secret } -} - -watchEffect(() => { - localStorage.setItem('token-name', token.value.name) - localStorage.setItem('token-secret', token.value.secret) -}) - -/** - * @type {(undefined|{ - * accessToken: { - * identifier: { - * type: string, - * value: number - * }, - * name: string, - * createdAt: string, - * description: string - * }, - * permissions: { - * identifier: string, - * shortcut: string - * }[], - * routes: { - * path: string, - * permission: { - * identifier: string, - * shortcut: string -* } - * }[] - * })} - */ -const defaultDetails = undefined -const details = ref(defaultDetails) - -const logout = () => { - setToken('', '') - details.value = undefined -} - -const login = (name, secret) => - createClient(name, secret) - .auth - .me() - .then(response => { - setToken(name, secret) - details.value = response.data - }) - -const client = computed(() => createClient(token.value.name, token.value.secret)) -const initializeSession = () => login(token.value.name, token.value.secret) -const isLogged = computed(() => details.value !== undefined) - -const isManager = computed(() => { - return details.value - ?.permissions - ?.some(entry => entry.identifier === 'access-token:manager') === true -}) - -const hasPermissionTo = (path, permission) => { - if (isManager.value) { - return true - } - return details.value - ?.routes - ?.find(route => path.startsWith(route.path) && route.permission.identifier === permission) !== undefined -} - -export function useSession() { - return { - token, - details, - login, - logout, - isLogged, - client, - isManager, - hasPermissionTo, - initializeSession - } -} diff --git a/reposilite-frontend/src/store/theme.js b/reposilite-frontend/src/store/theme.js deleted file mode 100644 index dbec85069..000000000 --- a/reposilite-frontend/src/store/theme.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { reactive } from 'vue' - -const theme = reactive({ - mode: 'auto', - isDark: false -}) - -const themeKey = 'theme-mode' - -export default function useTheme() { - const fetchColorMode = () => { - const storedTheme = localStorage.getItem(themeKey) ?? 'auto' - localStorage.setItem(themeKey, storedTheme) - theme.mode = storedTheme - - if (storedTheme === 'auto') { - theme.isDark = window.matchMedia("(prefers-color-scheme: dark)").matches - return - } - - theme.isDark = storedTheme === 'dark' - } - - const changeTheme = (mode) => { - localStorage.setItem(themeKey, mode) - fetchColorMode() - } - - return { - theme, - fetchColorMode, - changeTheme - } -} diff --git a/reposilite-frontend/vite.config.js b/reposilite-frontend/vite.config.js deleted file mode 100644 index d07b3d8f2..000000000 --- a/reposilite-frontend/vite.config.js +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { defineConfig } from "vite" -import vue from "@vitejs/plugin-vue" -import vueJsx from "@vitejs/plugin-vue-jsx" -import WindiCSS from "vite-plugin-windicss" -import { visualizer } from "rollup-plugin-visualizer" - -// https://vitejs.dev/config/ -export default defineConfig({ - server: { - port: 80, - }, - plugins: [ - vue({ - reactivityTransform: true, // Lack of support in ESLint rules tho - }), - vueJsx(), - WindiCSS(), - visualizer(), - ], - base: - process.env.NODE_ENV === "production" - ? "{{REPOSILITE.VITE_BASE_PATH}}" - : "/", - build: { - minify: true, - emptyOutDir: true, - outDir: "build/frontend/reposilite-frontend", - chunkSizeWarningLimit: 550 - }, - css: { - preprocessorOptions: { - css: { - charset: false, - }, - }, - postcss: { - plugins: [ - { - postcssPlugin: "internal:charset-removal", - AtRule: { - charset: (atRule) => { - if (atRule.name === "charset") { - atRule.remove() - } - }, - }, - }, - ], - }, - }, -}) diff --git a/reposilite-frontend/windi.config.js b/reposilite-frontend/windi.config.js deleted file mode 100644 index dae6a3bfc..000000000 --- a/reposilite-frontend/windi.config.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { defineConfig } from "windicss/helpers" -import colors from "windicss/colors" - -export default defineConfig({ - darkMode: "class", - plugins: [ - require('windicss/plugin/forms') - ], - theme: { - screens: { - sm: "640px", - md: "768px", - lg: "1024px", - xl: "1280px", - }, - extend: { - colors: { - gray: { - 125: "#efefef", - 150: "#ececec", - ...colors.neutral, - }, - }, - fontSize: { - xxs: ["0.45rem", { lineHeight: "0.5rem" }], - xm: ["0.625rem", { lineHeight: "0.75rem" }], - ssm: ["0.8rem", { lineHeight: "1.15rem" }], - }, - fontFamily: { - mono: ["Consolas", "Monaco", "monospace"], - } - }, - }, - shortcuts: { - "default-button": - "bg-white dark:bg-gray-900 cursor-pointer hover:(transition-color bg-gray-200 dark:bg-gray-800 duration-500)", - }, -}) - diff --git a/reposilite-plugins/migration-plugin/build.gradle.kts b/reposilite-plugins/migration-plugin/build.gradle.kts deleted file mode 100644 index eb8b6e4d4..000000000 --- a/reposilite-plugins/migration-plugin/build.gradle.kts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - -plugins { - id("com.github.johnrengelman.shadow") version "8.1.1" - kotlin("jvm") - kotlin("plugin.serialization") version "2.0.20" -} - -application { - mainClass.set("com.reposilite.plugin.migration.MigrationPlugin") -} - -dependencies { - compileOnly(project(":reposilite-backend")) - testImplementation(project(":reposilite-backend")) - implementation("com.charleskorn.kaml:kaml-jvm:0.61.0") -} - -tasks.withType { - archiveFileName.set("migration-plugin.jar") - destinationDirectory.set(file("$rootDir/reposilite-test/workspace/plugins")) - mergeServiceFiles() -} diff --git a/reposilite-plugins/migration-plugin/src/main/kotlin/com/reposilite/plugin/migration/MigrationPlugin.kt b/reposilite-plugins/migration-plugin/src/main/kotlin/com/reposilite/plugin/migration/MigrationPlugin.kt deleted file mode 100644 index 6c3b8dc28..000000000 --- a/reposilite-plugins/migration-plugin/src/main/kotlin/com/reposilite/plugin/migration/MigrationPlugin.kt +++ /dev/null @@ -1,93 +0,0 @@ -package com.reposilite.plugin.migration - -import com.charleskorn.kaml.Yaml -import com.charleskorn.kaml.decodeFromStream -import com.reposilite.maven.MavenFacade -import com.reposilite.plugin.api.Facade -import com.reposilite.plugin.api.Plugin -import com.reposilite.plugin.api.ReposilitePlugin -import com.reposilite.plugin.facade -import com.reposilite.plugin.parameters -import com.reposilite.token.AccessToken -import com.reposilite.token.AccessTokenPermission -import com.reposilite.token.ExportService -import com.reposilite.token.Route -import com.reposilite.token.RoutePermission -import com.reposilite.token.RoutePermission.READ -import com.reposilite.token.api.AccessTokenDetails -import java.nio.file.Files -import java.nio.file.Path -import kotlin.io.path.readBytes -import org.panda_lang.reposilite.auth.TokenCollection - -@Plugin(name = "migration", dependencies = ["maven"]) -class MigrationPlugin : ReposilitePlugin() { - - override fun initialize(): Facade? { - val workingDirectory = parameters().workingDirectory - val mavenFacade = facade() - - logger.warn("") - logger.warn("--- Migration") - - migrateTokens( - workingDirectory = workingDirectory, - repositories = mavenFacade.getRepositories().map { it.name } - ) - - return null - } - - fun migrateTokens(workingDirectory: Path, repositories: Collection): Collection? { - val tokensFile = workingDirectory.resolve("tokens.dat") - - if (Files.notExists(tokensFile)) { - logger.warn("Migration | 'tokens.dat' file not found in working directory, there is nothing that migration plugin can do.") - return null - } - - logger.warn("Migration | Reposilite 2.x 'tokens.dat' file found, the migration procedure has started.") - val tokenCollection = Yaml.default.decodeFromStream(TokenCollection.serializer(), tokensFile.readBytes().inputStream()) - logger.warn("Migration | ${tokenCollection.tokens.size} token(s) found in 'tokens.dat' file.") - - val migratedTokens = tokenCollection.tokens.map { token -> - val routePermissions = token.permissions - .toCharArray() - .map { shortcut -> RoutePermission.findRoutePermissionByShortcut(shortcut.toString()).orNull() } - .filterNotNull() - .toMutableSet() - .also { it.add(READ) } // default permission - - AccessTokenDetails( - accessToken = AccessToken( - name = token.alias, - encryptedSecret = token.token - ), - permissions = token.permissions - .toCharArray() - .map { shortcut -> AccessTokenPermission.findAccessTokenPermissionByShortcut(shortcut.toString()) } - .filterNotNull() - .toSet(), - routes = - if (token.path.startsWith("*")) - routePermissions - .flatMap { permission -> repositories.map { permission to it } } - .map { (permission, repository) -> Route(token.path.replace("*", "/$repository"), permission) } - .toSet() - else - routePermissions - .map { Route(token.path, it) } - .toSet() - ) - } - - val exportService = ExportService() - exportService.exportToFile(migratedTokens, workingDirectory.resolve("tokens.json")) - logger.warn("Migration | ${migratedTokens.size} token(s) have been exported to 'tokens.json' file.") - logger.warn("Migration | Run 'token-import tokens.json' command to import those tokens.") - logger.warn("Migration | This plugin is no longer needed, you can remove it.") - - return migratedTokens - } - -} \ No newline at end of file diff --git a/reposilite-plugins/migration-plugin/src/main/kotlin/org/panda_lang/reposilite/auth/TokenCollection.kt b/reposilite-plugins/migration-plugin/src/main/kotlin/org/panda_lang/reposilite/auth/TokenCollection.kt deleted file mode 100644 index d63dfb055..000000000 --- a/reposilite-plugins/migration-plugin/src/main/kotlin/org/panda_lang/reposilite/auth/TokenCollection.kt +++ /dev/null @@ -1,26 +0,0 @@ -package org.panda_lang.reposilite.auth - -import kotlinx.serialization.Serializable - -/* -class TokenCollection { - var tokens: List = emptyList() - - class Token { - var alias: String = "" - var path: String = "" - var permissions: String = "" - var token: String = "" - } -}*/ - -@Serializable -data class TokenCollection(var tokens: List) - -@Serializable -data class Token( - var alias: String = "", - var path: String = "", - var permissions: String = "", - var token: String = "" -) \ No newline at end of file diff --git a/reposilite-plugins/migration-plugin/src/main/resources/META-INF/services/com.reposilite.plugin.api.ReposilitePlugin b/reposilite-plugins/migration-plugin/src/main/resources/META-INF/services/com.reposilite.plugin.api.ReposilitePlugin deleted file mode 100644 index 60abaf2ed..000000000 --- a/reposilite-plugins/migration-plugin/src/main/resources/META-INF/services/com.reposilite.plugin.api.ReposilitePlugin +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2023 dzikoysk -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -com.reposilite.plugin.migration.MigrationPlugin \ No newline at end of file diff --git a/reposilite-plugins/migration-plugin/src/test/kotlin/com/reposilite/plugin/migration/MigrationPluginTest.kt b/reposilite-plugins/migration-plugin/src/test/kotlin/com/reposilite/plugin/migration/MigrationPluginTest.kt deleted file mode 100644 index 7df96b006..000000000 --- a/reposilite-plugins/migration-plugin/src/test/kotlin/com/reposilite/plugin/migration/MigrationPluginTest.kt +++ /dev/null @@ -1,44 +0,0 @@ -package com.reposilite.plugin.migration - -import com.reposilite.plugin.migration.specification.MigrationPluginSpecification -import com.reposilite.token.AccessTokenPermission.MANAGER -import com.reposilite.token.Route -import com.reposilite.token.RoutePermission.READ -import com.reposilite.token.RoutePermission.WRITE -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.Test -import java.nio.file.Files - -internal class MigrationPluginTest : MigrationPluginSpecification() { - - @Test - fun `should migrate old yaml scheme to the new json scheme`() { - // given: a tokens.dat file and a list of repositories - val tokensFile = workingDirectory().resolve("tokens.dat") - Files.write(tokensFile, resource(test = "should migrate old yaml scheme to the new json scheme", file = "tokens.dat").toByteArray()) - val repositories = setOf("releases", "snapshots", "private") - - // when: migration plugin will proceed migration - val tokens = migrationPlugin.migrateTokens(workingDirectory(), repositories)!! - - // then: a valid json scheme with up-to-date tokens should be generated - val schema = workingDirectory().resolve("tokens.json") - assertThat(Files.exists(schema)).isTrue - assertThat(tokens.size).isEqualTo(3) - - val privateToken = tokens.first { it.accessToken.name == "private" } - with (privateToken.routes.first()) { - assertThat(path).isEqualTo("/private") - assertThat(permission).isEqualTo(WRITE) - } - - val wildcardToken = tokens.first { it.accessToken.name == "wildcard" } - assertThat(wildcardToken.permissions).isEqualTo(setOf(MANAGER)) - assertThat(wildcardToken.routes).isEqualTo(repositories.map { Route("/$it/", READ) }.toSet()) - - val adminToken = tokens.first { it.accessToken.name == "admin" } - assertThat(adminToken.permissions).isEqualTo(setOf(MANAGER)) - assertThat(adminToken.routes).isEqualTo(setOf(Route("/", READ), Route("/", WRITE))) - } - -} \ No newline at end of file diff --git a/reposilite-plugins/migration-plugin/src/test/kotlin/com/reposilite/plugin/migration/specification/MigrationPluginSpecification.kt b/reposilite-plugins/migration-plugin/src/test/kotlin/com/reposilite/plugin/migration/specification/MigrationPluginSpecification.kt deleted file mode 100644 index 7044eecd9..000000000 --- a/reposilite-plugins/migration-plugin/src/test/kotlin/com/reposilite/plugin/migration/specification/MigrationPluginSpecification.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.reposilite.plugin.migration.specification - -import com.reposilite.journalist.backend.AggregatedLogger -import com.reposilite.journalist.backend.InMemoryLogger -import com.reposilite.journalist.backend.PrintStreamLogger -import com.reposilite.plugin.Extensions -import com.reposilite.plugin.api.ReposilitePlugin.ReposilitePluginAccessor -import com.reposilite.plugin.migration.MigrationPlugin -import org.junit.jupiter.api.io.TempDir -import java.io.File -import java.nio.file.Path - -internal open class MigrationPluginSpecification { - - @TempDir - lateinit var workingDirectory: File - - private val logger = InMemoryLogger() - private val extensions = Extensions(AggregatedLogger(logger, PrintStreamLogger(System.out, System.err))) - protected val migrationPlugin = MigrationPlugin() - - init { - ReposilitePluginAccessor.injectExtension(migrationPlugin, extensions) - } - - fun workingDirectory(): Path = - workingDirectory.toPath() - - fun resource(test: String, file: String): String = - MigrationPluginSpecification::class.java.getResourceAsStream("/$test - $file")!!.readBytes().decodeToString() - -} \ No newline at end of file diff --git a/reposilite-plugins/migration-plugin/src/test/resources/should migrate old yaml scheme to the new json scheme - tokens.dat b/reposilite-plugins/migration-plugin/src/test/resources/should migrate old yaml scheme to the new json scheme - tokens.dat deleted file mode 100644 index 65698c7c5..000000000 --- a/reposilite-plugins/migration-plugin/src/test/resources/should migrate old yaml scheme to the new json scheme - tokens.dat +++ /dev/null @@ -1,14 +0,0 @@ -!!org.panda_lang.reposilite.auth.TokenCollection -"tokens": -- "alias": "private" - "path": "/private" - "permissions": "w" - "token": "$2a$10$emGPCUwsR650EJYNrjy/tucpi2rA0O2oYTT87OYQU9bSodGlNrI.q" -- "alias": "wildcard" - "path": "*/" - "permissions": "m" - "token": "$2a$10$b2jinHwPoS.0BhwpBgj8juS9NXr3kDy5JpO8qggt3o6HakHeasl1." -- "alias": "admin" - "path": "/" - "permissions": "wm" - "token": "$2a$10$BgjbxB2Fug88kURC5F.xTeVVz2EEKvbiUNt7OnO4K5qBMZFTu39T." diff --git a/reposilite-plugins/swagger-plugin/build.gradle.kts b/reposilite-plugins/swagger-plugin/build.gradle.kts deleted file mode 100644 index 893405afa..000000000 --- a/reposilite-plugins/swagger-plugin/build.gradle.kts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2023 dzikoysk - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - -plugins { - id("com.github.johnrengelman.shadow") version "8.1.1" - kotlin("jvm") -} - -application { - mainClass.set("com.reposilite.plugin.swagger.SwaggerPluginKt") -} - -dependencies { - compileOnly(project(":reposilite-backend")) - implementation("io.javalin.community.openapi:javalin-swagger-plugin:6.3.0") -} - -tasks.withType { - archiveFileName.set("swagger-plugin.jar") - destinationDirectory.set(file("$rootDir/reposilite-test/workspace/plugins")) - mergeServiceFiles() -} \ No newline at end of file diff --git a/reposilite-plugins/swagger-plugin/src/main/kotlin/com/reposilite/plugin/swagger/SwaggerPlugin.kt b/reposilite-plugins/swagger-plugin/src/main/kotlin/com/reposilite/plugin/swagger/SwaggerPlugin.kt deleted file mode 100644 index e404ab90c..000000000 --- a/reposilite-plugins/swagger-plugin/src/main/kotlin/com/reposilite/plugin/swagger/SwaggerPlugin.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.reposilite.plugin.swagger - -import io.javalin.openapi.plugin.swagger.SwaggerPlugin as SwaggerPluginForJavalin -import com.reposilite.configuration.shared.SharedConfigurationFacade -import com.reposilite.frontend.application.FrontendSettings -import com.reposilite.plugin.api.Facade -import com.reposilite.plugin.api.Plugin -import com.reposilite.plugin.api.ReposilitePlugin -import com.reposilite.plugin.event -import com.reposilite.plugin.facade -import com.reposilite.web.api.HttpServerConfigurationEvent - -@Plugin(name = "swagger", dependencies = ["shared-configuration", "frontend"]) -class SwaggerPlugin : ReposilitePlugin() { - - override fun initialize(): Facade? { - val frontendSettings = facade().getDomainSettings() - - event { event: HttpServerConfigurationEvent -> - event.config.registerPlugin(SwaggerPluginForJavalin { swaggerConfiguration -> - swaggerConfiguration.title = frontendSettings.map { it.title } - }) - } - - return null - } - -} \ No newline at end of file diff --git a/reposilite-plugins/swagger-plugin/src/main/resources/META-INF/services/com.reposilite.plugin.api.ReposilitePlugin b/reposilite-plugins/swagger-plugin/src/main/resources/META-INF/services/com.reposilite.plugin.api.ReposilitePlugin deleted file mode 100644 index 72296a059..000000000 --- a/reposilite-plugins/swagger-plugin/src/main/resources/META-INF/services/com.reposilite.plugin.api.ReposilitePlugin +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2023 dzikoysk -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -com.reposilite.plugin.swagger.SwaggerPlugin \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index ca3b4cb66..db3e70490 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,13 +17,10 @@ rootProject.name = "reposilite-parent" include( - "reposilite-frontend", "reposilite-backend", "reposilite-plugins", "reposilite-plugins:checksum-plugin", "reposilite-plugins:example-plugin", "reposilite-plugins:groovy-plugin", - "reposilite-plugins:migration-plugin", "reposilite-plugins:prometheus-plugin", - "reposilite-plugins:swagger-plugin" )