diff --git a/.github/workflows/check-pr-template.yml b/.github/workflows/check-pr-template.yml new file mode 100644 index 0000000000000..f60498d269336 --- /dev/null +++ b/.github/workflows/check-pr-template.yml @@ -0,0 +1,80 @@ +name: Check PR Template + +on: + pull_request_target: # zizmor: ignore[dangerous-triggers] + types: [opened, edited] + +permissions: {} + +jobs: + parse: + runs-on: ubuntu-latest + if: ${{ github.event.pull_request.head.repo.fork == true }} + permissions: + contents: read + outputs: + uses_template: ${{ steps.check.outputs.uses_template }} + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + sparse-checkout: .github/pull_request_template.md + sparse-checkout-cone-mode: false + persist-credentials: false + + - name: Check required sections + id: check + env: + BODY: ${{ github.event.pull_request.body }} + run: | + OK=true + while IFS= read -r header; do + printf '%s\n' "$BODY" | grep -qF "$header" || OK=false + done < <(grep "^## " .github/pull_request_template.md) + echo "uses_template=$OK" >> "$GITHUB_OUTPUT" + + act: + runs-on: ubuntu-latest + needs: parse + permissions: + pull-requests: write + steps: + - name: Close PR + if: ${{ needs.parse.outputs.uses_template == 'false' && github.event.pull_request.state != 'closed' }} + env: + GH_TOKEN: ${{ github.token }} + NODE_ID: ${{ github.event.pull_request.node_id }} + run: | + gh api graphql \ + -f prId="$NODE_ID" \ + -f body="This PR has been automatically closed as the description doesn't follow our template. After you edit it to match the template, the PR will automatically be reopened." \ + -f query=' + mutation CommentAndClosePR($prId: ID!, $body: String!) { + addComment(input: { + subjectId: $prId, + body: $body + }) { + __typename + } + closePullRequest(input: { + pullRequestId: $prId + }) { + __typename + } + }' + + - name: Reopen PR (sections now present, PR closed) + if: ${{ needs.parse.outputs.uses_template == 'true' && github.event.pull_request.state == 'closed' }} + env: + GH_TOKEN: ${{ github.token }} + NODE_ID: ${{ github.event.pull_request.node_id }} + run: | + gh api graphql \ + -f prId="$NODE_ID" \ + -f query=' + mutation ReopenPR($prId: ID!) { + reopenPullRequest(input: { + pullRequestId: $prId + }) { + __typename + } + }' diff --git a/mobile/android/app/build.gradle b/mobile/android/app/build.gradle index f45a06e3df27d..25d3f911b6f0a 100644 --- a/mobile/android/app/build.gradle +++ b/mobile/android/app/build.gradle @@ -118,6 +118,8 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "com.squareup.okhttp3:okhttp:$okhttp_version" implementation 'org.chromium.net:cronet-embedded:143.7445.0' + implementation("androidx.media3:media3-datasource-okhttp:1.9.2") + implementation("androidx.media3:media3-datasource-cronet:1.9.2") implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version" implementation "androidx.work:work-runtime-ktx:$work_version" implementation "androidx.concurrent:concurrent-futures:$concurrent_version" diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt index a85929a0e93d3..06649de8f0afc 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt @@ -12,6 +12,7 @@ import app.alextran.immich.connectivity.ConnectivityApiImpl import app.alextran.immich.core.HttpClientManager import app.alextran.immich.core.ImmichPlugin import app.alextran.immich.core.NetworkApiPlugin +import me.albemala.native_video_player.NativeVideoPlayerPlugin import app.alextran.immich.images.LocalImageApi import app.alextran.immich.images.LocalImagesImpl import app.alextran.immich.images.RemoteImageApi @@ -31,6 +32,7 @@ class MainActivity : FlutterFragmentActivity() { companion object { fun registerPlugins(ctx: Context, flutterEngine: FlutterEngine) { HttpClientManager.initialize(ctx) + NativeVideoPlayerPlugin.dataSourceFactory = HttpClientManager::createDataSourceFactory flutterEngine.plugins.add(NetworkApiPlugin()) val messenger = flutterEngine.dartExecutor.binaryMessenger diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt index 180ae4735df77..5b53b2a49aab6 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/core/HttpClientManager.kt @@ -3,7 +3,13 @@ package app.alextran.immich.core import android.content.Context import android.content.SharedPreferences import android.security.KeyChain +import androidx.annotation.OptIn import androidx.core.content.edit +import androidx.media3.common.util.UnstableApi +import androidx.media3.datasource.DataSource +import androidx.media3.datasource.ResolvingDataSource +import androidx.media3.datasource.cronet.CronetDataSource +import androidx.media3.datasource.okhttp.OkHttpDataSource import app.alextran.immich.BuildConfig import app.alextran.immich.NativeBuffer import okhttp3.Cache @@ -16,6 +22,7 @@ import okhttp3.Headers import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.OkHttpClient +import org.chromium.net.CronetEngine import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json import java.io.ByteArrayInputStream @@ -25,6 +32,8 @@ import java.security.KeyStore import java.security.Principal import java.security.PrivateKey import java.security.cert.X509Certificate +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors import java.util.concurrent.TimeUnit import javax.net.ssl.HttpsURLConnection import javax.net.ssl.SSLContext @@ -56,6 +65,7 @@ private enum class AuthCookie(val cookieName: String, val httpOnly: Boolean) { */ object HttpClientManager { private const val CACHE_SIZE_BYTES = 100L * 1024 * 1024 // 100MiB + const val MEDIA_CACHE_SIZE_BYTES = 1024L * 1024 * 1024 // 1GiB private const val KEEP_ALIVE_CONNECTIONS = 10 private const val KEEP_ALIVE_DURATION_MINUTES = 5L private const val MAX_REQUESTS_PER_HOST = 64 @@ -67,6 +77,11 @@ object HttpClientManager { private lateinit var appContext: Context private lateinit var prefs: SharedPreferences + var cronetEngine: CronetEngine? = null + private set + private lateinit var cronetStorageDir: File + val cronetExecutor: ExecutorService = Executors.newFixedThreadPool(4) + private val keyStore = KeyStore.getInstance("AndroidKeyStore").apply { load(null) } var keyChainAlias: String? = null @@ -107,6 +122,10 @@ object HttpClientManager { val cacheDir = File(File(context.cacheDir, "okhttp"), "api") client = build(cacheDir) + + cronetStorageDir = File(context.cacheDir, "cronet").apply { mkdirs() } + cronetEngine = buildCronetEngine() + initialized = true } } @@ -223,6 +242,53 @@ object HttpClientManager { ?.joinToString("; ") { "${it.name}=${it.value}" } } + fun getAuthHeaders(url: String): Map { + val result = mutableMapOf() + headers.forEach { (key, value) -> result[key] = value } + loadCookieHeader(url)?.let { result["Cookie"] = it } + url.toHttpUrlOrNull()?.let { httpUrl -> + if (httpUrl.username.isNotEmpty()) { + result["Authorization"] = Credentials.basic(httpUrl.username, httpUrl.password) + } + } + return result + } + + fun rebuildCronetEngine(): CronetEngine { + val old = cronetEngine!! + cronetEngine = buildCronetEngine() + return old + } + + val cronetStoragePath: File get() = cronetStorageDir + + @OptIn(UnstableApi::class) + fun createDataSourceFactory(headers: Map): DataSource.Factory { + return if (isMtls) { + OkHttpDataSource.Factory(client.newBuilder().cache(null).build()) + } else { + ResolvingDataSource.Factory( + CronetDataSource.Factory(cronetEngine!!, cronetExecutor) + ) { dataSpec -> + val newHeaders = dataSpec.httpRequestHeaders.toMutableMap() + newHeaders.putAll(getAuthHeaders(dataSpec.uri.toString())) + newHeaders["Cache-Control"] = "no-store" + dataSpec.buildUpon().setHttpRequestHeaders(newHeaders).build() + } + } + } + + private fun buildCronetEngine(): CronetEngine { + return CronetEngine.Builder(appContext) + .enableHttp2(true) + .enableQuic(true) + .enableBrotli(true) + .setStoragePath(cronetStorageDir.absolutePath) + .setUserAgent(USER_AGENT) + .enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK, MEDIA_CACHE_SIZE_BYTES) + .build() + } + private fun build(cacheDir: File): OkHttpClient { val connectionPool = ConnectionPool( maxIdleConnections = KEEP_ALIVE_CONNECTIONS, diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImagesImpl.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImagesImpl.kt index b820b454254dc..8e9fc3f6d5b4a 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImagesImpl.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/images/RemoteImagesImpl.kt @@ -7,7 +7,6 @@ import app.alextran.immich.INITIAL_BUFFER_SIZE import app.alextran.immich.NativeBuffer import app.alextran.immich.NativeByteBuffer import app.alextran.immich.core.HttpClientManager -import app.alextran.immich.core.USER_AGENT import kotlinx.coroutines.* import okhttp3.Cache import okhttp3.Call @@ -15,9 +14,6 @@ import okhttp3.Callback import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response -import okhttp3.Credentials -import okhttp3.HttpUrl.Companion.toHttpUrlOrNull -import org.chromium.net.CronetEngine import org.chromium.net.CronetException import org.chromium.net.UrlRequest import org.chromium.net.UrlResponseInfo @@ -31,10 +27,6 @@ import java.nio.file.Path import java.nio.file.SimpleFileVisitor import java.nio.file.attribute.BasicFileAttributes import java.util.concurrent.ConcurrentHashMap -import java.util.concurrent.Executors - - -private const val CACHE_SIZE_BYTES = 1024L * 1024 * 1024 private class RemoteRequest(val cancellationSignal: CancellationSignal) @@ -101,7 +93,6 @@ class RemoteImagesImpl(context: Context) : RemoteImageApi { } private object ImageFetcherManager { - private lateinit var appContext: Context private lateinit var cacheDir: File private lateinit var fetcher: ImageFetcher private var initialized = false @@ -110,7 +101,6 @@ private object ImageFetcherManager { if (initialized) return synchronized(this) { if (initialized) return - appContext = context.applicationContext cacheDir = context.cacheDir fetcher = build() HttpClientManager.addClientChangedListener(::invalidate) @@ -143,7 +133,7 @@ private object ImageFetcherManager { return if (HttpClientManager.isMtls) { OkHttpImageFetcher.create(cacheDir) } else { - CronetImageFetcher(appContext, cacheDir) + CronetImageFetcher() } } } @@ -161,19 +151,11 @@ private sealed interface ImageFetcher { fun clearCache(onCleared: (Result) -> Unit) } -private class CronetImageFetcher(context: Context, cacheDir: File) : ImageFetcher { - private val ctx = context - private var engine: CronetEngine - private val executor = Executors.newFixedThreadPool(4) +private class CronetImageFetcher : ImageFetcher { private val stateLock = Any() private var activeCount = 0 private var draining = false private var onCacheCleared: ((Result) -> Unit)? = null - private val storageDir = File(cacheDir, "cronet").apply { mkdirs() } - - init { - engine = build(context) - } override fun fetch( url: String, @@ -190,30 +172,16 @@ private class CronetImageFetcher(context: Context, cacheDir: File) : ImageFetche } val callback = FetchCallback(onSuccess, onFailure, ::onComplete) - val requestBuilder = engine.newUrlRequestBuilder(url, callback, executor) - HttpClientManager.headers.forEach { (key, value) -> requestBuilder.addHeader(key, value) } - HttpClientManager.loadCookieHeader(url)?.let { requestBuilder.addHeader("Cookie", it) } - url.toHttpUrlOrNull()?.let { httpUrl -> - if (httpUrl.username.isNotEmpty()) { - requestBuilder.addHeader("Authorization", Credentials.basic(httpUrl.username, httpUrl.password)) - } + val requestBuilder = HttpClientManager.cronetEngine!! + .newUrlRequestBuilder(url, callback, HttpClientManager.cronetExecutor) + HttpClientManager.getAuthHeaders(url).forEach { (key, value) -> + requestBuilder.addHeader(key, value) } val request = requestBuilder.build() signal.setOnCancelListener(request::cancel) request.start() } - private fun build(ctx: Context): CronetEngine { - return CronetEngine.Builder(ctx) - .enableHttp2(true) - .enableQuic(true) - .enableBrotli(true) - .setStoragePath(storageDir.absolutePath) - .setUserAgent(USER_AGENT) - .enableHttpCache(CronetEngine.Builder.HTTP_CACHE_DISK, CACHE_SIZE_BYTES) - .build() - } - private fun onComplete() { val didDrain = synchronized(stateLock) { activeCount-- @@ -236,19 +204,16 @@ private class CronetImageFetcher(context: Context, cacheDir: File) : ImageFetche } private fun onDrained() { - engine.shutdown() val onCacheCleared = synchronized(stateLock) { val onCacheCleared = onCacheCleared this.onCacheCleared = null onCacheCleared } - if (onCacheCleared == null) { - executor.shutdown() - } else { + if (onCacheCleared != null) { + val oldEngine = HttpClientManager.rebuildCronetEngine() + oldEngine.shutdown() CoroutineScope(Dispatchers.IO).launch { - val result = runCatching { deleteFolderAndGetSize(storageDir.toPath()) } - // Cronet is very good at self-repair, so it shouldn't fail here regardless of clear result - engine = build(ctx) + val result = runCatching { deleteFolderAndGetSize(HttpClientManager.cronetStoragePath.toPath()) } synchronized(stateLock) { draining = false } onCacheCleared(result) } @@ -375,7 +340,7 @@ private class OkHttpImageFetcher private constructor( val dir = File(cacheDir, "okhttp") val client = HttpClientManager.getClient().newBuilder() - .cache(Cache(File(dir, "thumbnails"), CACHE_SIZE_BYTES)) + .cache(Cache(File(dir, "thumbnails"), HttpClientManager.MEDIA_CACHE_SIZE_BYTES)) .build() return OkHttpImageFetcher(client) diff --git a/mobile/ios/Runner/AppDelegate.swift b/mobile/ios/Runner/AppDelegate.swift index f842285b23448..8487db7b484a0 100644 --- a/mobile/ios/Runner/AppDelegate.swift +++ b/mobile/ios/Runner/AppDelegate.swift @@ -1,5 +1,6 @@ import BackgroundTasks import Flutter +import native_video_player import network_info_plus import path_provider_foundation import permission_handler_apple @@ -18,6 +19,7 @@ import UIKit UNUserNotificationCenter.current().delegate = self as UNUserNotificationCenterDelegate } + SwiftNativeVideoPlayerPlugin.cookieStorage = URLSessionManager.cookieStorage GeneratedPluginRegistrant.register(with: self) let controller: FlutterViewController = window?.rootViewController as! FlutterViewController AppDelegate.registerPlugins(with: controller.engine, controller: controller) diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index eee93ddf36002..7f50834f4a0e5 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -1210,10 +1210,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: @@ -1234,8 +1234,8 @@ packages: dependency: "direct main" description: path: "." - ref: "0a80cd0bd3ff61790d1e05ef15baa7cbe26264d2" - resolved-ref: "0a80cd0bd3ff61790d1e05ef15baa7cbe26264d2" + ref: cdf621bdb7edaf996e118a58a48f6441187d79c6 + resolved-ref: cdf621bdb7edaf996e118a58a48f6441187d79c6 url: "https://github.com/immich-app/native_video_player" source: git version: "1.3.1" @@ -1937,10 +1937,10 @@ packages: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.7" thumbhash: dependency: "direct main" description: diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 744d3ad219f66..4d7fe03a3c769 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -56,7 +56,7 @@ dependencies: native_video_player: git: url: https://github.com/immich-app/native_video_player - ref: '0a80cd0bd3ff61790d1e05ef15baa7cbe26264d2' + ref: 'cdf621bdb7edaf996e118a58a48f6441187d79c6' network_info_plus: ^6.1.3 octo_image: ^2.1.0 openapi: diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 98bfa1237f925..d3203a754e42b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -67,7 +67,7 @@ importers: version: 24.12.0 '@vitest/coverage-v8': specifier: ^4.0.0 - version: 4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) byte-size: specifier: ^9.0.0 version: 9.0.1 @@ -115,10 +115,10 @@ importers: version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) vitest: specifier: ^4.0.0 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) vitest-fetch-mock: specifier: ^0.4.0 - version: 0.4.5(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 0.4.5(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) yaml: specifier: ^2.3.1 version: 2.8.2 @@ -348,13 +348,13 @@ importers: dependencies: '@aws-sdk/client-s3': specifier: ^3.1000.0 - version: 3.1008.0 + version: 3.1009.0 '@aws-sdk/lib-storage': specifier: ^3.1000.0 - version: 3.1008.0(@aws-sdk/client-s3@3.1008.0) + version: 3.1009.0(@aws-sdk/client-s3@3.1009.0) '@aws-sdk/s3-request-presigner': specifier: ^3.1000.0 - version: 3.1008.0 + version: 3.1009.0 '@extism/extism': specifier: 2.0.0-rc13 version: 2.0.0-rc13 @@ -688,7 +688,7 @@ importers: version: 13.15.10 '@vitest/coverage-v8': specifier: ^3.0.0 - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) eslint: specifier: ^10.0.0 version: 10.0.2(jiti@2.6.1) @@ -745,7 +745,7 @@ importers: version: 6.1.1(typescript@5.9.3)(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) web: dependencies: @@ -802,7 +802,7 @@ importers: version: 2.6.0 fabric: specifier: ^7.0.0 - version: 7.2.0(encoding@0.1.13) + version: 7.2.0 geo-coordinates-parser: specifier: ^1.7.4 version: 1.7.4 @@ -908,7 +908,7 @@ importers: version: 6.9.1 '@testing-library/svelte': specifier: ^5.2.8 - version: 5.3.1(svelte@5.53.7)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 5.3.1(svelte@5.53.7)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) '@testing-library/user-event': specifier: ^14.5.2 version: 14.6.1(@testing-library/dom@10.4.1) @@ -932,7 +932,7 @@ importers: version: 1.5.6 '@vitest/coverage-v8': specifier: ^4.0.0 - version: 4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + version: 4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) dotenv: specifier: ^17.0.0 version: 17.3.1 @@ -995,7 +995,7 @@ importers: version: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) vitest: specifier: ^4.0.0 - version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + version: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) packages: @@ -1169,141 +1169,141 @@ packages: '@aws-crypto/util@5.2.0': resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} - '@aws-sdk/client-s3@3.1008.0': - resolution: {integrity: sha512-w/SIRD25v2zVMbkn8CYIxUsac8yf5Jghkhw5j7EsNWdJhl56m/nWpUX7t1etFUW1cnzpFjZV0lXt0dNFSnbXwA==} + '@aws-sdk/client-s3@3.1009.0': + resolution: {integrity: sha512-luy8CxallkoiGWTqU86ca/BbvkWJjs0oala7uIIRN1JtQxMb5i4Yl/PBZVcQFhbK9kQi0PK0GfD8gIpLkI91fw==} engines: {node: '>=20.0.0'} - '@aws-sdk/core@3.973.19': - resolution: {integrity: sha512-56KePyOcZnKTWCd89oJS1G6j3HZ9Kc+bh/8+EbvtaCCXdP6T7O7NzCiPuHRhFLWnzXIaXX3CxAz0nI5My9spHQ==} + '@aws-sdk/core@3.973.20': + resolution: {integrity: sha512-i3GuX+lowD892F3IuJf8o6AbyDupMTdyTxQrCJGcn71ni5hTZ82L4nQhcdumxZ7XPJRJJVHS/CR3uYOIIs0PVA==} engines: {node: '>=20.0.0'} - '@aws-sdk/crc64-nvme@3.972.4': - resolution: {integrity: sha512-HKZIZLbRyvzo/bXZU7Zmk6XqU+1C9DjI56xd02vwuDIxedxBEqP17t9ExhbP9QFeNq/a3l9GOcyirFXxmbDhmw==} + '@aws-sdk/crc64-nvme@3.972.5': + resolution: {integrity: sha512-2VbTstbjKdT+yKi8m7b3a9CiVac+pL/IY2PHJwsaGkkHmuuqkJZIErPck1h6P3T9ghQMLSdMPyW6Qp7Di5swFg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-env@3.972.17': - resolution: {integrity: sha512-MBAMW6YELzE1SdkOniqr51mrjapQUv8JXSGxtwRjQV0mwVDutVsn22OPAUt4RcLRvdiHQmNBDEFP9iTeSVCOlA==} + '@aws-sdk/credential-provider-env@3.972.18': + resolution: {integrity: sha512-X0B8AlQY507i5DwjLByeU2Af4ARsl9Vr84koDcXCbAkplmU+1xBFWxEPrWRAoh56waBne/yJqEloSwvRf4x6XA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-http@3.972.19': - resolution: {integrity: sha512-9EJROO8LXll5a7eUFqu48k6BChrtokbmgeMWmsH7lBb6lVbtjslUYz/ShLi+SHkYzTomiGBhmzTW7y+H4BxsnA==} + '@aws-sdk/credential-provider-http@3.972.20': + resolution: {integrity: sha512-ey9Lelj001+oOfrbKmS6R2CJAiXX7QKY4Vj9VJv6L2eE6/VjD8DocHIoYqztTm70xDLR4E1jYPTKfIui+eRNDA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-ini@3.972.19': - resolution: {integrity: sha512-pVJVjWqVrPqjpFq7o0mCmeZu1Y0c94OCHSYgivdCD2wfmYVtBbwQErakruhgOD8pcMcx9SCqRw1pzHKR7OGBcA==} + '@aws-sdk/credential-provider-ini@3.972.20': + resolution: {integrity: sha512-5flXSnKHMloObNF+9N0cupKegnH1Z37cdVlpETVgx8/rAhCe+VNlkcZH3HDg2SDn9bI765S+rhNPXGDJJPfbtA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-login@3.972.19': - resolution: {integrity: sha512-jOXdZ1o+CywQKr6gyxgxuUmnGwTTnY2Kxs1PM7fI6AYtDWDnmW/yKXayNqkF8KjP1unflqMWKVbVt5VgmE3L0g==} + '@aws-sdk/credential-provider-login@3.972.20': + resolution: {integrity: sha512-gEWo54nfqp2jABMu6HNsjVC4hDLpg9HC8IKSJnp0kqWtxIJYHTmiLSsIfI4ScQjxEwpB+jOOH8dOLax1+hy/Hw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-node@3.972.20': - resolution: {integrity: sha512-0xHca2BnPY0kzjDYPH7vk8YbfdBPpWVS67rtqQMalYDQUCBYS37cZ55K6TuFxCoIyNZgSCFrVKr9PXC5BVvQQw==} + '@aws-sdk/credential-provider-node@3.972.21': + resolution: {integrity: sha512-hah8if3/B/Q+LBYN5FukyQ1Mym6PLPDsBOBsIgNEYD6wLyZg0UmUF/OKIVC3nX9XH8TfTPuITK+7N/jenVACWA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-process@3.972.17': - resolution: {integrity: sha512-c8G8wT1axpJDgaP3xzcy+q8Y1fTi9A2eIQJvyhQ9xuXrUZhlCfXbC0vM9bM1CUXiZppFQ1p7g0tuUMvil/gCPg==} + '@aws-sdk/credential-provider-process@3.972.18': + resolution: {integrity: sha512-Tpl7SRaPoOLT32jbTWchPsn52hYYgJ0kpiFgnwk8pxTANQdUymVSZkzFvv1+oOgZm1CrbQUP9MBeoMZ9IzLZjA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-sso@3.972.19': - resolution: {integrity: sha512-kVjQsEU3b///q7EZGrUzol9wzwJFKbEzqJKSq82A9ShrUTEO7FNylTtby3sPV19ndADZh1H3FB3+5ZrvKtEEeg==} + '@aws-sdk/credential-provider-sso@3.972.20': + resolution: {integrity: sha512-p+R+PYR5Z7Gjqf/6pvbCnzEHcqPCpLzR7Yf127HjJ6EAb4hUcD+qsNRnuww1sB/RmSeCLxyay8FMyqREw4p1RA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.19': - resolution: {integrity: sha512-BV1BlTFdG4w4tAihxN7iXDBoNcNewXD4q8uZlNQiUrnqxwGWUhKHODIQVSPlQGxXClEj+63m+cqZskw+ESmeZg==} + '@aws-sdk/credential-provider-web-identity@3.972.20': + resolution: {integrity: sha512-rWCmh8o7QY4CsUj63qopzMzkDq/yPpkrpb+CnjBEFSOg/02T/we7sSTVg4QsDiVS9uwZ8VyONhq98qt+pIh3KA==} engines: {node: '>=20.0.0'} - '@aws-sdk/lib-storage@3.1008.0': - resolution: {integrity: sha512-SWIzixPt9VG6jz8+tR8VklOi3FXY1J6WMfd1JEtY9gVtJaLGF5tWexIkjUnGHP8B6M6Uk+qC5zdr2Caome5Gfg==} + '@aws-sdk/lib-storage@3.1009.0': + resolution: {integrity: sha512-gHQh1sNeTuxZxPSMSQWOq/Xli8I5499uWyRKMakMSv8N7IYfoyDdyT52Ul6697qcqVaoPHixmYTllfEWMo1AKg==} engines: {node: '>=20.0.0'} peerDependencies: - '@aws-sdk/client-s3': ^3.1008.0 + '@aws-sdk/client-s3': ^3.1009.0 - '@aws-sdk/middleware-bucket-endpoint@3.972.7': - resolution: {integrity: sha512-goX+axlJ6PQlRnzE2bQisZ8wVrlm6dXJfBzMJhd8LhAIBan/w1Kl73fJnalM/S+18VnpzIHumyV6DtgmvqG5IA==} + '@aws-sdk/middleware-bucket-endpoint@3.972.8': + resolution: {integrity: sha512-WR525Rr2QJSETa9a050isktyWi/4yIGcmY3BQ1kpHqb0LqUglQHCS8R27dTJxxWNZvQ0RVGtEZjTCbZJpyF3Aw==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-expect-continue@3.972.7': - resolution: {integrity: sha512-mvWqvm61bmZUKmmrtl2uWbokqpenY3Mc3Jf4nXB/Hse6gWxLPaCQThmhPBDzsPSV8/Odn8V6ovWt3pZ7vy4BFQ==} + '@aws-sdk/middleware-expect-continue@3.972.8': + resolution: {integrity: sha512-5DTBTiotEES1e2jOHAq//zyzCjeMB78lEHd35u15qnrid4Nxm7diqIf9fQQ3Ov0ChH1V3Vvt13thOnrACmfGVQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.973.5': - resolution: {integrity: sha512-Dp3hqE5W6hG8HQ3Uh+AINx9wjjqYmFHbxede54sGj3akx/haIQrkp85lNdTdC+ouNUcSYNiuGkzmyDREfHX1Gg==} + '@aws-sdk/middleware-flexible-checksums@3.973.6': + resolution: {integrity: sha512-0nYEgkJH7Yt9k+nZJyllTghnkKaz17TWFcr5Mi0XMVMzYlF4ytDZADQpF2/iJo36cKL5AYSzRsvlykE4M/ErTA==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-host-header@3.972.7': - resolution: {integrity: sha512-aHQZgztBFEpDU1BB00VWCIIm85JjGjQW1OG9+98BdmaOpguJvzmXBGbnAiYcciCd+IS4e9BEq664lhzGnWJHgQ==} + '@aws-sdk/middleware-host-header@3.972.8': + resolution: {integrity: sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-location-constraint@3.972.7': - resolution: {integrity: sha512-vdK1LJfffBp87Lj0Bw3WdK1rJk9OLDYdQpqoKgmpIZPe+4+HawZ6THTbvjhJt4C4MNnRrHTKHQjkwBiIpDBoig==} + '@aws-sdk/middleware-location-constraint@3.972.8': + resolution: {integrity: sha512-KaUoFuoFPziIa98DSQsTPeke1gvGXlc5ZGMhy+b+nLxZ4A7jmJgLzjEF95l8aOQN2T/qlPP3MrAyELm8ExXucw==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-logger@3.972.7': - resolution: {integrity: sha512-LXhiWlWb26txCU1vcI9PneESSeRp/RYY/McuM4SpdrimQR5NgwaPb4VJCadVeuGWgh6QmqZ6rAKSoL1ob16W6w==} + '@aws-sdk/middleware-logger@3.972.8': + resolution: {integrity: sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-recursion-detection@3.972.7': - resolution: {integrity: sha512-l2VQdcBcYLzIzykCHtXlbpiVCZ94/xniLIkAj0jpnpjY4xlgZx7f56Ypn+uV1y3gG0tNVytJqo3K9bfMFee7SQ==} + '@aws-sdk/middleware-recursion-detection@3.972.8': + resolution: {integrity: sha512-BnnvYs2ZEpdlmZ2PNlV2ZyQ8j8AEkMTjN79y/YA475ER1ByFYrkVR85qmhni8oeTaJcDqbx364wDpitDAA/wCA==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-sdk-s3@3.972.19': - resolution: {integrity: sha512-/CtOHHVFg4ZuN6CnLnYkrqWgVEnbOBC4kNiKa+4fldJ9cioDt3dD/f5vpq0cWLOXwmGL2zgVrVxNhjxWpxNMkg==} + '@aws-sdk/middleware-sdk-s3@3.972.20': + resolution: {integrity: sha512-yhva/xL5H4tWQgsBjwV+RRD0ByCzg0TcByDCLp3GXdn/wlyRNfy8zsswDtCvr1WSKQkSQYlyEzPuWkJG0f5HvQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-ssec@3.972.7': - resolution: {integrity: sha512-G9clGVuAml7d8DYzY6DnRi7TIIDRvZ3YpqJPz/8wnWS5fYx/FNWNmkO6iJVlVkQg9BfeMzd+bVPtPJOvC4B+nQ==} + '@aws-sdk/middleware-ssec@3.972.8': + resolution: {integrity: sha512-wqlK0yO/TxEC2UsY9wIlqeeutF6jjLe0f96Pbm40XscTo57nImUk9lBcw0dPgsm0sppFtAkSlDrfpK+pC30Wqw==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-user-agent@3.972.20': - resolution: {integrity: sha512-3kNTLtpUdeahxtnJRnj/oIdLAUdzTfr9N40KtxNhtdrq+Q1RPMdCJINRXq37m4t5+r3H70wgC3opW46OzFcZYA==} + '@aws-sdk/middleware-user-agent@3.972.21': + resolution: {integrity: sha512-62XRl1GDYPpkt7cx1AX1SPy9wgNE9Iw/NPuurJu4lmhCWS7sGKO+kS53TQ8eRmIxy3skmvNInnk0ZbWrU5Dpyg==} engines: {node: '>=20.0.0'} - '@aws-sdk/nested-clients@3.996.9': - resolution: {integrity: sha512-+RpVtpmQbbtzFOKhMlsRcXM/3f1Z49qTOHaA8gEpHOYruERmog6f2AUtf/oTRLCWjR9H2b3roqryV/hI7QMW8w==} + '@aws-sdk/nested-clients@3.996.10': + resolution: {integrity: sha512-SlDol5Z+C7Ivnc2rKGqiqfSUmUZzY1qHfVs9myt/nxVwswgfpjdKahyTzLTx802Zfq0NFRs7AejwKzzzl5Co2w==} engines: {node: '>=20.0.0'} - '@aws-sdk/region-config-resolver@3.972.7': - resolution: {integrity: sha512-/Ev/6AI8bvt4HAAptzSjThGUMjcWaX3GX8oERkB0F0F9x2dLSBdgFDiyrRz3i0u0ZFZFQ1b28is4QhyqXTUsVA==} + '@aws-sdk/region-config-resolver@3.972.8': + resolution: {integrity: sha512-1eD4uhTDeambO/PNIDVG19A6+v4NdD7xzwLHDutHsUqz0B+i661MwQB2eYO4/crcCvCiQG4SRm1k81k54FEIvw==} engines: {node: '>=20.0.0'} - '@aws-sdk/s3-request-presigner@3.1008.0': - resolution: {integrity: sha512-YZMG/5X2TVegzLjw6H5MIIeAUlp+JtkomKOITIZ9P9XS21hRZthRmFO4eJZe0xVLGfuMYZPUYSsiD2eEQuWdQw==} + '@aws-sdk/s3-request-presigner@3.1009.0': + resolution: {integrity: sha512-iLHNt/R35ZWnmP/oxYbcA6NAsOXHn2kUHAii48aPR9A/0+eMXajBaeIQ37CsQPZPTzqGhy0pqBG8CnpcRXP6rg==} engines: {node: '>=20.0.0'} - '@aws-sdk/signature-v4-multi-region@3.996.7': - resolution: {integrity: sha512-mYhh7FY+7OOqjkYkd6+6GgJOsXK1xBWmuR+c5mxJPj2kr5TBNeZq+nUvE9kANWAux5UxDVrNOSiEM/wlHzC3Lg==} + '@aws-sdk/signature-v4-multi-region@3.996.8': + resolution: {integrity: sha512-n1qYFD+tbqZuyskVaxUE+t10AUz9g3qzDw3Tp6QZDKmqsjfDmZBd4GIk2EKJJNtcCBtE5YiUjDYA+3djFAFBBg==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.1008.0': - resolution: {integrity: sha512-TulwlHQBWcJs668kNUDMZHN51DeLrDsYT59Ux4a/nbvr025gM6HjKJJ3LvnZccam7OS/ZKUVkWomCneRQKJbBg==} + '@aws-sdk/token-providers@3.1009.0': + resolution: {integrity: sha512-KCPLuTqN9u0Rr38Arln78fRG9KXpzsPWmof+PZzfAHMMQq2QED6YjQrkrfiH7PDefLWEposY1o4/eGwrmKA4JA==} engines: {node: '>=20.0.0'} - '@aws-sdk/types@3.973.5': - resolution: {integrity: sha512-hl7BGwDCWsjH8NkZfx+HgS7H2LyM2lTMAI7ba9c8O0KqdBLTdNJivsHpqjg9rNlAlPyREb6DeDRXUl0s8uFdmQ==} + '@aws-sdk/types@3.973.6': + resolution: {integrity: sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw==} engines: {node: '>=20.0.0'} '@aws-sdk/util-arn-parser@3.972.3': resolution: {integrity: sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-endpoints@3.996.4': - resolution: {integrity: sha512-Hek90FBmd4joCFj+Vc98KLJh73Zqj3s2W56gjAcTkrNLMDI5nIFkG9YpfcJiVI1YlE2Ne1uOQNe+IgQ/Vz2XRA==} + '@aws-sdk/util-endpoints@3.996.5': + resolution: {integrity: sha512-Uh93L5sXFNbyR5sEPMzUU8tJ++Ku97EY4udmC01nB8Zu+xfBPwpIwJ6F7snqQeq8h2pf+8SGN5/NoytfKgYPIw==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-format-url@3.972.7': - resolution: {integrity: sha512-V+PbnWfUl93GuFwsOHsAq7hY/fnm9kElRqR8IexIJr5Rvif9e614X5sGSyz3mVSf1YAZ+VTy63W1/pGdA55zyA==} + '@aws-sdk/util-format-url@3.972.8': + resolution: {integrity: sha512-J6DS9oocrgxM8xlUTTmQOuwRF6rnAGEujAN9SAzllcrQmwn5iJ58ogxy3SEhD0Q7JZvlA5jvIXBkpQRqEqlE9A==} engines: {node: '>=20.0.0'} '@aws-sdk/util-locate-window@3.965.5': resolution: {integrity: sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-user-agent-browser@3.972.7': - resolution: {integrity: sha512-7SJVuvhKhMF/BkNS1n0QAJYgvEwYbK2QLKBrzDiwQGiTRU6Yf1f3nehTzm/l21xdAOtWSfp2uWSddPnP2ZtsVw==} + '@aws-sdk/util-user-agent-browser@3.972.8': + resolution: {integrity: sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA==} - '@aws-sdk/util-user-agent-node@3.973.6': - resolution: {integrity: sha512-iF7G0prk7AvmOK64FcLvc/fW+Ty1H+vttajL7PvJFReU8urMxfYmynTTuFKDTA76Wgpq3FzTPKwabMQIXQHiXQ==} + '@aws-sdk/util-user-agent-node@3.973.7': + resolution: {integrity: sha512-Hz6EZMUAEzqUd7e+vZ9LE7mn+5gMbxltXy18v+YSFY+9LBJz15wkNZvw5JqfX3z0FS9n3bgUtz3L5rAsfh4YlA==} engines: {node: '>=20.0.0'} peerDependencies: aws-crt: '>=1.0.0' @@ -1311,8 +1311,8 @@ packages: aws-crt: optional: true - '@aws-sdk/xml-builder@3.972.10': - resolution: {integrity: sha512-OnejAIVD+CxzyAUrVic7lG+3QRltyja9LoNqCE/1YVs8ichoTbJlVSaZ9iSMcnHLyzrSNtvaOGjSDRP+d/ouFA==} + '@aws-sdk/xml-builder@3.972.11': + resolution: {integrity: sha512-iitV/gZKQMvY9d7ovmyFnFuTHbBAtrmLnvaSb/3X8vOKyevwtpmEtyc8AdhVWZe0pI/1GsHxlEvQeOePFzy7KQ==} engines: {node: '>=20.0.0'} '@aws/lambda-invoke-store@0.2.4': @@ -7707,8 +7707,8 @@ packages: fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} - fast-xml-builder@1.1.2: - resolution: {integrity: sha512-NJAmiuVaJEjVa7TjLZKlYd7RqmzOC91EtPFXHvlTcqBVo50Qh7XV5IwvXi1c7NRz2Q/majGX9YLcwJtWgHjtkA==} + fast-xml-builder@1.1.3: + resolution: {integrity: sha512-1o60KoFw2+LWKQu3IdcfcFlGTW4dpqEWmjhYec6H82AYZU2TVBXep6tMl8Z1Y+wM+ZrzCwe3BZ9Vyd9N2rIvmg==} fast-xml-parser@5.4.1: resolution: {integrity: sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==} @@ -12936,20 +12936,20 @@ snapshots: '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 tslib: 2.8.1 '@aws-crypto/crc32c@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 tslib: 2.8.1 '@aws-crypto/sha1-browser@5.2.0': dependencies: '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@aws-sdk/util-locate-window': 3.965.5 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -12959,7 +12959,7 @@ snapshots: '@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/supports-web-crypto': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@aws-sdk/util-locate-window': 3.965.5 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 @@ -12967,7 +12967,7 @@ snapshots: '@aws-crypto/sha256-js@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 tslib: 2.8.1 '@aws-crypto/supports-web-crypto@5.2.0': @@ -12976,33 +12976,33 @@ snapshots: '@aws-crypto/util@5.2.0': dependencies: - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@smithy/util-utf8': 2.3.0 tslib: 2.8.1 - '@aws-sdk/client-s3@3.1008.0': + '@aws-sdk/client-s3@3.1009.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.19 - '@aws-sdk/credential-provider-node': 3.972.20 - '@aws-sdk/middleware-bucket-endpoint': 3.972.7 - '@aws-sdk/middleware-expect-continue': 3.972.7 - '@aws-sdk/middleware-flexible-checksums': 3.973.5 - '@aws-sdk/middleware-host-header': 3.972.7 - '@aws-sdk/middleware-location-constraint': 3.972.7 - '@aws-sdk/middleware-logger': 3.972.7 - '@aws-sdk/middleware-recursion-detection': 3.972.7 - '@aws-sdk/middleware-sdk-s3': 3.972.19 - '@aws-sdk/middleware-ssec': 3.972.7 - '@aws-sdk/middleware-user-agent': 3.972.20 - '@aws-sdk/region-config-resolver': 3.972.7 - '@aws-sdk/signature-v4-multi-region': 3.996.7 - '@aws-sdk/types': 3.973.5 - '@aws-sdk/util-endpoints': 3.996.4 - '@aws-sdk/util-user-agent-browser': 3.972.7 - '@aws-sdk/util-user-agent-node': 3.973.6 + '@aws-sdk/core': 3.973.20 + '@aws-sdk/credential-provider-node': 3.972.21 + '@aws-sdk/middleware-bucket-endpoint': 3.972.8 + '@aws-sdk/middleware-expect-continue': 3.972.8 + '@aws-sdk/middleware-flexible-checksums': 3.973.6 + '@aws-sdk/middleware-host-header': 3.972.8 + '@aws-sdk/middleware-location-constraint': 3.972.8 + '@aws-sdk/middleware-logger': 3.972.8 + '@aws-sdk/middleware-recursion-detection': 3.972.8 + '@aws-sdk/middleware-sdk-s3': 3.972.20 + '@aws-sdk/middleware-ssec': 3.972.8 + '@aws-sdk/middleware-user-agent': 3.972.21 + '@aws-sdk/region-config-resolver': 3.972.8 + '@aws-sdk/signature-v4-multi-region': 3.996.8 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-endpoints': 3.996.5 + '@aws-sdk/util-user-agent-browser': 3.972.8 + '@aws-sdk/util-user-agent-node': 3.973.7 '@smithy/config-resolver': 4.4.11 '@smithy/core': 3.23.11 '@smithy/eventstream-serde-browser': 4.2.12 @@ -13040,10 +13040,10 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.973.19': + '@aws-sdk/core@3.973.20': dependencies: - '@aws-sdk/types': 3.973.5 - '@aws-sdk/xml-builder': 3.972.10 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/xml-builder': 3.972.11 '@smithy/core': 3.23.11 '@smithy/node-config-provider': 4.3.12 '@smithy/property-provider': 4.2.12 @@ -13056,23 +13056,23 @@ snapshots: '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/crc64-nvme@3.972.4': + '@aws-sdk/crc64-nvme@3.972.5': dependencies: '@smithy/types': 4.13.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.17': + '@aws-sdk/credential-provider-env@3.972.18': dependencies: - '@aws-sdk/core': 3.973.19 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/core': 3.973.20 + '@aws-sdk/types': 3.973.6 '@smithy/property-provider': 4.2.12 '@smithy/types': 4.13.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.972.19': + '@aws-sdk/credential-provider-http@3.972.20': dependencies: - '@aws-sdk/core': 3.973.19 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/core': 3.973.20 + '@aws-sdk/types': 3.973.6 '@smithy/fetch-http-handler': 5.3.15 '@smithy/node-http-handler': 4.4.16 '@smithy/property-provider': 4.2.12 @@ -13082,17 +13082,17 @@ snapshots: '@smithy/util-stream': 4.5.19 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.972.19': - dependencies: - '@aws-sdk/core': 3.973.19 - '@aws-sdk/credential-provider-env': 3.972.17 - '@aws-sdk/credential-provider-http': 3.972.19 - '@aws-sdk/credential-provider-login': 3.972.19 - '@aws-sdk/credential-provider-process': 3.972.17 - '@aws-sdk/credential-provider-sso': 3.972.19 - '@aws-sdk/credential-provider-web-identity': 3.972.19 - '@aws-sdk/nested-clients': 3.996.9 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/credential-provider-ini@3.972.20': + dependencies: + '@aws-sdk/core': 3.973.20 + '@aws-sdk/credential-provider-env': 3.972.18 + '@aws-sdk/credential-provider-http': 3.972.20 + '@aws-sdk/credential-provider-login': 3.972.20 + '@aws-sdk/credential-provider-process': 3.972.18 + '@aws-sdk/credential-provider-sso': 3.972.20 + '@aws-sdk/credential-provider-web-identity': 3.972.20 + '@aws-sdk/nested-clients': 3.996.10 + '@aws-sdk/types': 3.973.6 '@smithy/credential-provider-imds': 4.2.12 '@smithy/property-provider': 4.2.12 '@smithy/shared-ini-file-loader': 4.4.7 @@ -13101,11 +13101,11 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-login@3.972.19': + '@aws-sdk/credential-provider-login@3.972.20': dependencies: - '@aws-sdk/core': 3.973.19 - '@aws-sdk/nested-clients': 3.996.9 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/core': 3.973.20 + '@aws-sdk/nested-clients': 3.996.10 + '@aws-sdk/types': 3.973.6 '@smithy/property-provider': 4.2.12 '@smithy/protocol-http': 5.3.12 '@smithy/shared-ini-file-loader': 4.4.7 @@ -13114,15 +13114,15 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-node@3.972.20': + '@aws-sdk/credential-provider-node@3.972.21': dependencies: - '@aws-sdk/credential-provider-env': 3.972.17 - '@aws-sdk/credential-provider-http': 3.972.19 - '@aws-sdk/credential-provider-ini': 3.972.19 - '@aws-sdk/credential-provider-process': 3.972.17 - '@aws-sdk/credential-provider-sso': 3.972.19 - '@aws-sdk/credential-provider-web-identity': 3.972.19 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/credential-provider-env': 3.972.18 + '@aws-sdk/credential-provider-http': 3.972.20 + '@aws-sdk/credential-provider-ini': 3.972.20 + '@aws-sdk/credential-provider-process': 3.972.18 + '@aws-sdk/credential-provider-sso': 3.972.20 + '@aws-sdk/credential-provider-web-identity': 3.972.20 + '@aws-sdk/types': 3.973.6 '@smithy/credential-provider-imds': 4.2.12 '@smithy/property-provider': 4.2.12 '@smithy/shared-ini-file-loader': 4.4.7 @@ -13131,21 +13131,21 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-process@3.972.17': + '@aws-sdk/credential-provider-process@3.972.18': dependencies: - '@aws-sdk/core': 3.973.19 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/core': 3.973.20 + '@aws-sdk/types': 3.973.6 '@smithy/property-provider': 4.2.12 '@smithy/shared-ini-file-loader': 4.4.7 '@smithy/types': 4.13.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.972.19': + '@aws-sdk/credential-provider-sso@3.972.20': dependencies: - '@aws-sdk/core': 3.973.19 - '@aws-sdk/nested-clients': 3.996.9 - '@aws-sdk/token-providers': 3.1008.0 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/core': 3.973.20 + '@aws-sdk/nested-clients': 3.996.10 + '@aws-sdk/token-providers': 3.1009.0 + '@aws-sdk/types': 3.973.6 '@smithy/property-provider': 4.2.12 '@smithy/shared-ini-file-loader': 4.4.7 '@smithy/types': 4.13.1 @@ -13153,11 +13153,11 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/credential-provider-web-identity@3.972.19': + '@aws-sdk/credential-provider-web-identity@3.972.20': dependencies: - '@aws-sdk/core': 3.973.19 - '@aws-sdk/nested-clients': 3.996.9 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/core': 3.973.20 + '@aws-sdk/nested-clients': 3.996.10 + '@aws-sdk/types': 3.973.6 '@smithy/property-provider': 4.2.12 '@smithy/shared-ini-file-loader': 4.4.7 '@smithy/types': 4.13.1 @@ -13165,9 +13165,9 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/lib-storage@3.1008.0(@aws-sdk/client-s3@3.1008.0)': + '@aws-sdk/lib-storage@3.1009.0(@aws-sdk/client-s3@3.1009.0)': dependencies: - '@aws-sdk/client-s3': 3.1008.0 + '@aws-sdk/client-s3': 3.1009.0 '@smithy/abort-controller': 4.2.12 '@smithy/middleware-endpoint': 4.4.25 '@smithy/smithy-client': 4.12.5 @@ -13176,9 +13176,9 @@ snapshots: stream-browserify: 3.0.0 tslib: 2.8.1 - '@aws-sdk/middleware-bucket-endpoint@3.972.7': + '@aws-sdk/middleware-bucket-endpoint@3.972.8': dependencies: - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@aws-sdk/util-arn-parser': 3.972.3 '@smithy/node-config-provider': 4.3.12 '@smithy/protocol-http': 5.3.12 @@ -13186,21 +13186,21 @@ snapshots: '@smithy/util-config-provider': 4.2.2 tslib: 2.8.1 - '@aws-sdk/middleware-expect-continue@3.972.7': + '@aws-sdk/middleware-expect-continue@3.972.8': dependencies: - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@smithy/protocol-http': 5.3.12 '@smithy/types': 4.13.1 tslib: 2.8.1 - '@aws-sdk/middleware-flexible-checksums@3.973.5': + '@aws-sdk/middleware-flexible-checksums@3.973.6': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.973.19 - '@aws-sdk/crc64-nvme': 3.972.4 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/core': 3.973.20 + '@aws-sdk/crc64-nvme': 3.972.5 + '@aws-sdk/types': 3.973.6 '@smithy/is-array-buffer': 4.2.2 '@smithy/node-config-provider': 4.3.12 '@smithy/protocol-http': 5.3.12 @@ -13210,37 +13210,37 @@ snapshots: '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/middleware-host-header@3.972.7': + '@aws-sdk/middleware-host-header@3.972.8': dependencies: - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@smithy/protocol-http': 5.3.12 '@smithy/types': 4.13.1 tslib: 2.8.1 - '@aws-sdk/middleware-location-constraint@3.972.7': + '@aws-sdk/middleware-location-constraint@3.972.8': dependencies: - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@smithy/types': 4.13.1 tslib: 2.8.1 - '@aws-sdk/middleware-logger@3.972.7': + '@aws-sdk/middleware-logger@3.972.8': dependencies: - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@smithy/types': 4.13.1 tslib: 2.8.1 - '@aws-sdk/middleware-recursion-detection@3.972.7': + '@aws-sdk/middleware-recursion-detection@3.972.8': dependencies: - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@aws/lambda-invoke-store': 0.2.4 '@smithy/protocol-http': 5.3.12 '@smithy/types': 4.13.1 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.972.19': + '@aws-sdk/middleware-sdk-s3@3.972.20': dependencies: - '@aws-sdk/core': 3.973.19 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/core': 3.973.20 + '@aws-sdk/types': 3.973.6 '@aws-sdk/util-arn-parser': 3.972.3 '@smithy/core': 3.23.11 '@smithy/node-config-provider': 4.3.12 @@ -13254,37 +13254,37 @@ snapshots: '@smithy/util-utf8': 4.2.2 tslib: 2.8.1 - '@aws-sdk/middleware-ssec@3.972.7': + '@aws-sdk/middleware-ssec@3.972.8': dependencies: - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@smithy/types': 4.13.1 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.972.20': + '@aws-sdk/middleware-user-agent@3.972.21': dependencies: - '@aws-sdk/core': 3.973.19 - '@aws-sdk/types': 3.973.5 - '@aws-sdk/util-endpoints': 3.996.4 + '@aws-sdk/core': 3.973.20 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-endpoints': 3.996.5 '@smithy/core': 3.23.11 '@smithy/protocol-http': 5.3.12 '@smithy/types': 4.13.1 '@smithy/util-retry': 4.2.12 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.996.9': + '@aws-sdk/nested-clients@3.996.10': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.973.19 - '@aws-sdk/middleware-host-header': 3.972.7 - '@aws-sdk/middleware-logger': 3.972.7 - '@aws-sdk/middleware-recursion-detection': 3.972.7 - '@aws-sdk/middleware-user-agent': 3.972.20 - '@aws-sdk/region-config-resolver': 3.972.7 - '@aws-sdk/types': 3.973.5 - '@aws-sdk/util-endpoints': 3.996.4 - '@aws-sdk/util-user-agent-browser': 3.972.7 - '@aws-sdk/util-user-agent-node': 3.973.6 + '@aws-sdk/core': 3.973.20 + '@aws-sdk/middleware-host-header': 3.972.8 + '@aws-sdk/middleware-logger': 3.972.8 + '@aws-sdk/middleware-recursion-detection': 3.972.8 + '@aws-sdk/middleware-user-agent': 3.972.21 + '@aws-sdk/region-config-resolver': 3.972.8 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-endpoints': 3.996.5 + '@aws-sdk/util-user-agent-browser': 3.972.8 + '@aws-sdk/util-user-agent-node': 3.973.7 '@smithy/config-resolver': 4.4.11 '@smithy/core': 3.23.11 '@smithy/fetch-http-handler': 5.3.15 @@ -13314,39 +13314,39 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/region-config-resolver@3.972.7': + '@aws-sdk/region-config-resolver@3.972.8': dependencies: - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@smithy/config-resolver': 4.4.11 '@smithy/node-config-provider': 4.3.12 '@smithy/types': 4.13.1 tslib: 2.8.1 - '@aws-sdk/s3-request-presigner@3.1008.0': + '@aws-sdk/s3-request-presigner@3.1009.0': dependencies: - '@aws-sdk/signature-v4-multi-region': 3.996.7 - '@aws-sdk/types': 3.973.5 - '@aws-sdk/util-format-url': 3.972.7 + '@aws-sdk/signature-v4-multi-region': 3.996.8 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-format-url': 3.972.8 '@smithy/middleware-endpoint': 4.4.25 '@smithy/protocol-http': 5.3.12 '@smithy/smithy-client': 4.12.5 '@smithy/types': 4.13.1 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.996.7': + '@aws-sdk/signature-v4-multi-region@3.996.8': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.972.19 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/middleware-sdk-s3': 3.972.20 + '@aws-sdk/types': 3.973.6 '@smithy/protocol-http': 5.3.12 '@smithy/signature-v4': 5.3.12 '@smithy/types': 4.13.1 tslib: 2.8.1 - '@aws-sdk/token-providers@3.1008.0': + '@aws-sdk/token-providers@3.1009.0': dependencies: - '@aws-sdk/core': 3.973.19 - '@aws-sdk/nested-clients': 3.996.9 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/core': 3.973.20 + '@aws-sdk/nested-clients': 3.996.10 + '@aws-sdk/types': 3.973.6 '@smithy/property-provider': 4.2.12 '@smithy/shared-ini-file-loader': 4.4.7 '@smithy/types': 4.13.1 @@ -13354,7 +13354,7 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/types@3.973.5': + '@aws-sdk/types@3.973.6': dependencies: '@smithy/types': 4.13.1 tslib: 2.8.1 @@ -13363,17 +13363,17 @@ snapshots: dependencies: tslib: 2.8.1 - '@aws-sdk/util-endpoints@3.996.4': + '@aws-sdk/util-endpoints@3.996.5': dependencies: - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@smithy/types': 4.13.1 '@smithy/url-parser': 4.2.12 '@smithy/util-endpoints': 3.3.3 tslib: 2.8.1 - '@aws-sdk/util-format-url@3.972.7': + '@aws-sdk/util-format-url@3.972.8': dependencies: - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@smithy/querystring-builder': 4.2.12 '@smithy/types': 4.13.1 tslib: 2.8.1 @@ -13382,23 +13382,23 @@ snapshots: dependencies: tslib: 2.8.1 - '@aws-sdk/util-user-agent-browser@3.972.7': + '@aws-sdk/util-user-agent-browser@3.972.8': dependencies: - '@aws-sdk/types': 3.973.5 + '@aws-sdk/types': 3.973.6 '@smithy/types': 4.13.1 bowser: 2.14.1 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.973.6': + '@aws-sdk/util-user-agent-node@3.973.7': dependencies: - '@aws-sdk/middleware-user-agent': 3.972.20 - '@aws-sdk/types': 3.973.5 + '@aws-sdk/middleware-user-agent': 3.972.21 + '@aws-sdk/types': 3.973.6 '@smithy/node-config-provider': 4.3.12 '@smithy/types': 4.13.1 '@smithy/util-config-provider': 4.2.2 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.972.10': + '@aws-sdk/xml-builder@3.972.11': dependencies: '@smithy/types': 4.13.1 fast-xml-parser: 5.4.1 @@ -16183,6 +16183,22 @@ snapshots: '@mapbox/mapbox-gl-rtl-text@0.3.0': {} + '@mapbox/node-pre-gyp@1.0.11': + dependencies: + detect-libc: 2.1.2 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.7.0 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.7.4 + tar: 6.2.1 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + '@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)': dependencies: detect-libc: 2.1.2 @@ -17833,14 +17849,14 @@ snapshots: dependencies: svelte: 5.53.7 - '@testing-library/svelte@5.3.1(svelte@5.53.7)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@testing-library/svelte@5.3.1(svelte@5.53.7)(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@testing-library/dom': 10.4.1 '@testing-library/svelte-core': 1.0.0(svelte@5.53.7) svelte: 5.53.7 optionalDependencies: vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.1)': dependencies: @@ -18534,7 +18550,7 @@ snapshots: '@vercel/oidc@3.0.5': {} - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 @@ -18549,11 +18565,11 @@ snapshots: std-env: 3.10.0 test-exclude: 7.0.2 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.0.18 @@ -18565,9 +18581,9 @@ snapshots: obug: 2.1.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': + '@vitest/coverage-v8@4.0.18(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.0.18 @@ -18579,7 +18595,7 @@ snapshots: obug: 2.1.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) '@vitest/expect@3.2.4': dependencies: @@ -19352,6 +19368,16 @@ snapshots: caniuse-lite@1.0.30001776: {} + canvas@2.11.2: + dependencies: + '@mapbox/node-pre-gyp': 1.0.11 + nan: 2.25.0 + simple-get: 3.1.1 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + canvas@2.11.2(encoding@0.1.13): dependencies: '@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13) @@ -20950,10 +20976,10 @@ snapshots: extend@3.0.2: {} - fabric@7.2.0(encoding@0.1.13): + fabric@7.2.0: optionalDependencies: - canvas: 2.11.2(encoding@0.1.13) - jsdom: 26.1.0(canvas@2.11.2(encoding@0.1.13)) + canvas: 2.11.2 + jsdom: 26.1.0(canvas@2.11.2) transitivePeerDependencies: - bufferutil - encoding @@ -20989,13 +21015,13 @@ snapshots: fast-uri@3.1.0: {} - fast-xml-builder@1.1.2: + fast-xml-builder@1.1.3: dependencies: path-expression-matcher: 1.1.3 fast-xml-parser@5.4.1: dependencies: - fast-xml-builder: 1.1.2 + fast-xml-builder: 1.1.3 strnum: 2.2.0 fastq@1.20.1: @@ -22150,6 +22176,36 @@ snapshots: - utf-8-validate optional: true + jsdom@26.1.0(canvas@2.11.2): + dependencies: + cssstyle: 4.6.0 + data-urls: 5.0.0 + decimal.js: 10.6.0 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.23 + parse5: 7.3.0 + rrweb-cssom: 0.8.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 5.1.2 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.2.0 + ws: 8.19.0 + xml-name-validator: 5.0.0 + optionalDependencies: + canvas: 2.11.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + optional: true + jsep@1.4.0: {} jsesc@3.1.0: {} @@ -23379,6 +23435,11 @@ snapshots: emojilib: 2.4.0 skin-tone: 2.0.0 + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + optional: true + node-fetch@2.7.0(encoding@0.1.13): dependencies: whatwg-url: 5.0.0 @@ -26479,11 +26540,11 @@ snapshots: optionalDependencies: vite: 7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - vitest-fetch-mock@0.4.5(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)): + vitest-fetch-mock@0.4.5(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)): dependencies: - vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + vitest: 4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) - vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 @@ -26512,7 +26573,7 @@ snapshots: '@types/debug': 4.1.12 '@types/node': 24.12.0 happy-dom: 20.8.3 - jsdom: 26.1.0(canvas@2.11.2(encoding@0.1.13)) + jsdom: 26.1.0(canvas@2.11.2) transitivePeerDependencies: - jiti - less @@ -26567,7 +26628,47 @@ snapshots: - tsx - yaml - vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@24.12.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): + dependencies: + '@vitest/expect': 4.0.18 + '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) + '@vitest/pretty-format': 4.0.18 + '@vitest/runner': 4.0.18 + '@vitest/snapshot': 4.0.18 + '@vitest/spy': 4.0.18 + '@vitest/utils': 4.0.18 + es-module-lexer: 1.7.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.1 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 1.0.2 + tinyglobby: 0.2.15 + tinyrainbow: 3.0.3 + vite: 7.3.1(@types/node@24.12.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@opentelemetry/api': 1.9.0 + '@types/node': 24.12.0 + happy-dom: 20.8.3 + jsdom: 26.1.0(canvas@2.11.2) + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - yaml + + vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@25.4.0)(happy-dom@20.8.3)(jiti@2.6.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2): dependencies: '@vitest/expect': 4.0.18 '@vitest/mocker': 4.0.18(vite@7.3.1(@types/node@25.4.0)(jiti@2.6.1)(lightningcss@1.31.1)(sass@1.97.1)(terser@5.44.1)(tsx@4.21.0)(yaml@2.8.2)) @@ -26593,7 +26694,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@types/node': 25.4.0 happy-dom: 20.8.3 - jsdom: 26.1.0(canvas@2.11.2(encoding@0.1.13)) + jsdom: 26.1.0(canvas@2.11.2) transitivePeerDependencies: - jiti - less diff --git a/server/src/repositories/email.repository.ts b/server/src/repositories/email.repository.ts index dd415318ba522..fa4c67230e91d 100644 --- a/server/src/repositories/email.repository.ts +++ b/server/src/repositories/email.repository.ts @@ -162,6 +162,7 @@ export class EmailRepository { host: options.host, port: options.port, tls: { rejectUnauthorized: !options.ignoreCert }, + secure: options.secure, auth: options.username || options.password ? { diff --git a/server/src/services/asset-media.service.spec.ts b/server/src/services/asset-media.service.spec.ts index bee321d99359d..0b1f6f899d371 100644 --- a/server/src/services/asset-media.service.spec.ts +++ b/server/src/services/asset-media.service.spec.ts @@ -155,13 +155,6 @@ const createDto = Object.freeze({ duration: '0:00:00.000000', }) as AssetMediaCreateDto; -const replaceDto = Object.freeze({ - deviceAssetId: 'deviceAssetId', - deviceId: 'deviceId', - fileModifiedAt: new Date('2024-04-15T23:41:36.910Z'), - fileCreatedAt: new Date('2024-04-15T23:41:36.910Z'), -}) as AssetMediaReplaceDto; - const assetEntity = Object.freeze({ id: 'id_1', ownerId: 'user_id_1', @@ -182,6 +175,13 @@ const assetEntity = Object.freeze({ livePhotoVideoId: null, } as MapAsset); +const replaceDto = Object.freeze({ + deviceAssetId: 'deviceAssetId', + deviceId: 'deviceId', + fileModifiedAt: new Date('2024-04-15T23:41:36.910Z'), + fileCreatedAt: new Date('2024-04-15T23:41:36.910Z'), +}) as AssetMediaReplaceDto; + const existingAsset = Object.freeze({ ...assetEntity, duration: null, diff --git a/server/test/small.factory.ts b/server/test/small.factory.ts index 744d3b0f1e422..d3f5aa534b43d 100644 --- a/server/test/small.factory.ts +++ b/server/test/small.factory.ts @@ -459,10 +459,10 @@ const albumFactory = (album?: Partial>) => ({ export const factory = { activity: activityFactory, apiKey: apiKeyFactory, + authUser: authUserFactory, + authApiKey: authApiKeyFactory, assetOcr: assetOcrFactory, auth: authFactory, - authApiKey: authApiKeyFactory, - authUser: authUserFactory, library: libraryFactory, partner: partnerFactory, queueStatistics: queueStatisticsFactory, diff --git a/web/src/lib/components/share-page/individual-shared-viewer.svelte b/web/src/lib/components/share-page/individual-shared-viewer.svelte index a3898479e287e..c969d0d7583a9 100644 --- a/web/src/lib/components/share-page/individual-shared-viewer.svelte +++ b/web/src/lib/components/share-page/individual-shared-viewer.svelte @@ -75,8 +75,12 @@ }; -
- {#if sharedLink?.allowUpload || assets.length > 1} +{#if sharedLink?.allowUpload || assets.length > 1} +
+ +
+ +
{#if assetInteraction.selectionActive} {/if} -
- -
- {:else if assets.length === 1} - {#await getAssetInfo({ ...authManager.params, id: assets[0].id }) then asset} - {#await import('$lib/components/asset-viewer/asset-viewer.svelte') then { default: AssetViewer }} - - {/await} +
+{:else if assets.length === 1} + {#await getAssetInfo({ ...authManager.params, id: assets[0].id }) then asset} + {#await import('$lib/components/asset-viewer/asset-viewer.svelte') then { default: AssetViewer }} + {/await} - {/if} -
+ {/await} +{/if} diff --git a/web/src/lib/components/shared-components/drag-and-drop-upload-overlay.svelte b/web/src/lib/components/shared-components/drag-and-drop-upload-overlay.svelte index 826669d755669..a8ef02f035408 100644 --- a/web/src/lib/components/shared-components/drag-and-drop-upload-overlay.svelte +++ b/web/src/lib/components/shared-components/drag-and-drop-upload-overlay.svelte @@ -13,6 +13,7 @@ let isInLockedFolder = $derived(isLockedFolderRoute(page.route.id)); let dragStartTarget: EventTarget | null = $state(null); + let isInternalDrag = false; const onDragEnter = (e: DragEvent) => { if (e.dataTransfer && e.dataTransfer.types.includes('Files')) { @@ -133,7 +134,19 @@ } }; + const ondragstart = () => { + isInternalDrag = true; + }; + + const ondragend = () => { + isInternalDrag = false; + }; + const ondragenter = (e: DragEvent) => { + if (isInternalDrag) { + return; + } + e.preventDefault(); e.stopPropagation(); onDragEnter(e); @@ -146,6 +159,10 @@ }; const ondrop = async (e: DragEvent) => { + if (isInternalDrag) { + return; + } + e.preventDefault(); e.stopPropagation(); await onDrop(e); @@ -159,7 +176,7 @@ - + {#if dragStartTarget}