commit d26eb5087570e4216977fad37693b6c21811f3a4 Author: CodeTempla Date: Tue May 19 20:58:19 2026 +0900 스마트서비스 최종완료보고 버전 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..425e2a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +smartservice_backend/.gradle +smartservice_backend/.vscode +smartservice_backend/bin +smartservice_backend/build diff --git a/smartservice_backend/HELP.md b/smartservice_backend/HELP.md new file mode 100644 index 0000000..8a19168 --- /dev/null +++ b/smartservice_backend/HELP.md @@ -0,0 +1,27 @@ +# Getting Started + +### Reference Documentation +For further reference, please consider the following sections: + +* [Official Gradle documentation](https://docs.gradle.org) +* [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.7.3/gradle-plugin/reference/html/) +* [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.7.3/gradle-plugin/reference/html/#build-image) +* [Spring Boot DevTools](https://docs.spring.io/spring-boot/docs/2.7.3/reference/htmlsingle/#using.devtools) +* [Spring Web](https://docs.spring.io/spring-boot/docs/2.7.3/reference/htmlsingle/#web) +* [Spring Session](https://docs.spring.io/spring-session/reference/) +* [JDBC API](https://docs.spring.io/spring-boot/docs/2.7.3/reference/htmlsingle/#data.sql) + +### Guides +The following guides illustrate how to use some features concretely: + +* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/) +* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/) +* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/) +* [Accessing Relational Data using JDBC with Spring](https://spring.io/guides/gs/relational-data-access/) +* [Managing Transactions](https://spring.io/guides/gs/managing-transactions/) + +### Additional Links +These additional references should also help you: + +* [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle) + diff --git a/smartservice_backend/_clean.bat b/smartservice_backend/_clean.bat new file mode 100644 index 0000000..ffadb6c --- /dev/null +++ b/smartservice_backend/_clean.bat @@ -0,0 +1,4 @@ +rmdir /q /s .gradle\ +rmdir /q /s bin\ +rmdir /q /s build\ +rmdir /q /s lib\ diff --git a/smartservice_backend/build.gradle b/smartservice_backend/build.gradle new file mode 100644 index 0000000..0b43438 --- /dev/null +++ b/smartservice_backend/build.gradle @@ -0,0 +1,56 @@ +plugins { + id 'org.springframework.boot' version '3.2.0' + id 'io.spring.dependency-management' version '1.1.3' + id 'java' + //id 'war' +} + +group = 'com.handong' +version = '0.0.1-SNAPSHOT' +sourceCompatibility = '21' +targetCompatibility = '21' + +// Configure Java toolchain to use Java 21 for compilation and execution where supported +java { + toolchain { + languageVersion = JavaLanguageVersion.of(21) + } +} +//apply plugin: 'war' +//bootWar.enabled = false +//war.enabled = true + + +repositories { + mavenCentral() +} + +dependencies { + implementation 'org.springframework.boot:spring-boot-starter-jdbc' + implementation 'org.springframework.boot:spring-boot-starter-web' + developmentOnly 'org.springframework.boot:spring-boot-devtools' + implementation 'org.springframework.boot:spring-boot-starter-security' + //runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' + //runtimeOnly 'mysql:mysql-connector-java:5.1.44' + runtimeOnly 'com.mysql:mysql-connector-j:8.0.33' + testImplementation 'org.springframework.boot:spring-boot-starter-test' + + implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.3' + + implementation 'javax.servlet:jstl:1.2' + implementation 'org.apache.tomcat.embed:tomcat-embed-jasper' + implementation 'org.apache.poi:poi:5.2.2' + implementation 'org.apache.poi:poi-ooxml:5.2.2' + + // JWT + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' + runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' + + // Redis + implementation 'org.springframework.boot:spring-boot-starter-data-redis' +} + +tasks.named('test') { + useJUnitPlatform() +} diff --git a/smartservice_backend/gradle/wrapper/gradle-wrapper.jar b/smartservice_backend/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..41d9927 Binary files /dev/null and b/smartservice_backend/gradle/wrapper/gradle-wrapper.jar differ diff --git a/smartservice_backend/gradle/wrapper/gradle-wrapper.properties b/smartservice_backend/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..17655d0 --- /dev/null +++ b/smartservice_backend/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/smartservice_backend/gradlew b/smartservice_backend/gradlew new file mode 100644 index 0000000..1b6c787 --- /dev/null +++ b/smartservice_backend/gradlew @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# 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 +# +# https://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. +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +APP_NAME="Gradle" +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/smartservice_backend/gradlew.bat b/smartservice_backend/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/smartservice_backend/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/smartservice_backend/settings.gradle b/smartservice_backend/settings.gradle new file mode 100644 index 0000000..f820a46 --- /dev/null +++ b/smartservice_backend/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'smartservice' diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtAuthFilter.java b/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtAuthFilter.java new file mode 100644 index 0000000..b0871b8 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtAuthFilter.java @@ -0,0 +1,93 @@ +package com.handong.smartservice.JwtAuth; + +import java.io.IOException; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.UserInfo; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.JwtException; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +public class JwtAuthFilter extends OncePerRequestFilter { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final JwtProvider jwtProvider; + + + public JwtAuthFilter(JwtProvider jwtProvider) { + this.jwtProvider = jwtProvider; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + String uri = request.getRequestURI(); + + logger.info("doFilterInternal: " + uri); + + //if (uri.compareTo("/api/add-transaction.do") == 0 || + // uri.compareTo("/api/sign-in.do") == 0 || + // uri.compareTo("/api/sval2.do") == 0) { + // filterChain.doFilter(request, response); + // return; + //} + if (_AG.isSkipAuthUri(uri)) { + filterChain.doFilter(request, response); + return; + } + + String auth = request.getHeader("Authorization"); + if (auth == null) { + //logger.info("doFilterInternal: auth == null"); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return; + } + + if (auth != null && auth.startsWith("Bearer ")) { + String token = auth.substring(7); + if (token == null) { + logger.info("doFilterInternal: token == null, req = " + uri); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return; + } + + try { + Claims claims = jwtProvider.getClaims(token); + + //List authorities = List.of(new SimpleGrantedAuthority("ROLE_USER")); + //UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(_AG.createJwtUserInfo(claims), authorities, List.of()); + UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(_AG.createJwtUserInfo(claims), null, List.of()); + + SecurityContext context = SecurityContextHolder.createEmptyContext(); + context.setAuthentication(authentication); + SecurityContextHolder.setContext(context); + } + catch (ExpiredJwtException e) { + //e.printStackTrace(); + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + return; + } + catch (JwtException | IllegalArgumentException e) { + //e.printStackTrace(); + logger.info("doFilterInternal, JWT validation failed, uri={}, msg={}", uri, e.getMessage()); + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + return; + } + } + + filterChain.doFilter(request, response); + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtProvider.java b/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtProvider.java new file mode 100644 index 0000000..0e0d221 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtProvider.java @@ -0,0 +1,142 @@ +package com.handong.smartservice.JwtAuth; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.ResponseCookie; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.*; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.JwtException; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + +import java.util.List; +import java.util.Map; +import java.nio.charset.StandardCharsets; +import java.security.Key; +import java.util.Date; +import java.util.HashMap; + + +@Component +public class JwtProvider { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + //private final long ACCESS_TOKEN_EXPIRE = 1000L * 30; //TestCode 30sec + //private final long REFRESH_TOKEN_EXPIRE = 1000L * 60 * 2; //TestCode 2min + private final long ACCESS_TOKEN_EXPIRE = 1000L * 60 * 60; // 60min + private final long REFRESH_TOKEN_EXPIRE = 1000L * 60 * 60 * 24 * 14; // 14day + + private final Key signingKey; + + private final JwtTokenStore tokenStore; + + public JwtProvider(@Value("${jwt.secret}") String secret) { + signingKey = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secret)); + this.tokenStore = new JwtTokenStoreMap(); + //this.tokenStore = new JwtTokenStoreRedis(); + } + + public long getRefreshExpire() { + return REFRESH_TOKEN_EXPIRE; + } + + + /* + public String createAccessToken(Long gid, String user_id, String nick_name, Long permission, Long biz_group_id) { + Date now = new Date(); + return Jwts.builder() + .setSubject(gid.toString()) + .claim("user_id", user_id) + .claim("nick_name", nick_name) + .claim("permission", permission) + .claim("biz_group_id", biz_group_id) + .setIssuedAt(now) + .setExpiration(new Date(now.getTime() + ACCESS_TOKEN_EXPIRE)) + .signWith(signingKey, SignatureAlgorithm.HS256) + .compact(); + } + */ + public String createAccessToken(Long gid, Map claims) { + Date now = new Date(); + return Jwts.builder() + .setSubject(gid.toString()) + .addClaims(claims) + .setIssuedAt(now) + .setExpiration(new Date(now.getTime() + ACCESS_TOKEN_EXPIRE)) + .signWith(signingKey, SignatureAlgorithm.HS256) + .compact(); + } + + public String createRefreshToken(Long gid) { + Date now = new Date(); + String token = Jwts.builder() + .setSubject(gid.toString()) + .setIssuedAt(now) + .setExpiration(new Date(now.getTime() + REFRESH_TOKEN_EXPIRE)) + .signWith(signingKey, SignatureAlgorithm.HS256) + .compact(); + + tokenStore.save(gid, token, REFRESH_TOKEN_EXPIRE); + return token; + } + + public boolean isValidate(String token) { + Long gid = 0L; + try { + Claims claims = Jwts.parserBuilder() + .setSigningKey(signingKey) + .build() + .parseClaimsJws(token) + .getBody(); + + if (claims.getExpiration().before(new Date())) + return false; // expired + + gid = Long.parseLong(claims.getSubject()); + + String storedToken = tokenStore.get(gid); + + if (storedToken != null && token.compareTo(storedToken) == 0) + return true; + } + catch (ExpiredJwtException e) { + } + + return false; + } + + public Long getGid(String token) { + String strGid = Jwts.parserBuilder() + .setSigningKey(signingKey) + .build() + .parseClaimsJws(token) + .getBody() + .getSubject(); + + return Long.parseLong(strGid); + } + + public Claims getClaims(String token) { + return Jwts.parserBuilder() + .setSigningKey(signingKey) + .build() + .parseClaimsJws(token) + .getBody(); + } + + public void delete(Long gid) { + tokenStore.delete(gid); + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtTokenStore.java b/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtTokenStore.java new file mode 100644 index 0000000..c8e6dae --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtTokenStore.java @@ -0,0 +1,7 @@ +package com.handong.smartservice.JwtAuth; + +public interface JwtTokenStore { + public String get(Long gid); + public void save(Long gid, String token, Long expireTime); + public void delete(Long gid); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtTokenStoreMap.java b/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtTokenStoreMap.java new file mode 100644 index 0000000..bb2bef2 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtTokenStoreMap.java @@ -0,0 +1,56 @@ +package com.handong.smartservice.JwtAuth; + +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.Iterator; + + +public class JwtTokenStoreMap implements JwtTokenStore { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + Map mapToken = new HashMap<>(); + Map mapExpire = new HashMap<>(); + int removeExpireSkip = 0; + + public JwtTokenStoreMap() { + } + + @Override + public String get(Long gid) { + return mapToken.get(gid); + } + + @Override + public void save(Long gid, String token, Long expireTime) { + if (removeExpireSkip++ > 500) { + removeExpireSkip = 0; + + long currTime = System.currentTimeMillis(); + Iterator> iterator = mapExpire.entrySet().iterator(); + while (iterator.hasNext()) { + Map.Entry entry = iterator.next(); + + logger.info("JwtTokenStoreMap, save, expire = " + entry.getValue() + ", currTime = " + currTime); + if (entry.getValue() < currTime) { + mapToken.remove(entry.getKey()); + iterator.remove(); + logger.info("remove refresh token : " + entry.getKey()); + } + } + } + + mapToken.put(gid, token); + mapExpire.put(gid, System.currentTimeMillis() + expireTime); + } + + @Override + public void delete(Long gid) { + mapToken.remove(gid); + mapExpire.remove(gid); + } +} + diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtTokenStoreRedis.java b/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtTokenStoreRedis.java new file mode 100644 index 0000000..52265d4 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/JwtAuth/JwtTokenStoreRedis.java @@ -0,0 +1,25 @@ +package com.handong.smartservice.JwtAuth; + +import java.util.concurrent.TimeUnit; + +public class JwtTokenStoreRedis implements JwtTokenStore { + + //private final StringRedisTemplate redisTemplate; + + //public JwtTokenStoreRedis(StringRedisTemplate redisTemplate) { + public JwtTokenStoreRedis() { + } + + public String get(Long gid) { + //redisTemplate.opsForValue().get("refreshToken:" + gid); + return ""; + } + + public void save(Long gid, String token, Long expireTime) { + //redisTemplate.opsForValue().set("refreshToken:" + gid, token, expireTime, TimeUnit.MILLISECONDS); + } + + public void delete(Long gid) { + //redisTemplate.delete("refreshToken:" + gid); + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/RedisConfig.java b/smartservice_backend/src/main/java/com/handong/smartservice/RedisConfig.java new file mode 100644 index 0000000..487fea0 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/RedisConfig.java @@ -0,0 +1,39 @@ +package com.handong.smartservice; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; + +@Configuration +public class RedisConfig { + /* + @Value("${spring.data.redis.host}") + private String redisHost; + + @Value("${spring.data.redis.port}") + private int redisPort; + + @Value("${spring.data.redis.password}") // 비밀번호 없는 경우 기본값 empty + private String redisPassword; + + @Bean + public RedisConnectionFactory redisConnectionFactory() { + RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(); + config.setHostName(redisHost); + config.setPort(redisPort); + if (!redisPassword.isEmpty()) { + config.setPassword(redisPassword); + } + return new LettuceConnectionFactory(config); + } + + @Bean + public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { + return new StringRedisTemplate(redisConnectionFactory); + } + */ +} \ No newline at end of file diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/ServletInitializer.java b/smartservice_backend/src/main/java/com/handong/smartservice/ServletInitializer.java new file mode 100644 index 0000000..358fd8c --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/ServletInitializer.java @@ -0,0 +1,13 @@ +package com.handong.smartservice; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +public class ServletInitializer extends SpringBootServletInitializer { + + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(SmartServiceApplication.class); + } + +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/SmartServiceApplication.java b/smartservice_backend/src/main/java/com/handong/smartservice/SmartServiceApplication.java new file mode 100644 index 0000000..50f3b96 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/SmartServiceApplication.java @@ -0,0 +1,16 @@ +package com.handong.smartservice; + +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; + +@SpringBootApplication +@MapperScan("com.handong.smartservice.mapper") +public class SmartServiceApplication { + + public static void main(String[] args) { + SpringApplication.run(SmartServiceApplication.class, args); + } + +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/SpringSecurityConfig.java b/smartservice_backend/src/main/java/com/handong/smartservice/SpringSecurityConfig.java new file mode 100644 index 0000000..8ce0374 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/SpringSecurityConfig.java @@ -0,0 +1,76 @@ +package com.handong.smartservice; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.security.web.firewall.HttpFirewall; +import org.springframework.security.web.firewall.StrictHttpFirewall; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import com.handong.smartservice.JwtAuth.JwtAuthFilter; +import com.handong.smartservice.JwtAuth.JwtProvider; + + +@EnableTransactionManagement +@Configuration +public class SpringSecurityConfig { + + private final JwtProvider jwtProvider; + + + public SpringSecurityConfig(JwtProvider jwtProvider) { + this.jwtProvider = jwtProvider; + } + + @Bean + public PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public HttpFirewall allowDoubleSlashFirewall() { + StrictHttpFirewall firewall = new StrictHttpFirewall(); + firewall.setAllowUrlEncodedDoubleSlash(true); + // firewall.setAllowSemicolon(true); + // firewall.setAllowBackSlash(true); + return firewall; + } + + @Bean + public WebSecurityCustomizer webSecurityCustomizer(HttpFirewall firewall) { + return (web) -> web.httpFirewall(firewall); + } + + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception { + return configuration.getAuthenticationManager(); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + //return http.csrf(csrf -> csrf.disable()).build(); //TestCode + + http.csrf(csrf -> csrf.disable()) + .sessionManagement(sessionManagement -> + sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS) + ) + .authorizeHttpRequests(auth -> auth + .anyRequest().permitAll() + ) + //.authorizeHttpRequests(auth -> auth + // .requestMatchers("/api/sign-in.do").permitAll() + // .anyRequest().authenticated() + //) + .addFilterBefore(new JwtAuthFilter(jwtProvider), UsernamePasswordAuthenticationFilter.class); + + return http.build(); + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/_AG.java b/smartservice_backend/src/main/java/com/handong/smartservice/_AG.java new file mode 100644 index 0000000..df1504a --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/_AG.java @@ -0,0 +1,256 @@ +package com.handong.smartservice; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.handong.smartservice.component.UserInfo; + +import io.jsonwebtoken.Claims; + +//import com.handong.smartservice.model.OperatingHistoryModel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.math.BigInteger; +import java.text.SimpleDateFormat; +import java.util.*; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpSession; + + + +@Configuration +public class _AG { + static public String MEDIA_UPLOAD_LOCAL_PATH; + + //@Value("${app-global.upload-file-path}") + void setMEDIA_UPLOAD_LOCAL_PATH(String str) { + MEDIA_UPLOAD_LOCAL_PATH = str; + } + + public static String getCurrentDateTime() { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss", Locale.KOREA); + Date date = new Date(); + return simpleDateFormat.format(date); + } + + // Timestamp to yyyy-MM-dd HH:mm:ss + public static String timestampToStr(Object timestamp) { + if (timestamp == null) + return ""; + String str = timestamp.toString(); + return str.substring(0, str.length() - 2); + } + + static public boolean hasText(String str) { + if (str == null || str.isEmpty()) + return false; + + return true; + } + + static public String safeStr(String str) { + if (str == null || str.isEmpty()) + return ""; + + return str; + } + + static public Long toLong(String str) { + if (str == null || str.isEmpty()) + return 0L; + + return Long.parseLong(str); + } + + static public Long toLongOrNull(String str) { + if (str == null || str.isEmpty()) + return null; + + return Long.parseLong(str); + } + + static public Long toLong(Integer obj) { + if (obj == null) + return 0L; + + return obj.longValue(); + } + + static public Long toLong(BigInteger obj) { + if (obj == null) + return 0L; + + return obj.longValue(); + } + + static public Boolean toBoolean(String str) { + if (str == null || str.isEmpty()) + return false; + + return Boolean.parseBoolean(str); + } + + static public String mapToJson(Map map) { + String json = "{}"; + ObjectMapper mapper = new ObjectMapper(); + try { + //json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(data); + json = mapper.writeValueAsString(map); + } + catch (JsonProcessingException e) { + e.printStackTrace(); + } + + return json; + } + + static public String mapToJson2(Map map) { + String json = "{}"; + ObjectMapper mapper = new ObjectMapper(); + try { + //json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(data); + json = mapper.writeValueAsString(map); + } + catch (JsonProcessingException e) { + e.printStackTrace(); + } + + return json; + } + + static public String saveUploadedFile(MultipartFile[] attached_files, String strFileName) { + Date today = new Date(); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddhhmmss"); + dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Seoul")); + + String strSaveFileName = dateFormat.format(today) + "_" + strFileName; + + try { + File file = new File(_AG.MEDIA_UPLOAD_LOCAL_PATH + strSaveFileName); + attached_files[0].transferTo(file); + } + catch (Exception e) { + e.printStackTrace(); + return null; + } + + return strSaveFileName; + } + + static public Long getNumberFromQuery(String strColName, List> qeuryResult) { + if (qeuryResult == null || qeuryResult.size() == 0) + return 0L; + + return (Long)qeuryResult.get(0).get(strColName); + } + + static public String getIpAddr(HttpServletRequest request) { + String ip = request.getHeader("X-Forwarded-For"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Real-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-RealIP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("REMOTE_ADDR"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + if (ip != null && !ip.isEmpty()) { + ip = ip.split(",")[0].trim(); + } + return ip; + } + + //static public void addHistory(EntityManager entityManager, int nType, String strAction, String gid) { + // OperatingHistoryModel operatingHistoryModel = new OperatingHistoryModel(entityManager); + // operatingHistoryModel.addOperatingHistory(nType, strAction, gid); + //} + + //JWT Auth + static public boolean isSkipAuthUri(String uri) { + if (uri.compareTo("/api/miss-slot.do") == 0 || + uri.compareTo("/api/terminal-state.do") == 0 || + uri.compareTo("/api/sign-in.do") == 0 || + uri.compareTo("/api/sval2.do") == 0 || + uri.compareTo("/api/add-transaction.do") == 0) { + return true; + } + + return false; + } + + static public UserInfo createJwtUserInfo(Claims claims) { + UserInfo principal = new UserInfo( + Long.parseLong(claims.getSubject()), + claims.get("user_id", String.class), + claims.get("nick_name", String.class), + claims.get("permission", Number.class), + claims.get("biz_group_id", Number.class) + ); + return principal; + } + + static public Map createUserInfoMap(String user_id, String nick_name, Long permission, Long biz_group_id) { + Map map = new HashMap<>(); + map.put("user_id", user_id); + map.put("nick_name", nick_name); + map.put("permission", permission); + map.put("biz_group_id", biz_group_id); + return map; + } + // + + // 사업자 번호 하이픈 자동추가 + static public String formatBusinessNumber(String input) { + String digits = input.replaceAll("\\D", ""); + + if (digits.length() > 10) { + digits = digits.substring(0, 10); + } + + return digits.replaceFirst("^(\\d{3})(\\d{2})(\\d{5})$", "$1-$2-$3"); + } + + // 사업자번호 검증 + static public boolean isValidBusinessNumber(String input) { + //return true; //TestCode + + String digits = input.replaceAll("\\D", ""); + if (digits.length() != 10) { + return false; + } + + int[] weights = {1, 3, 7, 1, 3, 7, 1, 3, 5}; + int sum = 0; + + for (int i = 0; i < 9; i++) { + int num = Character.getNumericValue(digits.charAt(i)); + sum += num * weights[i]; + } + + sum += (Character.getNumericValue(digits.charAt(8)) * 5) / 10; + + int checkDigit = (10 - (sum % 10)) % 10; + return checkDigit == Character.getNumericValue(digits.charAt(9)); + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/component/CtErrorCode.java b/smartservice_backend/src/main/java/com/handong/smartservice/component/CtErrorCode.java new file mode 100644 index 0000000..09a3d92 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/component/CtErrorCode.java @@ -0,0 +1,15 @@ +package com.handong.smartservice.component; + +public class CtErrorCode { + static public final int NO_ERROR = 0; + static public final int FAILED_CONNECT_DB = -2; + static public final int QUERY_ERROR = -3; + static public final int EXCEPTION_OCCRUED = -5; + static public final int INVALID_PARAMETER = -6; + static public final int FILE_IO_ERROR = -7; + + static public final int UNCORRECT_DATA = -8; + static public final int INVALID_USER = -9; + static public final int ALREADY_EXIST = -11; + static public final int THIRDPARTY_ERROR = -12; +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/component/CtExcelMaker.java b/smartservice_backend/src/main/java/com/handong/smartservice/component/CtExcelMaker.java new file mode 100644 index 0000000..e3ab842 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/component/CtExcelMaker.java @@ -0,0 +1,124 @@ +package com.handong.smartservice.component; + +import org.apache.poi.openxml4j.opc.OPCPackage; +import org.apache.poi.poifs.crypt.EncryptionInfo; +import org.apache.poi.poifs.crypt.EncryptionMode; +import org.apache.poi.poifs.crypt.Encryptor; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRichTextString; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.*; +import java.net.URLEncoder; + +import java.util.List; +import java.util.Map; + + + +public class CtExcelMaker { + static private final Logger logger = LoggerFactory.getLogger(CtExcelMaker.class); + + static public String getBrowser(HttpServletRequest request) { + String header = request.getHeader("User-Agent"); + if (header.indexOf("MSIE") > -1) { + return "MSIE"; + } else if (header.indexOf("Trident") > -1) { + return "Trident"; + } else if (header.indexOf("Chrome") > -1) { + return "Chrome"; + } else if (header.indexOf("Opera") > -1) { + return "Opera"; + } + return "Firefox"; + } + + static public void makeExcelResponse(HttpServletRequest request, HttpServletResponse response, + String strFileName, String[] arrHeader, String[] arrColumn, List> listContents, String strPassword) { + logger.info("ExcelLeader, makeExcelResponse, file name = " + strFileName); + + try { + XSSFRow row = null; + XSSFCell cell = null; + int nRowIndex = 0; + + XSSFWorkbook workBook = new XSSFWorkbook(); + + XSSFSheet sheet = workBook.createSheet("sheet"); + + row = sheet.createRow(nRowIndex++); + + // header + int i = 0; + for (; i < arrHeader.length; i++) { + cell = row.createCell(i); + cell.setCellValue(new XSSFRichTextString(arrHeader[i])); + } + + for (i = 0; i < listContents.size(); i++) { + Map col = listContents.get(i); + + row = sheet.createRow(nRowIndex++); + Object cellData; + for (int j = 0; j < arrColumn.length; j++) { + cell = row.createCell(j); + cellData = col.get(arrColumn[j]); + if (cellData == null) + cell.setCellValue(new XSSFRichTextString("")); + else + cell.setCellValue(new XSSFRichTextString(cellData.toString())); + } + } + + String strTmp = strFileName + ".xlsx"; + String browser = getBrowser(request); + if (browser.contains("MSIE") || browser.contains("Trident")) { + String strDownloadName = URLEncoder.encode(strTmp, "UTF-8").replaceAll("\\+", "%20"); + response.addHeader("Content-Disposition", "attachment;filename=" + strDownloadName + ";"); + } else { + //val strDownloadName = String(strTmp.toByteArray(Charsets.UTF_8), Charsets.ISO_8859_1) + String strDownloadName = URLEncoder.encode(strTmp, "UTF-8"); + response.addHeader("Content-Disposition", "attachment;filename=\"" + strDownloadName + "\""); + } + response.setContentType("application/vnd.ms-excel;charset=UTF-8"); + + //fuck!!! not working over poi 4 + if (strPassword != null && strPassword.isEmpty() == false) { + EncryptionInfo info = new EncryptionInfo(EncryptionMode.standard); + Encryptor encryptor = info.getEncryptor(); + encryptor.confirmPassword(strPassword); + + ByteArrayOutputStream osByteArray = new ByteArrayOutputStream(); + workBook.write(osByteArray); + InputStream isTmp = new ByteArrayInputStream(osByteArray.toByteArray()); + OPCPackage opc = OPCPackage.open(isTmp); + POIFSFileSystem poifs = new POIFSFileSystem(); + OutputStream osTemp = encryptor.getDataStream(poifs); + opc.save(osTemp); + opc.close(); + + OutputStream osResponse = response.getOutputStream(); + poifs.writeFilesystem(osResponse); + osResponse.close(); + osByteArray.close(); + return; + } + + OutputStream osResponse = response.getOutputStream(); + workBook.write(osResponse); + osResponse.close(); + } + catch(Exception e) { + e.printStackTrace(); + } + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/component/CtResponse.java b/smartservice_backend/src/main/java/com/handong/smartservice/component/CtResponse.java new file mode 100644 index 0000000..c79f775 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/component/CtResponse.java @@ -0,0 +1,44 @@ +package com.handong.smartservice.component; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.HashMap; + +public class CtResponse extends HashMap { + + public CtResponse() { + put("errCode", ErrorCode.NO_ERROR); + } + + public CtResponse(String key, Object obj) { + put("errCode", ErrorCode.NO_ERROR); + put(key, obj); + } + + public CtResponse(int errCode) { + put("errCode", errCode); + } + + public int errCode() { + return (int)get("errCode"); + } + + public void setErrCode(int errCode) { + put("errCode", errCode); + } + + public String toJson() { + String json = "{}"; + ObjectMapper mapper = new ObjectMapper(); + try { + //json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(data); + json = mapper.writeValueAsString(this); + } + catch (JsonProcessingException e) { + e.printStackTrace(); + } + + return json; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/component/DbLogger.java b/smartservice_backend/src/main/java/com/handong/smartservice/component/DbLogger.java new file mode 100644 index 0000000..b1846a2 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/component/DbLogger.java @@ -0,0 +1,21 @@ +package com.handong.smartservice.component; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.handong.smartservice.mapper.BizGroupMapper; +import com.handong.smartservice.mapper.OperatingHistoryMapper; + +@Component +public class DbLogger { + private static OperatingHistoryMapper operatingHistoryMapper; + + @Autowired + public DbLogger(OperatingHistoryMapper mapper){ + DbLogger.operatingHistoryMapper = mapper; + } + + public static void insert(Long type, String action, Long gid) { + operatingHistoryMapper.insertOperatingHistory(type, action, gid); + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/component/ErrorCode.java b/smartservice_backend/src/main/java/com/handong/smartservice/component/ErrorCode.java new file mode 100644 index 0000000..dc003ec --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/component/ErrorCode.java @@ -0,0 +1,9 @@ +package com.handong.smartservice.component; + +public class ErrorCode extends CtErrorCode { + static public final int INVALID_TOKEN = -15; + static public final int INVALID_REFRESH = -16; + + static public final int INVALID_BIZ_REG_NUM = -17; + //... +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/component/RcTree.java b/smartservice_backend/src/main/java/com/handong/smartservice/component/RcTree.java new file mode 100644 index 0000000..08bd67f --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/component/RcTree.java @@ -0,0 +1,72 @@ +package com.handong.smartservice.component; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class RcTree { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + + protected abstract Map makeNewNode(Map item); + + + public Map searchTreeNode(List> listRcTree, String key) { + Map node = null; + + for(int i = 0; i < listRcTree.size(); i++) { + node = listRcTree.get(i); + if (key.compareTo((String)node.get("key")) == 0) { + return node; + } + + Object children = node.get("children"); + if (children != null) { + Map parentNode = searchTreeNode((List>)children, key); + if (parentNode != null) + return parentNode; + } + } + + return null; + } + + public List> convert(List> listTreeDb) { + List> listRcTree = new ArrayList>(); + listTreeDb.forEach(item -> { + Map newNode = makeNewNode(item); + + if (item.get("pid") == null || listRcTree.size() == 0) { + listRcTree.add(newNode); + } + else { + // search parent node + final String pid = item.get("pid") != null ? item.get("pid").toString() : ""; + logger.debug("pid = " + pid); + + Map parentNode = searchTreeNode(listRcTree, pid); + logger.debug("convert, parentNode = " + parentNode); + + if (parentNode != null) { + List> children = null; + Object childrenNode = parentNode.get("children"); + if (childrenNode == null) { + children = new ArrayList>(); + } + else { + children = (List>)childrenNode; + } + children.add(newNode); + parentNode.put("children", children); + } + } + }); + + return listRcTree; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/component/RcTreeBizGroup.java b/smartservice_backend/src/main/java/com/handong/smartservice/component/RcTreeBizGroup.java new file mode 100644 index 0000000..c659ba8 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/component/RcTreeBizGroup.java @@ -0,0 +1,69 @@ +package com.handong.smartservice.component; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.handong.smartservice._AG; + +public class RcTreeBizGroup extends RcTree { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static List> convertDb2RcTree(List> listTreeDb) { + RcTree rcTree = new RcTreeBizGroup(); + return rcTree.convert(listTreeDb); + } + + @Override + protected Map makeNewNode(Map item) { + Map newNode = new LinkedHashMap(); + + String biz_group_id = item.get("biz_group_id").toString(); + newNode.put("key", biz_group_id); + logger.debug("key(biz_group_id): " + biz_group_id); + + String name = (String)item.get("name"); + newNode.put("name", name); + + String biz_reg_num = _AG.formatBusinessNumber((String)item.get("biz_reg_num")); + newNode.put("biz_reg_num", biz_reg_num); + + //... newNode.put("title", name + "(" + biz_reg_num + ")"); + newNode.put("title", name); + logger.debug("title(name): " + name); + + Timestamp reg_time = (Timestamp)item.get("reg_time"); + if (reg_time != null) + newNode.put("reg_time", reg_time); + + String email = (String)item.get("email"); + if (email != null) + newNode.put("email", email); + + String phone = (String)item.get("phone"); + if (phone != null) + newNode.put("phone", phone); + + String ceo = (String)item.get("ceo"); + if (ceo != null) + newNode.put("ceo", ceo); + + String address = (String)item.get("address"); + if (address != null) + newNode.put("address", address); + + Long top_group_id = (Long)item.get("top_group_id"); + if (address != null) + newNode.put("top_group_id", top_group_id); + + Long hasChildren = (Long)item.get("hasChildren"); + newNode.put("isLeaf", hasChildren == null || hasChildren == 0 ? true : false); + + return newNode; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/component/RcTreeLocation.java b/smartservice_backend/src/main/java/com/handong/smartservice/component/RcTreeLocation.java new file mode 100644 index 0000000..7f0c83a --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/component/RcTreeLocation.java @@ -0,0 +1,49 @@ +package com.handong.smartservice.component; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RcTreeLocation extends RcTree { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static List> convertDb2RcTree(List> listTreeDb) { + RcTree rcTree = new RcTreeLocation(); + return rcTree.convert(listTreeDb); + } + + @Override + protected Map makeNewNode(Map item) { + Map newNode = new LinkedHashMap(); + + String location = item.get("location_id").toString(); + newNode.put("key", location); + logger.debug("key(biz_group_id): " + location); + + String name = (String)item.get("name"); + newNode.put("name", name); + + String description = (String)item.get("description"); + newNode.put("description", description); + + newNode.put("title", name); + logger.debug("title: " + name); + + Timestamp reg_time = (Timestamp)item.get("reg_time"); + if (reg_time != null) + newNode.put("reg_time", reg_time); + + String address = (String)item.get("address"); + if (address != null) + newNode.put("address", address); + + newNode.put("isLeaf", false); + + return newNode; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/component/RcTree_old.java b/smartservice_backend/src/main/java/com/handong/smartservice/component/RcTree_old.java new file mode 100644 index 0000000..27bee78 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/component/RcTree_old.java @@ -0,0 +1,108 @@ +package com.handong.smartservice.component; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RcTree_old { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static List> convertDb2RcTree(List> listTreeDb) { + RcTree_old rcTree = new RcTree_old(); + return rcTree.convert(listTreeDb); + } + + public Map searchTreeNode(List> listRcTree, String key) { + Map node = null; + + for(int i = 0; i < listRcTree.size(); i++) { + node = listRcTree.get(i); + if (key.compareTo((String)node.get("key")) == 0) { + return node; + } + + Object children = node.get("children"); + if (children != null) { + Map parentNode = searchTreeNode((List>)children, key); + if (parentNode != null) + return parentNode; + } + } + + return null; + } + + public List> convert(List> listTreeDb) { + List> listRcTree = new ArrayList>(); + listTreeDb.forEach(item -> { + Map newNode = new LinkedHashMap(); + + String biz_group_id = item.get("biz_group_id").toString(); + newNode.put("key", biz_group_id); + logger.debug("key(biz_group_id): " + biz_group_id); + + String name = (String)item.get("name"); + newNode.put("name", name); + + String biz_reg_num = (String)item.get("biz_reg_num"); + newNode.put("biz_reg_num", biz_reg_num); + + newNode.put("title", name + "(" + biz_reg_num + ")"); + logger.debug("title(name): " + name); + + Timestamp reg_time = (Timestamp)item.get("reg_time"); + if (reg_time != null) + newNode.put("reg_time", reg_time); + + String email = (String)item.get("email"); + if (email != null) + newNode.put("email", email); + + String phone = (String)item.get("phone"); + if (phone != null) + newNode.put("phone", phone); + + String ceo = (String)item.get("ceo"); + if (ceo != null) + newNode.put("ceo", ceo); + + String address = (String)item.get("address"); + if (address != null) + newNode.put("address", address); + + newNode.put("isLeaf", false); + + if (item.get("pid") == null || listRcTree.size() == 0) { + listRcTree.add(newNode); + } + else { + // search parent node + final String pid = item.get("pid") != null ? item.get("pid").toString() : ""; + logger.debug("pid = " + pid); + + Map parentNode = searchTreeNode(listRcTree, pid); + logger.debug("convert, parentNode = " + parentNode); + + if (parentNode != null) { + List> children = null; + Object childrenNode = parentNode.get("children"); + if (childrenNode == null) { + children = new ArrayList>(); + } + else { + children = (List>)childrenNode; + } + children.add(newNode); + parentNode.put("children", children); + } + } + }); + + return listRcTree; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/component/UserInfo.java b/smartservice_backend/src/main/java/com/handong/smartservice/component/UserInfo.java new file mode 100644 index 0000000..b0708b5 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/component/UserInfo.java @@ -0,0 +1,24 @@ +package com.handong.smartservice.component; + +public class UserInfo { + + private final Long gid; + private final String userId; + private final String nickName; + private final Long permission; + private final Long bizGroupId; + + public UserInfo(Long gid, String user_id, String nick_name, Number permission, Number bizGroupId) { + this.gid = gid; + this.userId = user_id; + this.nickName = nick_name; + this.permission = permission != null ? permission.longValue() : 0L; + this.bizGroupId = bizGroupId != null ? bizGroupId.longValue() : 0L; + } + + public Long getGid() { return gid; } + public String getUserId() { return userId; } + public String getNickName() { return nickName; } + public Long getPermission() { return permission; } + public Long getBizGroupId() { return bizGroupId; } +} \ No newline at end of file diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/IndexController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/IndexController.java new file mode 100644 index 0000000..5f9d2f7 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/IndexController.java @@ -0,0 +1,31 @@ +package com.handong.smartservice.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + + +@Controller +public class IndexController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @RequestMapping(value = {"/", "/index"}, method = RequestMethod.GET) + public String index(HttpServletRequest request, HttpServletResponse response) { + //logger.info("[TRACE] session : " + AppGlobal.sessionToMap(session).toString()); + + //if (session.getAttribute("account_id") == null) { + // session.invalidate(); + // return "redirect:/login"; + //} + + return "/index"; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/AccountController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/AccountController.java new file mode 100644 index 0000000..ee726a6 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/AccountController.java @@ -0,0 +1,122 @@ +package com.handong.smartservice.controller.api; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.bind.annotation.*; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtExcelMaker; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.mapper.AccountMapper; +import com.handong.smartservice.service.AccountService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + + +@RestController +@RequestMapping("/api") +class AccountController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final AccountService accountService; + + + public AccountController(AccountService accountService) { + this.accountService = accountService; + } + + @RequestMapping(value = "/get-account.do", method = RequestMethod.POST) + public CtResponse getAccountList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + Boolean is_excel = _AG.toBoolean(body.get("is_excel")); + + Boolean is_group_access = _AG.toBoolean(body.get("is_group_access")); + String nick_name = body.get("nick_name"); + String user_id = body.get("user_id"); + String email = body.get("email"); + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + + Map mapResult = accountService.getAccountList(offset, limit, date_start, date_end, is_excel, is_group_access, user_id, email, nick_name, biz_group_id); + + if (is_excel) { + List> list = (List>)mapResult.get("list"); + + for (Map item : list) { + item.replace("reg_time", _AG.timestampToStr(item.get("reg_time"))); + } + + String[] arrHeader = {"등록일", "그룹", "아이디", "닉네임", "이메일", "상태"}; + String[] arrColumn = {"reg_time", "biz_group_name", "user_id", "nick_name", "email", "state"}; + + CtExcelMaker.makeExcelResponse(request, response, "계정목록", arrHeader, arrColumn, list, null); + return null; + } + + result.put("result", mapResult); + return result; + } + + public CtResponse addOrModifyAccount(boolean isModify, HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + CtResponse result = new CtResponse(); + + Long gid = _AG.toLong(body.get("gid")); + String user_id = body.get("user_id"); + String user_pw = body.get("user_pw"); + String email = body.get("email"); + String nick_name = body.get("nick_name"); + Long state = _AG.toLong(body.get("state")); + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + Long new_biz_group_id = _AG.toLong(body.get("new_biz_group_id")); + + if (user_id == null || user_id.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + result = accountService.addOrModifyAccount(isModify, gid, user_id, user_pw, email, nick_name, state, biz_group_id, new_biz_group_id); + return result; + } + + @RequestMapping(value = "/add-account.do", method = RequestMethod.POST) + public CtResponse addAccount(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyAccount(false, request, response, body); + } + + @RequestMapping(value = "/modify-account.do", method = RequestMethod.POST) + public CtResponse modifyAccount(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyAccount(true, request, response, body); + } + + @RequestMapping(value = "/remove-account.do", method = RequestMethod.POST) + public CtResponse removeAccount(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + String ids = body.get("ids"); + + return accountService.removeAccount(ids); + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/AuthController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/AuthController.java new file mode 100644 index 0000000..4b94f37 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/AuthController.java @@ -0,0 +1,169 @@ +package com.handong.smartservice.controller.api; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseCookie; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.bind.annotation.*; + +import com.handong.smartservice._AG; +import com.handong.smartservice.JwtAuth.JwtProvider; +import com.handong.smartservice.component.CtErrorCode; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.component.UserInfo; +import com.handong.smartservice.service.AccountService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + + +@RestController +@RequestMapping("/api") +class AuthController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final AccountService accountService; + private final PasswordEncoder passwordEncoder; + private final JwtProvider jwtProvider; + + + public AuthController(AccountService accountService, PasswordEncoder passwordEncoder, JwtProvider jwtProvider) { + this.accountService = accountService; + this.passwordEncoder = passwordEncoder; + this.jwtProvider = jwtProvider; + } + + @RequestMapping(value = "/sign-in.do", method = RequestMethod.POST) + public CtResponse signIn(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + String user_id = body.get("id"); + String user_pw = body.get("pw"); + + logger.info("user_id = " + user_id); //TestComment + + CtResponse result = accountService.getAccount(0L, user_id); + Map mapAccount = (Map)result.get("result"); + + if (mapAccount == null) { // not found + result.setErrCode(ErrorCode.INVALID_USER); + return result; + } + + if ("2".equals(mapAccount.get("state"))) { // stopped user + result.setErrCode(ErrorCode.INVALID_USER); + return result; + } + + Long gid = (Long)mapAccount.get("gid"); + logger.info("gid: " + gid); + + String nick_name = (String)mapAccount.get("nick_name"); + Long permission = (Long)mapAccount.get("permission"); + Long biz_group_id = (Long)mapAccount.get("biz_group_id"); + String encPw = (String)mapAccount.get("user_pw"); + // 1 : $2a$10$HaPODuNOvfKE/MD0JxTrX.CxZ4zeGxjmcwaGE.jyx0KzWGQh3vVeG + // 1234: $2a$10$fg4gH81OiYVm3AItCvKQvOPWnRx8YsXHymIDJI88XCTKk/3Kah092 + + // password check + logger.info("------ enc pw: " + passwordEncoder.encode(user_pw)); + if (passwordEncoder.matches(user_pw, encPw) == false) { + result.setErrCode(ErrorCode.INVALID_USER); + return result; + } + + //mapAccount.put("sval1", jwtProvider.createAccessToken(gid, user_id, nick_name, permission, biz_group_id)); + mapAccount.put("sval1", jwtProvider.createAccessToken(gid, _AG.createUserInfoMap(user_id, nick_name, permission, biz_group_id))); + String refreshToken = jwtProvider.createRefreshToken(gid); + + /* + ResponseCookie cookie = ResponseCookie.from("sval2", refreshToken) + .httpOnly(true) + .secure(true) + .sameSite("Strict") + .path("/") + .maxAge(jwtProvider.getRefreshExpire()) + .build(); + */ + ResponseCookie cookie = ResponseCookie.from("sval2", refreshToken) + .httpOnly(true) + .secure(false) + .sameSite("Lax") + .path("/") + .build(); + response.addHeader("Set-Cookie", cookie.toString()); + + return result; + } + + @RequestMapping(value = "/sign-out.do", method = RequestMethod.POST) + public CtResponse signOut(HttpServletRequest request, HttpServletResponse response, + @RequestBody Map body, Authentication authentication) { + logger.info("req: " + request.getRequestURI()); + + Long gid = _AG.toLong(body.get("gid")); + UserInfo userInfo = (UserInfo)authentication.getPrincipal(); + + CtResponse result = new CtResponse(); + if (gid != userInfo.getGid()) { + result.setErrCode(CtErrorCode.UNCORRECT_DATA); + return result; + } + + jwtProvider.delete(gid); + + return result; + } + + @PostMapping("/sval2.do") // security value 2(token refresh) + public ResponseEntity tokenRefresh(HttpServletRequest request, @CookieValue(value = "sval2", required = false) String refreshToken) { + logger.info("req: " + request.getRequestURI()); + + if (refreshToken == null) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + + if (jwtProvider.isValidate(refreshToken) == false) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build(); + } + + Long gid = jwtProvider.getGid(refreshToken); + + logger.info("gid: " + gid); + + CtResponse result = accountService.getAccount(gid, null); + Map mapAccount = (Map)result.get("result"); + + if (mapAccount == null) { // not found + result.setErrCode(ErrorCode.INVALID_USER); + return ResponseEntity.ok(result); + } + + if ("2".equals(mapAccount.get("state"))) { // stopped user + result.setErrCode(ErrorCode.INVALID_USER); + return ResponseEntity.ok(result); + } + + String user_id = (String)mapAccount.get("user_id"); + String nick_name = (String)mapAccount.get("user_id"); + Long permission = (Long)mapAccount.get("permission"); + Long biz_group_id = (Long)mapAccount.get("biz_group_id"); + //String newAccessToken = jwtProvider.createAccessToken(gid, user_id, nick_name, permission, biz_group_id); + String newAccessToken = jwtProvider.createAccessToken(gid, _AG.createUserInfoMap(user_id, nick_name, permission, biz_group_id)); + + mapAccount.put("sval1", newAccessToken); + + return ResponseEntity.ok(result); + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/BizGroupController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/BizGroupController.java new file mode 100644 index 0000000..5a314e8 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/BizGroupController.java @@ -0,0 +1,154 @@ +package com.handong.smartservice.controller.api; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.bind.annotation.*; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.mapper.BizGroupMapper; +import com.handong.smartservice.service.BizGroupService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + + +@RestController +@RequestMapping("/api") +class BizGroupController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final BizGroupService bizGroupService; + + + public BizGroupController(BizGroupService bizGroupService) { + this.bizGroupService = bizGroupService; + } + + @RequestMapping(value = "/get-biz-group.do", method = RequestMethod.POST) + public CtResponse getBizGroupList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Long offset = _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + String name = body.get("name"); + + String biz_reg_num = body.get("biz_reg_num"); + if (biz_reg_num != null && biz_reg_num.isEmpty() == false) { + biz_reg_num = biz_reg_num.replaceAll("-", ""); + } + + String email = body.get("email"); + String phone = body.get("phone"); + String address = body.get("address"); + + Map mapResult = bizGroupService.getBizGroupList(offset, limit, date_start, date_end, name, biz_reg_num, email, phone, address); + result.put("result", mapResult); + return result; + } + + + public CtResponse addOrModifyBizGroup(boolean isModify, HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + CtResponse result = new CtResponse(); + + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + Long pid = _AG.toLong(body.get("pid")); + Long top_group_id = _AG.toLong(body.get("top_group_id")); + String name = body.get("name"); + + + String biz_reg_num = body.get("biz_reg_num"); + + if (biz_reg_num != null && biz_reg_num.isEmpty() == false) { + biz_reg_num = biz_reg_num.replaceAll("-", ""); + if (_AG.isValidBusinessNumber(biz_reg_num) == false) { + result.setErrCode(ErrorCode.INVALID_BIZ_REG_NUM); + return result; + } + } + + String email = body.get("email"); + String phone = body.get("phone"); + String ceo = body.get("ceo"); + String address = body.get("address"); + + //if (name == null || name.isEmpty() || biz_reg_num == null || biz_reg_num.isEmpty()) { + if (name == null || name.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + result = bizGroupService.addOrModifyBizGroup(isModify, biz_group_id, pid, top_group_id, name, biz_reg_num, email, phone, ceo, address); + return result; + } + + @RequestMapping(value = "/add-biz-group.do", method = RequestMethod.POST) + public CtResponse addBizGroup(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyBizGroup(false, request, response, body); + } + + @RequestMapping(value = "/modify-biz-group.do", method = RequestMethod.POST) + public CtResponse modifyBizGroup(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyBizGroup(true, request, response, body); + } + + @RequestMapping(value = "/remove-biz-group.do", method = RequestMethod.POST) + public CtResponse removeBizGroup(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + String ids = body.get("ids"); + + CtResponse result = bizGroupService.removeBizGroup(ids); + return result; + } + + + // ver 2 + @RequestMapping(value = "/get-biz-group2.do", method = RequestMethod.POST) + public CtResponse getBizGroup2(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + Boolean isRoot = _AG.toBoolean(body.get("isRoot")); + Long pid = _AG.toLong(body.get("pid")); + Long top_group_id = _AG.toLong(body.get("top_group_id")); + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + String name = body.get("name"); + + String biz_reg_num = body.get("biz_reg_num"); + if (biz_reg_num != null && biz_reg_num.isEmpty() == false) { + biz_reg_num = biz_reg_num.replaceAll("-", ""); + } + + return bizGroupService.getBizGroup2(isRoot, pid, top_group_id, date_start, date_end, name, biz_reg_num); + } + + @RequestMapping(value = "/get-biz-group3.do", method = RequestMethod.POST) + public CtResponse getBizGroup3(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + + return bizGroupService.getBizGroup3(biz_group_id); + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/DeviceController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/DeviceController.java new file mode 100644 index 0000000..636a093 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/DeviceController.java @@ -0,0 +1,150 @@ +package com.handong.smartservice.controller.api; + +import com.handong.smartservice.component.CtExcelMaker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.bind.annotation.*; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.service.DeviceService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + + +@RestController +@RequestMapping("/api") +class DeviceController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final DeviceService deviceService; + + + public DeviceController(DeviceService deviceService) { + this.deviceService = deviceService; + } + + @RequestMapping(value = "/get-device.do", method = RequestMethod.POST) + public CtResponse getDeviceList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Boolean is_excel = _AG.toBoolean(body.get("is_excel")); + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + Boolean is_group_access = _AG.toBoolean(body.get("is_group_access")); + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + String name = body.get("name"); + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + + Map mapResult = deviceService.getDeviceList(is_excel, offset, limit, is_group_access, biz_group_id, name, date_start, date_end); + + if (is_excel) { + List> list = (List>)mapResult.get("list"); + + for (Map item : list) { + item.replace("reg_time", _AG.timestampToStr(item.get("reg_time"))); + item.replace("connect_time", _AG.timestampToStr(item.get("connect_time"))); + item.replace("disconnect_time", _AG.timestampToStr(item.get("disconnect_time"))); + } + + String[] arrHeader = {"등록일", "그룹", "장치명", "단말기TID", "가동시간", "장애발생시간", "관리자"}; + String[] arrColumn = {"reg_time", "biz_group_name", "name", "uid1", "connect_time", "disconnect_time", "manager_name"}; + + CtExcelMaker.makeExcelResponse(request, response, "무인기기목록", arrHeader, arrColumn, list, null); + return null; + } + + result.put("result", mapResult); + return result; + } + + + public CtResponse addOrModifyDevice(boolean isModify, HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + //CtResponse result = new CtResponse(); + + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + Long new_biz_group_id = _AG.toLong(body.get("new_biz_group_id")); + Long device_id = _AG.toLong(body.get("device_id")); + Long terminal_id = _AG.toLong(body.get("terminal_id")); + String name = body.get("name"); + String uid1 = body.get("uid1"); + String manager_name = body.get("manager_name"); + + //if (name == null || name.isEmpty() || uid1 == null || uid1.isEmpty()) { + // result.setErrCode(ErrorCode.INVALID_PARAMETER); + // return result; + //} + + return deviceService.addOrModifyDevice(isModify, biz_group_id, new_biz_group_id, device_id, terminal_id, name, uid1, manager_name); + } + + @RequestMapping(value = "/add-device.do", method = RequestMethod.POST) + public CtResponse addDevice(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyDevice(false, request, response, body); + } + + @RequestMapping(value = "/modify-device.do", method = RequestMethod.POST) + public CtResponse modifyDevice(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyDevice(true, request, response, body); + } + + @RequestMapping(value = "/remove-device.do", method = RequestMethod.POST) + public CtResponse removeDevice(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + //String ids = body.get("ids"); + //CtResult result = deviceService.removeDevice(ids); + + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + Long device_id = _AG.toLong(body.get("device_id")); + + return deviceService.removeDevice(biz_group_id, device_id); + } + + @RequestMapping(value = "/config-device.do", method = RequestMethod.POST) + public CtResponse configDevice(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Long device_id = _AG.toLong(body.get("device_id")); + + Map mapResult = deviceService.configDevice(device_id); + result.put("result", mapResult); + return result; + } + + @RequestMapping(value = "/error-device.do", method = RequestMethod.POST) + public CtResponse selectDeviceByError(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + + Map mapResult = deviceService.selectDeviceByError(biz_group_id); + result.put("result", mapResult); + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/ErrorHistoryController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/ErrorHistoryController.java new file mode 100644 index 0000000..e72577b --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/ErrorHistoryController.java @@ -0,0 +1,83 @@ +package com.handong.smartservice.controller.api; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.service.ErrorHistoryService; +import com.handong.smartservice.service.VocService; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + + +@RestController +@RequestMapping("/api") +class ErrorHistoryController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final ErrorHistoryService errorHistoryService; + + + public ErrorHistoryController(ErrorHistoryService errorHistoryService) { + this.errorHistoryService = errorHistoryService; + } + + @RequestMapping(value = "/get-error-history.do", method = RequestMethod.POST) + public CtResponse getErrorHistory(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Boolean is_excel = _AG.toBoolean(body.get("is_excel")); + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + String uid1 = body.get("uid1"); + Long uid1_type = _AG.toLong(body.get("uid1_type")); + String slot = body.get("slot"); + + Map mapResult = errorHistoryService.getErrorHistoryList(is_excel, offset, limit, date_start, date_end, uid1, uid1_type, slot); + result.put("result", mapResult); + return result; + } + + @RequestMapping(value = "/get-miss.do", method = RequestMethod.POST) + public CtResponse getMiss(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Long state = _AG.toLong(body.get("state")); + + Map mapResult = errorHistoryService.getMiss(state); + result.put("result", mapResult); + return result; + } + + @RequestMapping(value = "/miss-slot.do", method = RequestMethod.POST) + public CtResponse missSlot(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + String uid1 = body.get("uid1"); + Long uid1_type = _AG.toLong(body.get("uid1_type")); + String slot = body.get("slot"); + + Map mapResult = errorHistoryService.missSlot(uid1, uid1_type, slot); + result.put("result", mapResult); + return result; + } + + +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/GoodsController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/GoodsController.java new file mode 100644 index 0000000..6a6e04c --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/GoodsController.java @@ -0,0 +1,295 @@ +package com.handong.smartservice.controller.api; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.*; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtExcelMaker; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.service.GoodsService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + + +@RestController +@RequestMapping("/api") +class GoodsController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final GoodsService goodsService; + + + public GoodsController(GoodsService goodsService) { + this.goodsService = goodsService; + } + + @RequestMapping(value = "/get-goods.do", method = RequestMethod.POST) + public CtResponse getGoodsList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Boolean is_excel = _AG.toBoolean(body.get("is_excel")); + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + Boolean is_group_access = _AG.toBoolean(body.get("is_group_access")); + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + Long device_id = _AG.toLong(body.get("device_id")); + Long state = _AG.toLong(body.get("state")); + String code = body.get("code"); + String name = body.get("name"); + String vendor = body.get("vendor"); + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + + Map mapResult = goodsService.getGoodsList(is_excel, offset, limit, is_group_access, biz_group_id, device_id, state, code, name, vendor, date_start, date_end); + + if (is_excel) { + List> list = (List>)mapResult.get("list"); + + for (Map item : list) { + item.replace("reg_time", _AG.timestampToStr(item.get("reg_time"))); + } + + String[] arrHeader = {"등록일", "사업자", "상품코드", "상품명", "가격", "공급사"}; + String[] arrColumn = {"reg_time", "biz_group_name", "code", "name", "price", "vendor"}; + + CtExcelMaker.makeExcelResponse(request, response, "상품목록", arrHeader, arrColumn, list, null); + return null; + } + + result.put("result", mapResult); + return result; + } + + public CtResponse addOrModifyGoods(boolean isModify, HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + CtResponse result = new CtResponse(); + + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + Long goods_id = _AG.toLong(body.get("goods_id")); + String code = body.get("code"); + String name = body.get("name"); + String vendor = body.get("vendor"); + Long price = _AG.toLongOrNull(body.get("price"));// nullable + Long inventory = _AG.toLongOrNull(body.get("inventory"));// nullable + + if (code == null || code.isEmpty() || name == null || name.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + result = goodsService.addOrModifyGoods(isModify, biz_group_id, goods_id, code, name, price, inventory, vendor); + return result; + } + + @RequestMapping(value = "/add-goods.do", method = RequestMethod.POST) + public CtResponse addGoods(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyGoods(false, request, response, body); + } + + @RequestMapping(value = "/modify-goods.do", method = RequestMethod.POST) + public CtResponse modifyGoods(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyGoods(true, request, response, body); + } + + @RequestMapping(value = "/remove-goods.do", method = RequestMethod.POST) + public CtResponse removeGoods(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + String ids = body.get("ids"); + + CtResponse result = goodsService.removeGoods(ids); + return result; + } + + // + @RequestMapping(value = "/get-device-goods.do", method = RequestMethod.POST) + public CtResponse getDeviceGoodsList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Long device_id = _AG.toLong(body.get("device_id")); + String slot = body.get("slot"); + Long goods_id = _AG.toLong(body.get("goods_id")); + + if (device_id == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + Map mapResult = goodsService.getDeviceGoodsList(device_id, slot, goods_id); + result.put("result", mapResult); + return result; + } + + @Transactional + @RequestMapping(value = "/manage-device-goods.do", method = RequestMethod.POST) + public CtResponse addOrModifyDeviceGoods(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + //logger.info("body: " + body); + //logger.info("prev_device_goods: " + body.get("prev_device_goods")); + //logger.info("new_device_goods: " + body.get("new_device_goods")); + + CtResponse result = new CtResponse(); + + Long device_id = _AG.toLong((Integer)body.get("device_id")); + List> prev_device_goods = (List>)body.get("prev_device_goods"); + List> new_device_goods = (List>)body.get("new_device_goods"); + + Long biz_group_id = _AG.toLong((Integer)body.get("biz_group_id")); + boolean isSaveTemplate = (boolean)body.get("isSaveTemplate"); + String templateName = (String)body.get("templateName"); + List> goods_template_elements = (List>)body.get("goods_template_elements"); + Map goods_template_inventory = (Map)body.get("goods_template_inventory"); + + if (device_id == null) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + try { + if (prev_device_goods != null && prev_device_goods.size() != 0) { + goodsService.deleteDeviceGoods(device_id, prev_device_goods); + } + + if (new_device_goods != null && new_device_goods.size() != 0) { + result = goodsService.addDeviceGoods(device_id, new_device_goods); + } + + if (isSaveTemplate) { + result = goodsService.addGoodsTemplate(biz_group_id, templateName, goods_template_inventory, goods_template_elements); + } + } + catch (Exception e) { + e.printStackTrace(); + result.setErrCode(ErrorCode.INVALID_PARAMETER); + } + return result; + } + + @RequestMapping(value="/get-goods-templates.do", method = RequestMethod.POST) + public CtResponse getGoodsTemplate(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Boolean is_excel = _AG.toBoolean(body.get("is_excel")); + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + Boolean is_group_access = _AG.toBoolean(body.get("is_group_access")); + + // goods_template_id 가 있으면 하나만 탐색 + // biz_group_id 가 있으면 모두 탐색 + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + Long goods_template_id = _AG.toLong(body.get("goods_template_id")); + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + + if (biz_group_id == 0 && goods_template_id == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + logger.info("biz_group_id: " + biz_group_id); + logger.info("goods_template_id: " + goods_template_id); + + try { + Map mapResult; + if (goods_template_id != 0) { + mapResult = goodsService.getGoodsTemplateById(goods_template_id); + } + else { + mapResult = goodsService.getGoodsTemplateByBizGroupId(biz_group_id); + } + result.put("result", mapResult); + } + catch (Exception e) { + e.printStackTrace(); + result.setErrCode(ErrorCode.INVALID_PARAMETER); + } + + return result; + } + + @Transactional + @RequestMapping(value="/manage-goods-template.do", method = RequestMethod.POST) + public CtResponse manageGoodsTemplate(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Long biz_group_id = _AG.toLong((Integer)body.get("biz_group_id")); + Long goods_template_id = _AG.toLong((Integer)body.get("goods_template_id")); + String goods_template_name = (String)body.get("goods_template_name"); + Map goods_template_inventory = (Map)body.get("goods_template_inventory"); + List> goods_template_elements = (List>)body.get("goods_template_elements"); + + if (biz_group_id == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + try { + if (goods_template_id != 0) { + result = goodsService.removeGoodsTemplate(goods_template_id); + } + + result = goodsService.addGoodsTemplate(biz_group_id, goods_template_name, goods_template_inventory, goods_template_elements); + } + catch (Exception e) { + e.printStackTrace(); + result.setErrCode(ErrorCode.INVALID_PARAMETER); + } + + return result; + } + + @Transactional + @RequestMapping(value="/remove-goods-template.do", method = RequestMethod.POST) + public CtResponse removeGoodsTemplate(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Long goods_template_id = _AG.toLong((Integer)body.get("goods_template_id")); + + if (goods_template_id == null) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + try { + result = goodsService.removeGoodsTemplate(goods_template_id); + } + catch (Exception e) { + e.printStackTrace(); + result.setErrCode(ErrorCode.INVALID_PARAMETER); + } + + return result; + } + +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/LocationController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/LocationController.java new file mode 100644 index 0000000..c5baf73 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/LocationController.java @@ -0,0 +1,119 @@ +package com.handong.smartservice.controller.api; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.bind.annotation.*; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.mapper.LocationMapper; +import com.handong.smartservice.service.LocationService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + + +@RestController +@RequestMapping("/api") +class LocationController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final LocationService locationService; + + + public LocationController(LocationService locationService) { + this.locationService = locationService; + } + + @RequestMapping(value = "/get-location.do", method = RequestMethod.POST) + public CtResponse getLocationList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Boolean is_excel = _AG.toBoolean(body.get("is_excel")); + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + String name = body.get("name"); + String description = body.get("description"); + String address = body.get("address"); + + Map mapResult = locationService.getLocationList(offset, limit, date_start, date_end, name, description, address); + result.put("result", mapResult); + return result; + } + + + public CtResponse addOrModifyLocation(boolean isModify, HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + CtResponse result = new CtResponse(); + + Long location_id = _AG.toLong(body.get("location_id")); + Long pid = _AG.toLong(body.get("pid")); + String name = body.get("name"); + String description = body.get("description"); + String address = body.get("address"); + + if (name == null || name.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + result = locationService.addOrModifyLocation(isModify, location_id, pid, name, description, address); + return result; + } + + @RequestMapping(value = "/add-location.do", method = RequestMethod.POST) + public CtResponse addLocation(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyLocation(false, request, response, body); + } + + @RequestMapping(value = "/modify-location.do", method = RequestMethod.POST) + public CtResponse modifyLocation(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyLocation(true, request, response, body); + } + + @RequestMapping(value = "/remove-location.do", method = RequestMethod.POST) + public CtResponse removeLocation(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + String ids = body.get("ids"); + + CtResponse result = locationService.removeLocation(ids); + return result; + } + + + // ver 2 + @RequestMapping(value = "/get-location2.do", method = RequestMethod.POST) + public CtResponse getLocation2(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + Boolean isRoot = _AG.toBoolean(body.get("isRoot")); + Long pid = _AG.toLong(body.get("id")); + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + String name = body.get("name"); + String description = body.get("description"); + String address = body.get("address"); + + return locationService.getLocation2(isRoot, pid, date_start, date_end, name, description, address); + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/NoticeController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/NoticeController.java new file mode 100644 index 0000000..3405876 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/NoticeController.java @@ -0,0 +1,101 @@ +package com.handong.smartservice.controller.api; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.service.NoticeService; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + + +@RestController +@RequestMapping("/api") +class NoticeController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final NoticeService noticeService; + + + public NoticeController(NoticeService noticeService) { + this.noticeService = noticeService; + } + + @RequestMapping(value = "/get-notice-detail.do", method = RequestMethod.POST) + public CtResponse getNoticeDetail(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + String notice_id = body.get("id"); + + CtResponse result = noticeService.getNoticeDetail(notice_id); + return result; + } + + @RequestMapping(value = "/get-notice.do", method = RequestMethod.POST) + public CtResponse getNoticeList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Boolean is_excel = _AG.toBoolean(body.get("is_excel")); + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + String title = body.get("title"); + String content = body.get("content"); + + Map mapResult = noticeService.getNoticeList(offset, limit, date_start, date_end, title, content); + result.put("result", mapResult); + return result; + } + + + public CtResponse addOrModifyNotice(boolean isModify, HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + CtResponse result = new CtResponse(); + + String notice_id = body.get("notice_id"); + String title = body.get("title"); + String content = body.get("content"); + + if (title == null || title.isEmpty() || content == null || content.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + result = noticeService.addOrModifyNotice(isModify, notice_id, title, content); + return result; + } + + @RequestMapping(value = "/add-notice.do", method = RequestMethod.POST) + public CtResponse addNotice(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyNotice(false, request, response, body); + } + + @RequestMapping(value = "/modify-notice.do", method = RequestMethod.POST) + public CtResponse modifyNotice(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyNotice(true, request, response, body); + } + + @RequestMapping(value = "/remove-notice.do", method = RequestMethod.POST) + public CtResponse removeNotice(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + String ids = body.get("ids"); + + CtResponse result = noticeService.removeNotice(ids); + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/OperatingHistoryController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/OperatingHistoryController.java new file mode 100644 index 0000000..da0a9dc --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/OperatingHistoryController.java @@ -0,0 +1,52 @@ +package com.handong.smartservice.controller.api; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.service.OperatingHistoryService; +import com.handong.smartservice.service.VocService; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + + +@RestController +@RequestMapping("/api") +class OperatingHistoryController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final OperatingHistoryService operatingHistoryService; + + + public OperatingHistoryController(OperatingHistoryService operatingHistoryService) { + this.operatingHistoryService = operatingHistoryService; + } + + @RequestMapping(value = "/get-operating-history.do", method = RequestMethod.POST) + public CtResponse getOperatingHistory(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Boolean is_excel = _AG.toBoolean(body.get("is_excel")); + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + Long type = _AG.toLong(body.get("type")); + String action = body.get("action"); + + Map mapResult = operatingHistoryService.getOperatingHistoryList(is_excel, offset, limit, date_start, date_end, type, action); + result.put("result", mapResult); + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/ResourceBoardController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/ResourceBoardController.java new file mode 100644 index 0000000..07dad76 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/ResourceBoardController.java @@ -0,0 +1,108 @@ +package com.handong.smartservice.controller.api; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.bind.annotation.*; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.service.ResourceBoardService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + + +@RestController +@RequestMapping("/api") +class ResourceBoardController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final ResourceBoardService resourceBoardService; + + + public ResourceBoardController(ResourceBoardService resourceBoardService) { + this.resourceBoardService = resourceBoardService; + } + + @RequestMapping(value = "/get-resource-board-detail.do", method = RequestMethod.POST) + public CtResponse getResourceBoardDetail(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + String resource_board_id = body.get("id"); + + CtResponse result = resourceBoardService.getResourceBoardDetail(resource_board_id); + return result; + } + + @RequestMapping(value = "/get-resource-board.do", method = RequestMethod.POST) + public CtResponse getResourceBoardList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + String title = body.get("title"); + String content = body.get("content"); + + Map mapResult = resourceBoardService.getResourceBoardList(offset, limit, date_start, date_end, title, content); + result.put("result", mapResult); + return result; + } + + + public CtResponse addOrModifyResourceBoard(boolean isModify, HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + CtResponse result = new CtResponse(); + + String resource_board_id = body.get("resource_board_id"); + String title = body.get("title"); + String content = body.get("content"); + + if (title == null || title.isEmpty() || content == null || content.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + result = resourceBoardService.addOrModifyResourceBoard(isModify, resource_board_id, title, content); + return result; + } + + @RequestMapping(value = "/add-resource-board.do", method = RequestMethod.POST) + public CtResponse addResourceBoard(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyResourceBoard(false, request, response, body); + } + + @RequestMapping(value = "/modify-resource-board.do", method = RequestMethod.POST) + public CtResponse modifyResourceBoard(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyResourceBoard(true, request, response, body); + } + + @RequestMapping(value = "/remove-resource-board.do", method = RequestMethod.POST) + public CtResponse removeResourceBoard(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + String ids = body.get("ids"); + + CtResponse result = resourceBoardService.removeResourceBoard(ids); + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/SalesController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/SalesController.java new file mode 100644 index 0000000..fee74d2 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/SalesController.java @@ -0,0 +1,75 @@ +package com.handong.smartservice.controller.api; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.bind.annotation.*; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtExcelMaker; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.service.SalesService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + + +@RestController +@RequestMapping("/api") +class SalesController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final SalesService salesService; + + + public SalesController(SalesService salesService) { + this.salesService = salesService; + } + + @RequestMapping(value = "/get-sales.do", method = RequestMethod.POST) + public CtResponse getSalesList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Boolean is_excel = _AG.toBoolean(body.get("is_excel")); + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + Boolean is_group_access = _AG.toBoolean(body.get("is_group_access")); + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + String uid1 = body.get("uid1"); + String device_name = body.get("device_name"); + Long approval_type = _AG.toLong(body.get("approval_type")); + Long date_type = _AG.toLong(body.get("date_type")); + + Map mapResult = salesService.getSalesList(is_excel, offset, limit, is_group_access, biz_group_id, date_start, date_end, + uid1, device_name, approval_type, date_type); + + if (is_excel) { + List> list = (List>)mapResult.get("list"); + + String[] arrHeader = {"날짜", "무인기기명", "단말기TID", "카드건수", "카드금액", "현금건수", "현금금액", "T머니건수", "T머니금액", "캐시비건수", "캐시비금액", "합계"}; + String[] arrColumn = {"date", "device_name", "uid1", "card_count", "card_amount", "cash_count", "cash_amount", "tmoney_count", "tmoney_amount", "cbee_count", "cbee_amount", "total"}; + + CtExcelMaker.makeExcelResponse(request, response, "매출집계", arrHeader, arrColumn, list, null); + return null; + } + + result.put("result", mapResult); + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/TerminalController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/TerminalController.java new file mode 100644 index 0000000..e2386c3 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/TerminalController.java @@ -0,0 +1,132 @@ +package com.handong.smartservice.controller.api; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.bind.annotation.*; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtExcelMaker; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.service.TerminalService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + + +@RestController +@RequestMapping("/api") +class TerminalController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final TerminalService terminalService; + + + public TerminalController(TerminalService terminalService) { + this.terminalService = terminalService; + } + + @RequestMapping(value = "/get-terminal.do", method = RequestMethod.POST) + public CtResponse getTerminalList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Boolean is_excel = _AG.toBoolean(body.get("is_excel")); + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + Boolean is_group_access = _AG.toBoolean(body.get("is_group_access")); + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + Long state = _AG.toLong(body.get("state")); + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + + Map mapResult = terminalService.getTerminalList(is_excel, offset, limit, is_group_access, biz_group_id, state, date_start, date_end); + + if (is_excel) { + List> list = (List>)mapResult.get("list"); + + for (Map item : list) { + item.replace("reg_time", _AG.timestampToStr(item.get("reg_time"))); + } + + String[] arrHeader = {"등록일", "사업자", "기기명", "단말기 TID", "무인기기 장착 여부"}; + String[] arrColumn = {"reg_time", "biz_group_name", "name", "uid1", "state"}; + + CtExcelMaker.makeExcelResponse(request, response, "카드단말기목록", arrHeader, arrColumn, list, null); + return null; + } + + result.put("result", mapResult); + return result; + } + + + public CtResponse addOrModifyTerminal(boolean isModify, HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + CtResponse result = new CtResponse(); + + Long addType = _AG.toLong(body.get("addType")); + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + Long terminal_id = _AG.toLong(body.get("terminal_id")); + String name = body.get("name"); + String uid1 = body.get("uid1"); + Long type = _AG.toLong(body.get("type")); + + if (name == null || name.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + return terminalService.addOrModifyTerminal(isModify, addType, biz_group_id, terminal_id, name, uid1, type); + } + + @RequestMapping(value = "/add-terminal.do", method = RequestMethod.POST) + public CtResponse addTerminal(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyTerminal(false, request, response, body); + } + + @RequestMapping(value = "/modify-terminal.do", method = RequestMethod.POST) + public CtResponse modifyTerminal(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyTerminal(true, request, response, body); + } + + @RequestMapping(value = "/remove-terminal.do", method = RequestMethod.POST) + public CtResponse removeTerminal(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + //String ids = body.get("ids"); + //CtResult result = terminalService.removeTerminal(ids); + + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + Long terminal_id = _AG.toLong(body.get("terminal_id")); + + return terminalService.removeTerminal(biz_group_id, terminal_id); + } + + @RequestMapping(value = "/terminal-state.do", method = RequestMethod.POST) + public CtResponse terminalState(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + String uid1 = body.get("uid1"); + Long type = _AG.toLong(body.get("type")); + Long state = _AG.toLong(body.get("state")); + + return terminalService.terminalState(uid1, type, state); + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/TransactionController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/TransactionController.java new file mode 100644 index 0000000..7cfbdc7 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/TransactionController.java @@ -0,0 +1,160 @@ +package com.handong.smartservice.controller.api; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.web.bind.annotation.*; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtExcelMaker; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.mapper.TransactionMapper; +import com.handong.smartservice.service.TransactionService; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; + + +import java.util.List; +import java.util.Map; +import java.util.HashMap; + + +@RestController +@RequestMapping("/api") +class TransactionController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final TransactionService transactionService; + + + public TransactionController(TransactionService transactionService) { + this.transactionService = transactionService; + } + + @RequestMapping(value = "/get-transaction.do", method = RequestMethod.POST) + public CtResponse getTransactionList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Boolean is_excel = _AG.toBoolean(body.get("is_excel")); + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + Boolean is_group_access = _AG.toBoolean(body.get("is_group_access")); + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + Long biz_group_id = _AG.toLong(body.get("biz_group_id")); + String uid1 = body.get("uid1"); + Long uid1_type = _AG.toLong(body.get("uid1_type")); + String type = body.get("type"); + Long amount = _AG.toLong(body.get("amount")); + String approval = body.get("approval"); + String pay_name = body.get("pay_name"); + String pay_vendor = body.get("pay_vendor"); + String slot = body.get("slot"); + String code = body.get("code"); + String goods_name = body.get("goods_name"); + + Map mapResult = transactionService.getTransactionList(is_excel, offset, limit, is_group_access, biz_group_id, date_start, date_end, + uid1, uid1_type, type, amount, approval, pay_name, pay_vendor, slot, code, goods_name); + + if (is_excel) { + List> list = (List>)mapResult.get("list"); + + for (Map item : list) { + item.replace("order_time", _AG.timestampToStr(item.get("order_time"))); + } + + String[] arrHeader = {"거래시간", "단말기 TID", "금액", "결제유형", "승인번호", "컬럼번호", "상품코드", "상품명", "결제서비스업체"}; + String[] arrColumn = {"order_time", "uid1", "amount", "type", "approval", "slot", "code", "goods_name", "pay_vendor"}; + + CtExcelMaker.makeExcelResponse(request, response, "거래내역목록", arrHeader, arrColumn, list, null); + return null; + } + + result.put("result", mapResult); + return result; + } + + @RequestMapping(value = "/get-u-transaction.do", method = RequestMethod.POST) + public CtResponse getUndefinedTransactionList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Boolean is_excel = _AG.toBoolean(body.get("is_excel")); + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + String uid1 = body.get("uid1"); + Long uid1_type = _AG.toLong(body.get("uid1_type")); + String type = body.get("type"); + Long amount = _AG.toLong(body.get("amount")); + String approval = body.get("approval"); + String pay_name = body.get("pay_name"); + String pay_vendor = body.get("pay_vendor"); + String slot = body.get("slot"); + String code = body.get("code"); + String goods_name = body.get("goods_name"); + + Map mapResult = transactionService.getUndefinedTransactionList(is_excel, offset, limit, date_start, date_end, + uid1, uid1_type, type, amount, approval, pay_name, pay_vendor, slot, code, goods_name); + result.put("result", mapResult); + return result; + } + + @RequestMapping(value = "/add-transaction.do", method = RequestMethod.POST) + public CtResponse addTransaction(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + /* + curl -X POST http://localhost:18080/api/add-transaction.do \ + -H "Content-Type: application/json" \ + -d '{ + "uid1": "123", + "uid1_type": "1", + "type": "D1", + "amount": "900", + "approval": "33", + "pay_name": " HANA", + "pay_vendor": "HANA", + "slot": "01" + }' + */ + + CtResponse result = new CtResponse(); + + String uid1 = body.get("uid1"); + Long uid1_type = _AG.toLong(body.get("uid1_type")); + String type = body.get("type"); + Long amount = _AG.toLong(body.get("amount")); + String approval = body.get("approval"); + String pay_name = body.get("pay_name"); + String pay_vendor = body.get("pay_vendor"); + String slot = body.get("slot"); + //String code = body.get("code"); + //String goods_name = body.get("goods_name"); + String pay_unique_num = body.get("pay_unique_num"); + String pay_order_time = body.get("pay_order_time"); + + if (uid1 == null || uid1_type == null || type == null || amount == null || slot == null) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + result = transactionService.addTransaction(uid1, uid1_type, type, amount, approval, pay_name, pay_vendor, slot, pay_unique_num, pay_order_time); + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/VocController.java b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/VocController.java new file mode 100644 index 0000000..cfe9e5b --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/controller/api/VocController.java @@ -0,0 +1,102 @@ +package com.handong.smartservice.controller.api; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.service.VocService; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.Map; + + +@RestController +@RequestMapping("/api") +class VocController { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final VocService vocService; + + + public VocController(VocService vocService) { + this.vocService = vocService; + } + + @RequestMapping(value = "/get-voc-detail.do", method = RequestMethod.POST) + public CtResponse getVocDetail(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + String voc_id = body.get("id"); + + CtResponse result = vocService.getVocDetail(voc_id); + return result; + } + + @RequestMapping(value = "/get-voc.do", method = RequestMethod.POST) + public CtResponse getVocList(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + CtResponse result = new CtResponse(); + + Long offset= _AG.toLong(body.get("offset")); + Long limit = _AG.toLong(body.get("limit")); + if (limit > 100) + limit = 100L; + + String date_start = body.get("date_start"); + String date_end = body.get("date_end"); + String title = body.get("title"); + String content = body.get("content"); + String process = body.get("process"); + + Map mapResult = vocService.getVocList(offset, limit, date_start, date_end, title, content, process); + result.put("result", mapResult); + return result; + } + + + public CtResponse addOrModifyVoc(boolean isModify, HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + CtResponse result = new CtResponse(); + + String voc_id = body.get("voc_id"); + String title = body.get("title"); + String content = body.get("content"); + + if (title == null || title.isEmpty() || content == null || content.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + result = vocService.addOrModifyVoc(isModify, voc_id, title, content); + return result; + } + + @RequestMapping(value = "/add-voc.do", method = RequestMethod.POST) + public CtResponse addVoc(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyVoc(false, request, response, body); + } + + @RequestMapping(value = "/modify-voc.do", method = RequestMethod.POST) + public CtResponse modifyVoc(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + return addOrModifyVoc(true, request, response, body); + } + + @RequestMapping(value = "/remove-voc.do", method = RequestMethod.POST) + public CtResponse removeVoc(HttpServletRequest request, HttpServletResponse response, @RequestBody Map body) { + logger.info("req: " + request.getRequestURI()); + + String ids = body.get("ids"); + + CtResponse result = vocService.removeVoc(ids); + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/AccountMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/AccountMapper.java new file mode 100644 index 0000000..7ad977e --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/AccountMapper.java @@ -0,0 +1,23 @@ +package com.handong.smartservice.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface AccountMapper { + + List> selectAccount(Boolean isCount, Boolean is_excel, Long offset, Long limit, + String date_start, String date_end, Long gid, String user_id, String email, String nick_name, Long biz_group_id); + + List> selectAccount2(Boolean isCount, Long offset, Long limit, + String date_start, String date_end, Boolean is_excel, Long gid, String user_id, String email, String nick_name, Long biz_group_id); + + int insertAccount(Map params); + + int updateAccount(Long gid, String user_pw, String nick_name, String email, Long state, Long biz_group_id); + + int changeState(List ids, int state); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/BizGroupMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/BizGroupMapper.java new file mode 100644 index 0000000..b011c1c --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/BizGroupMapper.java @@ -0,0 +1,53 @@ +package com.handong.smartservice.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface BizGroupMapper { + List> selectBizGroup(Long biz_group_id, Boolean isCount, Long offset, Long limit, + String date_start, String date_end, + String name, String biz_reg_num, String email, + String phone, String address); + + Map selectExistBizGroup(Long biz_group_id, String biz_reg_num); + + Map selectBizGroupByDeviceId(Long device_id); + Map selectBizGroupByTerminalId(Long terminal_id); + + //int insertBizGroup(Long pid, String name, String biz_reg_num, Long gid, String email, + // String phone, String ceo, String address); + int insertBizGroup(Map params); + + int updateBizGroup(Long biz_group_id, Long pid, String name, String biz_reg_num, String email, + String phone, String ceo, String address); + + //int deleteBizGroup(List ids); + int changeStateBizGroup(List ids, int state); + + int changePidBizGroup(List pids, Long new_pid); + + List> selectBizGroupParentTree(List ids); + + // ver2 + List> selectRootNode(boolean isDbRoot, Long top_group_id, String date_start, String date_end, + String name, String biz_reg_num); + + List> selectBizGroupChildTree(boolean queryAll, Long pid, Long top_group_id, String date_start, String date_end, + String name, String biz_reg_num); + + List> selectBizGroupTree(boolean queryAll, Long biz_group_id, String date_start, String date_end, + String name, String biz_reg_num); + + // get ids + List selectBizGroupDownwardIds(Long biz_group_id); + List selectBizGroupDownwardIdsByTerminalId(Long terminal_id); + List selectBizGroupDownwardIdsByDeviceId(Long device_id); + + List selectBizGroupUpwardIds(Long biz_group_id); + List selectBizGroupUpwardIdsByTerminalId(Long terminal_id); + List selectBizGroupUpwardIdsByDeviceId(Long device_id); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/DeviceMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/DeviceMapper.java new file mode 100644 index 0000000..7c197b0 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/DeviceMapper.java @@ -0,0 +1,39 @@ +package com.handong.smartservice.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +@Mapper +public interface DeviceMapper { + List> selectDevice(Boolean isCount, boolean is_excel, Long offset, Long limit, Boolean is_group_access, + Long biz_group_id, String name, String date_start, String date_end); + + List> selectDevice2(Boolean isCount, boolean is_excel, Long offset, Long limit, + Long biz_group_id, String name, String date_start, String date_end); + + Map selectDeviceById(Long device_id); + + Map selectExistDevice(Long device_id, String name); + + int insertDevice(Map params); + + int updateDevice(Long device_id, Long terminal_id, String name, String uid1, String manager_name, Long gid); + + int updateDeviceTerminalTime(Long device_id, LocalDateTime connect_time, LocalDateTime disconnect_time); + + int changeStateDevice(List ids, int state); + + //int deleteDevice(List ids); + int deleteDevice(Long device_id); + + // + int insertDeviceBizGroup(Long biz_group_id, Long device_id); + + int deleteDeviceBizGroup(Long biz_group_id, Long device_id); + + List> selectDeviceByError(Long biz_group_id); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/ErrorHistoryMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/ErrorHistoryMapper.java new file mode 100644 index 0000000..bff416b --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/ErrorHistoryMapper.java @@ -0,0 +1,17 @@ +package com.handong.smartservice.mapper; + +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; +import java.util.Map; + + +@Mapper +public interface ErrorHistoryMapper { + List> selectErrorHistory(Boolean isCount, Boolean is_excel, Long offset, Long limit, + String date_start, String date_end, String uid1, Long uid1_type, String slot); + + List> selectErrorHistoryByState(Long state); + + int insertErrorHistory(String uid1, Long uid1_type, String slot); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/GoodsMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/GoodsMapper.java new file mode 100644 index 0000000..bb2250d --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/GoodsMapper.java @@ -0,0 +1,44 @@ +package com.handong.smartservice.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface GoodsMapper { + List> selectGoods(Boolean isCount, Boolean is_excel, Long offset, Long limit, Boolean is_group_access, Long biz_group_id, Long device_id, + Long state, String code, String name, String vendor, String date_start, String date_end); + + List> selectGoodsByBizGroupId(Long biz_group_id); + List> selectGoodsByDevice(Boolean is_group_access, Long device_id); + + Map selectExistGoods(Long biz_group_id, String code, String name); + + Map selectGoodsByUid1(String uid1, Long uid1_type, String slot); + + int insertGoods(Map params); + + int updateGoods(Long biz_group_id, Long goods_id, String code, String name, Long price, Long inventory, String vendor, Long gid); + + int deleteGoods(List ids); + + // + List> selectDeviceGoods(Long device_id, String slot, Long goods_id); + int insertDeviceGoods(Long device_id, List> device_goods); + int updateDeviceGoodsPlusInventory(String approval); + int updateDeviceGoodsMinusInventory(Long device_id, String slot); + int deleteDeviceGoods(Long device_id, List> device_goods); + + List> selectGoodsTemplateByBizGroupId(Long biz_group_id); + List> selectGoodsTemplateById(Long goods_template_id); + + Long selectGoodsTemplateCount(Long biz_group_id); + int insertGoodsTemplate(Map params); + int insertGoodsTemplateElements(Long goods_template_id, List> goods_template_elements); + + int updateGoodsTemplate(Long goods_template_id, String name); + int deleteGoodsTemplateElements(Long goods_template_id); + int deleteGoodsTemplate(Long goods_template_id); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/LocationMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/LocationMapper.java new file mode 100644 index 0000000..69aa53a --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/LocationMapper.java @@ -0,0 +1,31 @@ +package com.handong.smartservice.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface LocationMapper { + List> selectLocation(Boolean isCount, Long offset, Long limit, + String date_start, String date_end, String name, String description, String address); + + int insertLocation(Map params); + + int updateLocation(Long location_id, Long pid, String name, + String description, String address); + + int changeStateLocation(List ids, int state); + + int changePidLocation(List pids, Long new_pid); + + List> selectLocationParentTree(List ids); + + // ver2 + List> selectRootNode(boolean isDbRoot, String date_start, String date_end, + String name, String description, String address); + + List> selectLocationChildTree(boolean queryAll, Long pid, String date_start, String date_end, + String name, String description, String address); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/NoticeMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/NoticeMapper.java new file mode 100644 index 0000000..684dba9 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/NoticeMapper.java @@ -0,0 +1,22 @@ +package com.handong.smartservice.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface NoticeMapper { + Map selectDetailNotice(String notice_id); + + List> selectNotice(Boolean isCount, Long offset, Long limit, + String date_start, String date_end, String title, String content); + + int insertNotice(String title, String content, Long gid); + + int updateNotice(Long biz_group_id, String title, String content); + + //int deleteNotice(List ids); + int changeStateNotice(List ids, int state); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/OperatingHistoryMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/OperatingHistoryMapper.java new file mode 100644 index 0000000..015a1be --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/OperatingHistoryMapper.java @@ -0,0 +1,15 @@ +package com.handong.smartservice.mapper; + +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; +import java.util.Map; + + +@Mapper +public interface OperatingHistoryMapper { + List> selectOperatingHistory(Boolean isCount, Boolean is_excel, Long offset, Long limit, + String date_start, String date_end, Long type, String action); + + int insertOperatingHistory(Long type, String action, Long gid); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/ResourceBoardMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/ResourceBoardMapper.java new file mode 100644 index 0000000..5939342 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/ResourceBoardMapper.java @@ -0,0 +1,23 @@ +package com.handong.smartservice.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface ResourceBoardMapper { + Map selectDetailResourceBoard(String resource_board_id); + + List> selectResourceBoard(Boolean isCount, Long offset, Long limit, + String date_start, String date_end, + String title, String content); + + int insertResourceBoard(String title, String content, Long gid); + + int updateResourceBoard(Long resource_board_id, String title, String content); + + //int deleteResourceBoard(List ids); + int changeStateResourceBoard(List ids, int state); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/TerminalMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/TerminalMapper.java new file mode 100644 index 0000000..f9f797e --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/TerminalMapper.java @@ -0,0 +1,46 @@ +package com.handong.smartservice.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import com.handong.smartservice.component.CtResponse; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface TerminalMapper { + List> selectTerminal(Boolean isCount, Boolean is_excel, Long offset, Long limit, Boolean is_group_access, + Long biz_group_id, String name, Long state, String date_start, String date_end); + + Map selectTerminalById(Long terminal_id); + + Map selectTerminalByDeviceId(Long device_id); + + Map selectTerminal3(String uid1, Long type); + + Map selectExistTerminal(String name, String uid1, Long type); + + int insertTerminal(Map params); + + int updateTerminal(Long terminal_id, String name, String uid1, Long type, String manager_name, Long gid); + + int updateTerminalChangeDevice(Long terminal_id, Long device_id, Long state, String name); + int updateTerminalRemoveDevice(Long device_id); + + int changeStateTerminal(Long terminal_id, int state); + int changeStateTerminals(List ids, int state); + + int changeStateDeviceTerminal(Long device_id, int state); + + //int deleteTerminal(List ids); + int deleteTerminal(Long terminal_id); + + // + int insertTerminalBizGroup(Long biz_group_id, Long terminal_id); + + int deleteTerminalBizGroup(Long biz_group_id, Long terminal_id); + + // + int terminalState(String uid1, Long type, Long state); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/TransactionMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/TransactionMapper.java new file mode 100644 index 0000000..60a764b --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/TransactionMapper.java @@ -0,0 +1,27 @@ +package com.handong.smartservice.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +@Mapper +public interface TransactionMapper { + + List> selectTransaction(Boolean isCount, Boolean is_excel, Long offset, Long limit, Boolean is_group_access, + Long biz_group_id, String date_start, String date_end, String uid1, Long uid1_type, String type, Long amount, + String approval, String pay_name, String pay_vendor, String slot, String code, String goods_name); + + List> selectTransactionBizGroup0(Boolean isCount, Boolean is_excel, Long offset, Long limit, + String date_start, String date_end, String uid1, Long uid1_type, String type, Long amount, String approval, + String pay_name, String pay_vendor, String slot, String code, String goods_name); + + List> selectTransaction2(Boolean isCount, Boolean is_excel, Long offset, Long limit, Boolean is_group_access, + Long biz_group_id, String date_start, String date_end, String uid1); + + List> selectTransaction3(Boolean isCount, Boolean is_excel, Long offset, Long limit, Boolean is_group_access, + Long biz_group_id, String date_start, String date_end, String uid1, String device_name, Long approval_type, Long date_type); + + int insertTransaction(Map params); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/mapper/VocMapper.java b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/VocMapper.java new file mode 100644 index 0000000..2de264d --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/mapper/VocMapper.java @@ -0,0 +1,23 @@ +package com.handong.smartservice.mapper; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + + +@Mapper +public interface VocMapper { + Map selectDetailVoc(String voc_id); + + List> selectVoc(Boolean isCount, Long offset, Long limit, + String date_start, String date_end, String title, String content, String process); + + int insertVoc(String title, String content, Long gid); + + int updateVoc(Long biz_group_id, String title, String content); + + //int deleteVoc(List ids); + int changeStateVoc(List ids, int state); +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/AccountService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/AccountService.java new file mode 100644 index 0000000..d5ae1ca --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/AccountService.java @@ -0,0 +1,137 @@ +package com.handong.smartservice.service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.DbLogger; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.component.UserInfo; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import com.handong.smartservice.mapper.AccountMapper; + + +@Service +public class AccountService { + private final AccountMapper accountMapper; + private final PasswordEncoder passwordEncoder; + + public AccountService(AccountMapper accountMapper, PasswordEncoder passwordEncoder) { + this.accountMapper = accountMapper; + this.passwordEncoder = passwordEncoder; + } + + public CtResponse getAccount(Long gid, String user_id) { + CtResponse result = new CtResponse(); + if (gid != 0L && user_id != null && user_id.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + List> listMap = (List>)accountMapper.selectAccount(false, false, 0L, 1L, + null, null, gid, user_id, null, null, 0L); + + if (listMap.size() == 0) + result.put("result", null); + else + result.put("result", listMap.get(0)); + + return result; + } + + public Map getAccountList(Long offset, Long limit, String date_start, String date_end, Boolean is_excel, Boolean is_group_access, String user_id, String email, String nick_name, Long biz_group_id) { + Map mapResult = new HashMap<>(); + + //if (is_group_access) { + + List> listMap = (List>)accountMapper.selectAccount2(false, offset, limit, + date_start, date_end, is_excel, 0L, user_id, email, nick_name, biz_group_id); + mapResult.put("list", listMap); + + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", accountMapper.selectAccount2(true, offset, limit, + date_start, date_end, is_excel, 0L, user_id, email, nick_name, biz_group_id)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + return mapResult; + } + + public CtResponse addOrModifyAccount(boolean isModify, Long gid, String user_id, String user_pw, String email, String nick_name, Long state, Long biz_group_id, Long new_biz_group_id) { + CtResponse result = new CtResponse(); + + UserInfo userInfo = (UserInfo)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + + String enc_pw = passwordEncoder.encode(user_pw); + + if (new_biz_group_id != 0 && new_biz_group_id != biz_group_id) + biz_group_id = new_biz_group_id; + + if (isModify) { + if (gid == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + //accountMapper.updateAccount(gid, user_pw, nick_name, email, state, biz_group_id); + accountMapper.updateAccount(gid, enc_pw, nick_name, email, state, biz_group_id); + DbLogger.insert(2L, "계정정보 수정", userInfo.getGid()); + } + else { + if (user_id == null || user_id.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + Map params = new HashMap<>(); + params.put("user_id", user_id); + //params.put("user_pw", user_pw); + params.put("user_pw", enc_pw); + params.put("nick_name", nick_name); + params.put("email", email); + params.put("state", state); + params.put("biz_group_id", biz_group_id); + + if (biz_group_id == 667) //TempCode + params.put("permission", 1L); + else + params.put("permission", 2L); + + if (accountMapper.insertAccount(params) == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + } + else { + DbLogger.insert(2L, "신규 계정 추가, id: " + user_id, userInfo.getGid()); + //result.put("result", Map.of("gid", params.get("gid"))); + Map ret = new HashMap(); + ret.put("gid", params.get("gid")); + result.put("result", ret); + } + } + + return result; + } + + public CtResponse removeAccount(String ids) { + CtResponse result = new CtResponse(); + + List arrId = Arrays.stream(ids.split(",")) + .map(Long::parseLong) + .collect(Collectors.toList()); + + int changed = accountMapper.changeState(arrId, 2); + if (changed == 0) { + result.setErrCode(ErrorCode.QUERY_ERROR); + } + DbLogger.insert(2L, "계정 삭제, id: " + ids, 2L); + + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/BizGroupService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/BizGroupService.java new file mode 100644 index 0000000..a753758 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/BizGroupService.java @@ -0,0 +1,158 @@ +package com.handong.smartservice.service; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.apache.ibatis.jdbc.SQL; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.DbLogger; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.component.RcTreeBizGroup; +import com.handong.smartservice.mapper.BizGroupMapper; +import com.handong.smartservice.mapper.OperatingHistoryMapper; + + +@Service +public class BizGroupService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired BizGroupMapper bizGroupMapper; + + + public Map getBizGroupList(Long offset, Long limit, String date_start, String date_end, + String name, String biz_reg_num, String email, String phone, String address) { + Map mapResult = new HashMap<>(); + + List> listMap = (List>)bizGroupMapper.selectBizGroup(0L, false, offset, limit, + date_start, date_end, name, biz_reg_num, email, phone, address); + mapResult.put("list", listMap); + + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", bizGroupMapper.selectBizGroup(0L, true, offset, limit, + date_start, date_end, name, biz_reg_num, email, phone, address)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + + if (listMap.size() == 0) + return mapResult; + + // get BizGroup Tree part + // + List listBizGroupId = listMap.stream() + .map(item -> (Long)item.get("biz_group_id")) + .filter(Objects::nonNull) + .map(Long::valueOf) + .collect(Collectors.toList()); + List> listTreeDb = bizGroupMapper.selectBizGroupParentTree(listBizGroupId); + + // Covert for react rc-tree + List> listRcTree = RcTreeBizGroup.convertDb2RcTree(listTreeDb); + + mapResult.put("tree", listRcTree); + return mapResult; + } + + public CtResponse addOrModifyBizGroup(boolean isModify, Long biz_group_id, Long pid, Long top_group_id, String name, String biz_reg_num, String email, String phone, String ceo, String address) { + CtResponse result = new CtResponse(); + + //if (bizGroupMapper.selectExistBizGroup(biz_group_id, biz_reg_num) != null) { + // result.setErrCode(ErrorCode.ALREADY_EXIST); + // return result; + //} + + if (isModify) { + if (biz_group_id == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + bizGroupMapper.updateBizGroup(biz_group_id, pid, name, biz_reg_num, email, phone, ceo, address); + DbLogger.insert(2L, "사업자그룹정보 수정", 2L); + } + else { + Map params = new HashMap<>(); + params.put("pid", pid); + params.put("name", name); + params.put("biz_reg_num", biz_reg_num); + params.put("gid", 2L); //TempCode + params.put("email", email); + params.put("phone", phone); + params.put("ceo", ceo); + params.put("address", address); + + if (bizGroupMapper.insertBizGroup(params) == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + } + else { + DbLogger.insert(2L, "사업자그룹 추가, 사업자명: " + name + ", 사업자번호: " + biz_reg_num, 2L); + result.put("result", Map.of("biz_group_id", params.get("biz_group_id"))); + } + } + + return result; + } + + @Transactional + public CtResponse removeBizGroup(String ids) { + CtResponse result = new CtResponse(); + + List arrId = Arrays.stream(ids.split(",")) + .map(Long::parseLong) + .collect(Collectors.toList()); + + int changed = bizGroupMapper.changeStateBizGroup(arrId, 2); + //result.setErrCode(ErrorCode.QUERY_ERROR); + if (changed > 0) { + bizGroupMapper.changePidBizGroup(arrId, null); + } + DbLogger.insert(2L, "사업자그룹 삭제, 사업자명: " + ids, 2L); + + return result; + } + + // ver2 + public CtResponse getBizGroup2(boolean isDbRoot, Long pid, Long top_group_id, String date_start, String date_end, String name, String biz_reg_num) { + CtResponse result = new CtResponse(); + + if (isDbRoot == true) { + List> listTreeDb = (List>)bizGroupMapper.selectRootNode(isDbRoot, top_group_id, date_start, date_end, name, biz_reg_num); + + // Covert for react rc-tree + List> listRcTree = RcTreeBizGroup.convertDb2RcTree(listTreeDb); + result.put("result", Map.of("tree", listRcTree)); + return result; + } + + List> listTreeDb = (List>)bizGroupMapper.selectBizGroupChildTree(true, pid, top_group_id, date_start, date_end, name, biz_reg_num); + + // Covert for react rc-tree + List> listRcTree = RcTreeBizGroup.convertDb2RcTree(listTreeDb); + result.put("result", Map.of("tree", listRcTree)); + return result; + } + + public CtResponse getBizGroup3(Long biz_group_id) { + CtResponse result = new CtResponse(); + + // get BizGroup Tree part + List> listTreeDb = bizGroupMapper.selectBizGroupTree(true, biz_group_id, null, null, null, null); + + // Covert for react rc-tree + List> listRcTree = RcTreeBizGroup.convertDb2RcTree(listTreeDb); + + result.put("result", Map.of("tree", listRcTree)); + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/CustomUserDetailsService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/CustomUserDetailsService.java new file mode 100644 index 0000000..ab5deaf --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/CustomUserDetailsService.java @@ -0,0 +1,40 @@ +package com.handong.smartservice.service; + +import com.handong.smartservice.mapper.AccountMapper; +import org.springframework.security.core.userdetails.*; +import org.springframework.stereotype.Service; +import java.util.List; + +@Service +public class CustomUserDetailsService implements UserDetailsService { + + private final AccountMapper accountMapper; + + public CustomUserDetailsService(AccountMapper accountMapper) { + this.accountMapper = accountMapper; + } + + + @Override + public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException { + /* + var account = accountMapper.selectById(userId); + if (account == null) { + throw new UsernameNotFoundException("error"); + } + + + return new User( + (String) account.get("user_id"), + (String) account.get("user_pw"), + List.of() // 권한이 없으면 빈 리스트 + ); + */ + return new User( + "user_id", + "user_pw", + List.of() // 권한이 없으면 빈 리스트 + ); + } + +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/DeviceService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/DeviceService.java new file mode 100644 index 0000000..d76236f --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/DeviceService.java @@ -0,0 +1,224 @@ +package com.handong.smartservice.service; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.jdbc.SQL; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.DbLogger; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.component.UserInfo; +import com.handong.smartservice.mapper.BizGroupMapper; +import com.handong.smartservice.mapper.DeviceMapper; +import com.handong.smartservice.mapper.TerminalMapper; + + +@Service +public class DeviceService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired DeviceMapper deviceMapper; + @Autowired TerminalMapper terminalMapper; + @Autowired BizGroupMapper bizGroupMapper; + + + public DeviceService(DeviceMapper deviceMapper) { + this.deviceMapper = deviceMapper; + } + + public Map getDeviceList(Boolean is_excel, Long offset, Long limit, Boolean is_group_access, Long biz_group_id, String name, String date_start, String date_end) { + Map mapResult = new HashMap<>(); + + //OldVer + //if (is_group_access == false) { + // List> listForTopId = bizGroupMapper.selectBizGroup(biz_group_id, false, 0L, 1L, null, null, null, null, null, null, null); + // if (listForTopId.size() >= 0) { + // biz_group_id = (Long)listForTopId.get(0).get("top_group_id"); + // if (biz_group_id == null) + // biz_group_id = (Long)listForTopId.get(0).get("biz_group_id"); + // } + //} + if (is_group_access) { + List> listMap = (List>)deviceMapper.selectDevice(false, is_excel, offset, limit, is_group_access, + biz_group_id, name, date_start, date_end); + mapResult.put("list", listMap); + + if (is_excel == false) { + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", deviceMapper.selectDevice(true, is_excel, offset, limit, is_group_access, + biz_group_id, name, date_start, date_end)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + } + } + else { + List> listMap = (List>)deviceMapper.selectDevice2(false, is_excel, offset, limit, + biz_group_id, name, date_start, date_end); + mapResult.put("list", listMap); + + if (is_excel == false) { + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", deviceMapper.selectDevice2(true, is_excel, offset, limit, + biz_group_id, name, date_start, date_end)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + } + } + + return mapResult; + } + + public CtResponse addOrModifyDevice(boolean isModify, Long biz_group_id, Long new_biz_group_id, Long device_id, Long terminal_id, String name, String uid1, String manager_name) { + CtResponse result = new CtResponse(); + + UserInfo userInfo = (UserInfo)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + + if (isModify) { + if (device_id == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + //OldVer + //if (terminal_id != 0) { + // terminalMapper.updateTerminalRemoveDevice(device_id); + // terminalMapper.updateTerminalChangeDevice(terminal_id, device_id); + //} + Map mapTerminal = null; + if (terminal_id != 0) { + mapTerminal = terminalMapper.selectTerminalByDeviceId(device_id); + if (mapTerminal != null) { + Long curr_terminal_id = (Long)mapTerminal.get("terminal_id"); // current terminal + + Map mapNewTerminal = terminalMapper.selectTerminalById(terminal_id); + if (mapNewTerminal != null) { + Long new_device_id = (Long)mapNewTerminal.get("device_id"); // new device + + Map mapNewDevice = deviceMapper.selectDeviceById(new_device_id); + if (mapNewDevice != null) { + String new_device_name = (String)mapNewDevice.get("name"); + terminalMapper.updateTerminalChangeDevice(curr_terminal_id, new_device_id, 5L, new_device_name); + } + } + } + + terminalMapper.updateTerminalChangeDevice(terminal_id, device_id, 1L, name); + } + + if (new_biz_group_id != 0 && new_biz_group_id != biz_group_id) { + deviceMapper.deleteDeviceBizGroup(biz_group_id, device_id); // delete n:n relation + deviceMapper.insertDeviceBizGroup(new_biz_group_id, device_id); + + if (mapTerminal != null) + mapTerminal = terminalMapper.selectTerminalByDeviceId(device_id); + + if (mapTerminal != null) { + terminal_id = (Long)mapTerminal.get("terminal_id"); // old terminal + if (terminal_id != null) { + terminalMapper.deleteTerminalBizGroup(biz_group_id, terminal_id); + terminalMapper.insertTerminalBizGroup(new_biz_group_id, terminal_id); + } + } + } + + deviceMapper.updateDevice(device_id, terminal_id, name, uid1, manager_name, userInfo.getGid()); + DbLogger.insert(2L, "무인기기 정보 수정, device_id: " + device_id, userInfo.getGid()); + } + else { + Map params = new HashMap<>(); + params.put("name", name); + params.put("uid1", uid1); + params.put("manager_name", manager_name); + params.put("gid", 2L); //TempCode + + if (terminal_id != 0) { + params.put("terminal_id", terminal_id); + } + + if (deviceMapper.insertDevice(params) == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + DbLogger.insert(2L, "무인기기 추가, 기기명: " + name + "TID: " + uid1, userInfo.getGid()); + + Long new_device_id = _AG.toLong((BigInteger)params.get("device_id")); + + if (deviceMapper.insertDeviceBizGroup(biz_group_id, new_device_id) == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + } + else { + result.put("result", Map.of("biz_group_id", params.get("biz_group_id"))); + } + } + + return result; + } + + @Transactional + //public CtResponse removeDevice(String ids) { + public CtResponse removeDevice(Long biz_group_id, Long device_id) { + CtResponse result = new CtResponse(); + + UserInfo userInfo = (UserInfo)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + + //terminalMapper.updateTerminalRemoveDevice(device_id); + Map mapTerminal = terminalMapper.selectTerminalByDeviceId(device_id); + if (mapTerminal != null) { + Long terminal_id = (Long)mapTerminal.get("terminal_id"); + if (terminal_id != null) { + int changed = terminalMapper.deleteTerminal(terminal_id); + changed = terminalMapper.deleteTerminalBizGroup(biz_group_id, terminal_id); // delete n:n relation + } + } + + //List arrId = Arrays.stream(ids.split(",")) + // .map(Long::parseLong) + // .collect(Collectors.toList()); + //int changed = terminalMapper.changeStateTerminals(arrId, 2); + int changed = deviceMapper.deleteDevice(device_id); + if (changed == 0) { + result.setErrCode(ErrorCode.QUERY_ERROR); + } + DbLogger.insert(2L, "무인기기 삭제, device_id: " + device_id, userInfo.getGid()); + + changed = deviceMapper.deleteDeviceBizGroup(biz_group_id, device_id); // delete n:n relation + if (changed == 0) { + result.setErrCode(ErrorCode.QUERY_ERROR); + } + + return result; + } + + public CtResponse configDevice(Long device_id) { + CtResponse result = new CtResponse(); + + int changed = deviceMapper.updateDeviceTerminalTime(device_id, null, null); + if (changed == 0) { + result.setErrCode(ErrorCode.QUERY_ERROR); + } + + return result; + } + + public Map selectDeviceByError(Long biz_group_id) { + Map mapResult = new HashMap<>(); + + List> listMap = (List>)deviceMapper.selectDeviceByError(biz_group_id); + mapResult.put("list", listMap); + + return mapResult; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/ErrorHistoryService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/ErrorHistoryService.java new file mode 100644 index 0000000..693e497 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/ErrorHistoryService.java @@ -0,0 +1,63 @@ +package com.handong.smartservice.service; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.DbLogger; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.mapper.ErrorHistoryMapper; +import com.handong.smartservice.mapper.VocMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@Service +public class ErrorHistoryService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final ErrorHistoryMapper errorHistoryMapper; + + + public ErrorHistoryService(ErrorHistoryMapper errorHistoryMapper) { + this.errorHistoryMapper = errorHistoryMapper; + } + + public Map getErrorHistoryList(Boolean is_excel, Long offset, Long limit, String date_start, String date_end, + String uid1, Long uid1_type, String slot) { + Map mapResult = new HashMap<>(); + + List> listMap = (List>)errorHistoryMapper.selectErrorHistory(false, is_excel, offset, limit, + date_start, date_end, uid1, uid1_type, slot); + mapResult.put("list", listMap); + + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", errorHistoryMapper.selectErrorHistory(true, is_excel, offset, limit, + date_start, date_end, uid1, uid1_type, slot)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + return mapResult; + } + + public Map getMiss(Long state) { + Map mapResult = new HashMap<>(); + + List> listMap = errorHistoryMapper.selectErrorHistoryByState(1L); + mapResult.put("list", listMap); + + return mapResult; + } + + public CtResponse missSlot(String uid1, Long uid1_type, String slot) { + CtResponse result = new CtResponse(); + + errorHistoryMapper.insertErrorHistory(uid1, uid1_type, slot); + DbLogger.insert(1L, "물품 미투출 TID: " + uid1 + ", 컬럼번호: " + slot, 2L); + + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/GoodsService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/GoodsService.java new file mode 100644 index 0000000..537dc8e --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/GoodsService.java @@ -0,0 +1,282 @@ +package com.handong.smartservice.service; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.apache.ibatis.jdbc.SQL; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.DbLogger; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.component.UserInfo; +import com.handong.smartservice.mapper.BizGroupMapper; +import com.handong.smartservice.mapper.DeviceMapper; +import com.handong.smartservice.mapper.GoodsMapper; + + +@Service +public class GoodsService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final GoodsMapper goodsMapper; + private final BizGroupMapper bizGroupMapper; + private final DeviceMapper deviceMapper; + + + public GoodsService(GoodsMapper goodsMapper, BizGroupMapper bizGroupMapper, DeviceMapper deviceMapper) { + this.goodsMapper = goodsMapper; + this.bizGroupMapper = bizGroupMapper; + this.deviceMapper = deviceMapper; + } + + public Map getGoodsList(Boolean is_excel, Long offset, Long limit, Boolean is_group_access, Long biz_group_id, Long device_id, Long state, + String code, String name, String vendor, String date_start, String date_end) { + Map mapResult = new HashMap<>(); + + if (is_group_access == false) { + List> listForTopId = bizGroupMapper.selectBizGroup(biz_group_id, false, 0L, 1L, null, null, null, null, null, null, null); + if (listForTopId != null && listForTopId.size() > 0) { + biz_group_id = (Long)listForTopId.get(0).get("top_group_id"); + if (biz_group_id == null) + biz_group_id = (Long)listForTopId.get(0).get("biz_group_id"); + } + } + + List> listMap = (List>)goodsMapper.selectGoods(false, is_excel, offset, limit, is_group_access, + biz_group_id, device_id, state, code, name, vendor, date_start, date_end); + mapResult.put("list", listMap); + + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", goodsMapper.selectGoods(true, is_excel, offset, limit, is_group_access, + biz_group_id, device_id, state, code, name, vendor, date_start, date_end)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + return mapResult; + } + + public CtResponse addOrModifyGoods(boolean isModify, Long biz_group_id, Long goods_id, String code, String name, Long price, Long inventory, String vendor) { + CtResponse result = new CtResponse(); + + UserInfo userInfo = (UserInfo)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + + if (isModify) { + if (goods_id == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + goodsMapper.updateGoods(biz_group_id, goods_id, code, name, price, inventory, vendor, userInfo.getGid()); + DbLogger.insert(2L, "상품정보 수정, goods_id: " + goods_id, 2L); + } + else { + if (goodsMapper.selectExistGoods(biz_group_id, code, name) != null) { + result.setErrCode(ErrorCode.ALREADY_EXIST); + return result; + } + + if (price == null) + price = 0L; + + Map params = new HashMap<>(); + params.put("biz_group_id", biz_group_id); + params.put("code", code); + params.put("name", name); + params.put("price", price); + params.put("inventory", inventory); + params.put("vendor", vendor); + params.put("gid", 2L); //TempCode + + goodsMapper.insertGoods(params); + DbLogger.insert(2L, "상품정보 추가, code: " + code + ", name: " + name, userInfo.getGid()); + } + + return result; + } + + public CtResponse removeGoods(String ids) { + CtResponse result = new CtResponse(); + + List arrId = Arrays.stream(ids.split(",")) + .map(Long::parseLong) + .collect(Collectors.toList()); + + int changed = goodsMapper.deleteGoods(arrId); + //if (changed == 0) { + //result.setErrCode(ErrorCode.QUERY_ERROR); + //} + + return result; + } + + // + public Map getDeviceGoodsList(Long device_id, String slot, Long goods_id) { + Map mapResult = new HashMap<>(); + + Map mapDevice = deviceMapper.selectDeviceById(device_id); + mapResult.put("device_name", mapDevice.get("name")); + + List> listMap = (List>)goodsMapper.selectGoodsByDevice(false, device_id); + mapResult.put("goods_list", listMap); + + List> listMap2 = (List>)goodsMapper.selectDeviceGoods(device_id, slot, goods_id); + mapResult.put("device_goods_list", listMap2); + + if (listMap.size() > 0) { + Map mapTemplate = getGoodsTemplateByBizGroupId((Long)listMap.get(0).get("biz_group_id")); + mapResult.put("goods_template_list", mapTemplate.get("goods_template_list")); + } + + return mapResult; + } + + public CtResponse addDeviceGoods(Long device_id, List> device_goods) { + CtResponse result = new CtResponse(); + + UserInfo userInfo = (UserInfo)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + + if (goodsMapper.insertDeviceGoods(device_id, device_goods) == 0) { + result.setErrCode(ErrorCode.QUERY_ERROR); + } + DbLogger.insert(2L, "무인기기 상품 추가, device_id: " + device_id, userInfo.getGid()); + return result; + } + + public CtResponse deleteDeviceGoods(Long device_id, List> device_goods) { + CtResponse result = new CtResponse(); + + UserInfo userInfo = (UserInfo)SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + + //for (Map item : device_goods) { + // item.put("device_id", device_id); + //} + if (goodsMapper.deleteDeviceGoods(device_id, device_goods) == 0) { + result.setErrCode(ErrorCode.QUERY_ERROR); + } + DbLogger.insert(2L, "무인기기 상품 삭제, device_id: " + device_id, userInfo.getGid()); + + return result; + } + + public Map getGoodsTemplateByBizGroupId(Long biz_group_id) { + Map mapResult = new HashMap<>(); + + List> listMap = (List>)goodsMapper.selectGoodsTemplateByBizGroupId(biz_group_id); + + Map> templateMap = new HashMap<>(); + + for (Map item : listMap) { + Object templateId = item.get("goods_template_id"); + + if (!templateMap.containsKey(templateId)) { + Map template = new HashMap<>(); + template.put("goods_template_id", templateId); + template.put("template_name", item.get("template_name")); + template.put("template_reg_time", item.get("template_reg_time")); + template.put("goods_template_elements", new ArrayList>()); + template.put("template_inventory", item.get("template_inventory")); + template.put("template_inventory_max", item.get("template_inventory_max")); + template.put("template_inventory_alarm", item.get("template_inventory_alarm")); + templateMap.put(templateId, template); + } + + Map element = new HashMap<>(); + element.put("goods_template_element_id", item.get("goods_template_element_id")); + element.put("slot", item.get("slot")); + element.put("goods_id", item.get("goods_id")); + element.put("inventory", item.get("inventory")); + element.put("idx", item.get("idx")); + element.put("inventory_max", item.get("inventory_max")); + element.put("inventory_alarm", item.get("inventory_alarm")); + + @SuppressWarnings("unchecked") + List> elements = (List>)templateMap.get(templateId).get("goods_template_elements"); + elements.add(element); + } + + List> groupedList = new ArrayList<>(templateMap.values()); + mapResult.put("goods_template_list", groupedList); + return mapResult; + } + + public Map getGoodsTemplateById(Long goods_template_id) { + Map mapResult = new HashMap<>(); + + List> templateElements = goodsMapper.selectGoodsTemplateById(goods_template_id); + mapResult.put("goods_template_elements", templateElements); + + List> goodsList = goodsMapper.selectGoodsByBizGroupId((Long)templateElements.get(0).get("biz_group_id")); + mapResult.put("goods_list", goodsList); + + return mapResult; + } + + public CtResponse addGoodsTemplate(Long biz_group_id, String goods_template_name, Map goods_template_inventory, List> goods_template_elements) { + CtResponse result = new CtResponse(); + + if (biz_group_id == null) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + try { + Map params = new HashMap<>(); + params.put("biz_group_id", biz_group_id); + params.put("name", goods_template_name); + params.put("inventory", (Integer)goods_template_inventory.get("inventory")); + params.put("inventory_max", (Integer)goods_template_inventory.get("inventory_max")); + params.put("inventory_alarm", (Integer)goods_template_inventory.get("inventory_alarm")); + + goodsMapper.insertGoodsTemplate(params); + + Long goods_template_id = _AG.toLong((BigInteger)params.get("goods_template_id")); + + if (goods_template_id == null || goods_template_id == 0) { + result.setErrCode(ErrorCode.QUERY_ERROR); + return result; + } + + if (goods_template_elements != null && goods_template_elements.size() > 0) { + if (goodsMapper.insertGoodsTemplateElements(goods_template_id, goods_template_elements) == 0) { + result.setErrCode(ErrorCode.QUERY_ERROR); + } + } + } + catch (Exception e) { + e.printStackTrace(); + result.setErrCode(ErrorCode.INVALID_PARAMETER); + } + + return result; + } + + public CtResponse removeGoodsTemplate(Long goods_template_id) { + CtResponse result = new CtResponse(); + + if (goods_template_id == null || goods_template_id == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + try { + goodsMapper.deleteGoodsTemplateElements(goods_template_id); + goodsMapper.deleteGoodsTemplate(goods_template_id); + } + catch (Exception e) { + e.printStackTrace(); + result.setErrCode(ErrorCode.INVALID_PARAMETER); + } + + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/LocationService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/LocationService.java new file mode 100644 index 0000000..0281f1d --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/LocationService.java @@ -0,0 +1,131 @@ +package com.handong.smartservice.service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.apache.ibatis.jdbc.SQL; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.component.RcTreeLocation; +import com.handong.smartservice.mapper.LocationMapper; + + +@Service +public class LocationService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final LocationMapper locationMapper; + + public LocationService(LocationMapper locationMapper) { + this.locationMapper = locationMapper; + } + + public Map getLocationList(Long offset, Long limit, String date_start, String date_end, + String name, String description, String address) { + Map mapResult = new HashMap<>(); + + List> listMap = (List>)locationMapper.selectLocation(false, offset, limit, + date_start, date_end, name, description, address); + mapResult.put("list", listMap); + + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", locationMapper.selectLocation(true, offset, limit, + date_start, date_end, name, description, address)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + + if (listMap.size() == 0) + return mapResult; + + // get Location Tree part + // + List listLocationId = listMap.stream() + .map(item -> (Long)item.get("location_id")) + .filter(Objects::nonNull) + .map(Long::valueOf) + .collect(Collectors.toList()); + List> listTreeDb = locationMapper.selectLocationParentTree(listLocationId); + + // Covert for react rc-tree + List> listRcTree = RcTreeLocation.convertDb2RcTree(listTreeDb); + + mapResult.put("tree", listRcTree); + return mapResult; + } + + public CtResponse addOrModifyLocation(boolean isModify, Long location_id, Long pid, String name, String description, String address) { + CtResponse result = new CtResponse(); + + if (isModify) { + if (location_id == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + locationMapper.updateLocation(location_id, pid, name, description, address); + } + else { + Map params = new HashMap<>(); + params.put("pid", pid); + params.put("name", name); + params.put("gid", 2L); //TempCode + params.put("description", description); + params.put("address", address); + + if (locationMapper.insertLocation(params) == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + } + else { + result.put("result", Map.of("location_id", params.get("location_id"))); + } + } + + return result; + } + + public CtResponse removeLocation(String ids) { + CtResponse result = new CtResponse(); + + List arrId = Arrays.stream(ids.split(",")) + .map(Long::parseLong) + .collect(Collectors.toList()); + + int changed = locationMapper.changeStateLocation(arrId, 2); + //result.setErrCode(ErrorCode.QUERY_ERROR); + if (changed > 0) { + locationMapper.changePidLocation(arrId, null); + } + + return result; + } + + // ver2 + public CtResponse getLocation2(boolean isDbRoot, Long pid, String date_start, String date_end, String name, String description, String address) { + CtResponse result = new CtResponse(); + + if (isDbRoot == true) { + List> listTreeDb = (List>)locationMapper.selectRootNode(isDbRoot, date_start, date_end, name, description, address); + + // Covert for react rc-tree + List> listRcTree = RcTreeLocation.convertDb2RcTree(listTreeDb); + result.put("result", Map.of("tree", listRcTree)); + return result; + } + + List> listTreeDb = (List>)locationMapper.selectLocationChildTree(true, pid, date_start, date_end, name, description, address); + + // Covert for react rc-tree + List> listRcTree = RcTreeLocation.convertDb2RcTree(listTreeDb); + result.put("result", Map.of("tree", listRcTree)); + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/NoticeService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/NoticeService.java new file mode 100644 index 0000000..cbb9f6d --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/NoticeService.java @@ -0,0 +1,92 @@ +package com.handong.smartservice.service; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.mapper.NoticeMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@Service +public class NoticeService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final NoticeMapper noticeMapper; + + + public NoticeService(NoticeMapper noticeMapper) { + this.noticeMapper = noticeMapper; + } + + public CtResponse getNoticeDetail(String notice_id) { + CtResponse result = new CtResponse(); + + Map detail = noticeMapper.selectDetailNotice(notice_id); + + if (notice_id == null || notice_id.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + result.put("result", detail); + return result; + } + + public Map getNoticeList(Long offset, Long limit, String date_start, String date_end, + String title, String content) { + Map mapResult = new HashMap<>(); + + List> listMap = (List>)noticeMapper.selectNotice(false, offset, limit, + date_start, date_end, title, content); + mapResult.put("list", listMap); + + //Long totalCount = _AG.getTotalCount(noticeMapper.selectNotice(true, offset, limit, + // date_start, date_end, title, content)); + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", noticeMapper.selectNotice(true, offset, limit, + date_start, date_end, title, content)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + return mapResult; + } + + public CtResponse addOrModifyNotice(boolean isModify, String notice_id, String title, String content) { + CtResponse result = new CtResponse(); + + if (isModify) { + if (notice_id == null || notice_id.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + noticeMapper.updateNotice(_AG.toLong(notice_id), title, content); + } + else { + noticeMapper.insertNotice(title, content, 2L); + } + + return result; + } + + public CtResponse removeNotice(String ids) { + CtResponse result = new CtResponse(); + + List arrId = Arrays.stream(ids.split(",")) + .map(Long::parseLong) + .collect(Collectors.toList()); + + int changed = noticeMapper.changeStateNotice(arrId, 2); + //if (changed == 0) { + //result.setErrCode(ErrorCode.QUERY_ERROR); + //} + + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/OperatingHistoryService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/OperatingHistoryService.java new file mode 100644 index 0000000..5555f8c --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/OperatingHistoryService.java @@ -0,0 +1,52 @@ +package com.handong.smartservice.service; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.mapper.OperatingHistoryMapper; +import com.handong.smartservice.mapper.VocMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@Service +public class OperatingHistoryService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final OperatingHistoryMapper operatingHistoryMapper; + + + public OperatingHistoryService(OperatingHistoryMapper operatingHistoryMapper) { + this.operatingHistoryMapper = operatingHistoryMapper; + } + + public Map getOperatingHistoryList(Boolean is_excel, Long offset, Long limit, String date_start, String date_end, + Long type, String action) { + Map mapResult = new HashMap<>(); + + List> listMap = (List>)operatingHistoryMapper.selectOperatingHistory(false, is_excel, offset, limit, + date_start, date_end, type, action); + mapResult.put("list", listMap); + + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", operatingHistoryMapper.selectOperatingHistory(true, is_excel, offset, limit, + date_start, date_end, type, action)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + return mapResult; + } + + public CtResponse add(Long type, String action, Long gid) { + CtResponse result = new CtResponse(); + + operatingHistoryMapper.insertOperatingHistory(type, action, gid); + + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/RequiredArgsConstructor.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/RequiredArgsConstructor.java new file mode 100644 index 0000000..b6c5270 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/RequiredArgsConstructor.java @@ -0,0 +1,5 @@ +package com.handong.smartservice.service; + +public @interface RequiredArgsConstructor { + +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/ResourceBoardService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/ResourceBoardService.java new file mode 100644 index 0000000..1d7c8b9 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/ResourceBoardService.java @@ -0,0 +1,96 @@ +package com.handong.smartservice.service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.apache.ibatis.jdbc.SQL; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.mapper.ResourceBoardMapper; + + +@Service +public class ResourceBoardService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final ResourceBoardMapper resourceBoardMapper; + + + public ResourceBoardService(ResourceBoardMapper resourceBoardMapper) { + this.resourceBoardMapper = resourceBoardMapper; + } + + public CtResponse getResourceBoardDetail(String resource_board_id) { + CtResponse result = new CtResponse(); + + Map detail = resourceBoardMapper.selectDetailResourceBoard(resource_board_id); + + if (resource_board_id == null || resource_board_id.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + result.put("result", detail); + return result; + } + + public Map getResourceBoardList(Long offset, Long limit, String date_start, String date_end, + String title, String content) { + Map mapResult = new HashMap<>(); + + List> listMap = (List>)resourceBoardMapper.selectResourceBoard(false, offset, limit, + date_start, date_end, title, content); + mapResult.put("list", listMap); + + //Long totalCount = _AG.getTotalCount(resourceBoardMapper.selectResourceBoard(true, offset, limit, + // date_start, date_end, title, content)); + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", resourceBoardMapper.selectResourceBoard(true, offset, limit, + date_start, date_end, title, content)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + return mapResult; + } + + public CtResponse addOrModifyResourceBoard(boolean isModify, String resource_board_id, String title, String content) { + CtResponse result = new CtResponse(); + + if (isModify) { + if (resource_board_id == null || resource_board_id.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + resourceBoardMapper.updateResourceBoard(_AG.toLong(resource_board_id), title, content); + } + else { + resourceBoardMapper.insertResourceBoard(title, content, 2L); + } + + return result; + } + + public CtResponse removeResourceBoard(String ids) { + CtResponse result = new CtResponse(); + + List arrId = Arrays.stream(ids.split(",")) + .map(Long::parseLong) + .collect(Collectors.toList()); + + int changed = resourceBoardMapper.changeStateResourceBoard(arrId, 2); + //if (changed == 0) { + //result.setErrCode(ErrorCode.QUERY_ERROR); + //} + + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/SalesService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/SalesService.java new file mode 100644 index 0000000..8c058ea --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/SalesService.java @@ -0,0 +1,58 @@ +package com.handong.smartservice.service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; + +import org.apache.ibatis.jdbc.SQL; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.handong.smartservice.mapper.TransactionMapper; +import com.handong.smartservice.mapper.BizGroupMapper; +import com.handong.smartservice.mapper.GoodsMapper; + +@Service +public class SalesService { + + private final TransactionMapper transactionMapper; + private final BizGroupMapper bizGroupMapper; + + public SalesService(TransactionMapper transactionMapper, BizGroupMapper bizGroupMapper) { + this.transactionMapper = transactionMapper; + this.bizGroupMapper = bizGroupMapper; + } + + public Map getSalesList(Boolean is_excel, Long offset, Long limit, Boolean is_group_access, Long biz_group_id, String date_start, String date_end, + String uid1, String device_name, Long approval_type, Long date_type) { + Map mapResult = new HashMap<>(); + + if (is_group_access == false) { + List> listForTopId = bizGroupMapper.selectBizGroup(biz_group_id, false, 0L, 1L, null, null, null, null, null, null, null); + if (listForTopId != null && listForTopId.size() > 0) { + biz_group_id = (Long)listForTopId.get(0).get("top_group_id"); + if (biz_group_id == null) + biz_group_id = (Long)listForTopId.get(0).get("biz_group_id"); + } + } + + List> listMap = (List>)transactionMapper.selectTransaction3(false, is_excel, offset, limit, is_group_access, + biz_group_id, date_start, date_end, uid1, device_name, approval_type, date_type); + mapResult.put("list", listMap); + + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", transactionMapper.selectTransaction3(true, is_excel, offset, limit, is_group_access, + biz_group_id, date_start, date_end, uid1, device_name, approval_type, date_type)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + return mapResult; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/TerminalService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/TerminalService.java new file mode 100644 index 0000000..5cd0543 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/TerminalService.java @@ -0,0 +1,189 @@ +package com.handong.smartservice.service; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.jdbc.SQL; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.DbLogger; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.mapper.BizGroupMapper; +import com.handong.smartservice.mapper.DeviceMapper; +import com.handong.smartservice.mapper.GoodsMapper; +import com.handong.smartservice.mapper.TerminalMapper; + + +@Service +public class TerminalService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final TerminalMapper terminalMapper; + private final DeviceMapper deviceMapper; + private final BizGroupMapper bizGroupMapper; + + + public TerminalService(TerminalMapper terminalMapper, DeviceMapper deviceMapper, BizGroupMapper bizGroupMapper) { + this.terminalMapper = terminalMapper; + this.deviceMapper = deviceMapper; + this.bizGroupMapper = bizGroupMapper; + } + + public Map getTerminalList(Boolean is_excel, Long offset, Long limit, Boolean is_group_access, Long biz_group_id, Long state, String date_start, String date_end) { + Map mapResult = new HashMap<>(); + + if (is_group_access == false) { + List> listForTopId = bizGroupMapper.selectBizGroup(biz_group_id, false, 0L, 1L, null, null, null, null, null, null, null); + if (listForTopId != null && listForTopId.size() > 0) { + biz_group_id = (Long)listForTopId.get(0).get("top_group_id"); + if (biz_group_id == null) + biz_group_id = (Long)listForTopId.get(0).get("biz_group_id"); + } + } + + List> listMap = (List>)terminalMapper.selectTerminal(false, is_excel, offset, limit, is_group_access, + biz_group_id, null, state, date_start, date_end); + mapResult.put("list", listMap); + + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", terminalMapper.selectTerminal(true, is_excel, offset, limit, is_group_access, + biz_group_id, null, state, date_start, date_end)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + return mapResult; + } + + @Transactional + public CtResponse addOrModifyTerminal(boolean isModify, Long addType, Long biz_group_id, Long terminal_id, String name, String uid1, Long type) { + CtResponse result = new CtResponse(); + + if (isModify) { + if (terminal_id == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + terminalMapper.updateTerminal(terminal_id, name, uid1, type, null, 2L); + DbLogger.insert(2L, "카드단말기 정보변경, terminal_id: " + terminal_id, 2L); + } + else { + if (terminalMapper.selectExistTerminal(name, uid1, type) != null) { + result.setErrCode(ErrorCode.ALREADY_EXIST); + return result; + } + + Map params = new HashMap<>(); + params.put("name", name); + params.put("gid", 2L); //TempCode + + logger.info("addType = " + addType); + /* oldVer + if (addType == 1L) { + logger.info("addType2 = " + addType); + if (deviceMapper.insertDevice(params) == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + Long new_device_id = _AG.toLong((BigInteger)params.get("device_id")); + + if (deviceMapper.insertDeviceBizGroup(biz_group_id, new_device_id) == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + } + */ + if (addType != 1L) + params.put("state", 5L); + else + params.put("state", 1L); + + if (deviceMapper.insertDevice(params) == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + Long new_device_id = _AG.toLong((BigInteger)params.get("device_id")); + + if (deviceMapper.insertDeviceBizGroup(biz_group_id, new_device_id) == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + // + + params.put("uid1", uid1); + params.put("type", type); + params.put("gid", 2L); //TempCode + + if (terminalMapper.insertTerminal(params) == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + DbLogger.insert(2L, "카드단말기 추가, TID: " + uid1, 2L); + + Long new_terminal_id = _AG.toLong((BigInteger)params.get("terminal_id")); + + if (terminalMapper.insertTerminalBizGroup(biz_group_id, new_terminal_id) == 0) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + result.put("result", Map.of("terminal_id", new_terminal_id)); + } + + return result; + } + + @Transactional + //public CtResponse removeTerminal(String ids) { + public CtResponse removeTerminal(Long biz_group_id, Long terminal_id) { + CtResponse result = new CtResponse(); + + Map mapTerminal = terminalMapper.selectTerminalById(terminal_id); + if (mapTerminal != null) { + Long device_id = (Long)mapTerminal.get("device_id"); + if (device_id != null) { + int changed = deviceMapper.deleteDevice(device_id); + changed = deviceMapper.deleteDeviceBizGroup(biz_group_id, device_id); // delete n:n relation + } + } + + //List arrId = Arrays.stream(ids.split(",")) + // .map(Long::parseLong) + // .collect(Collectors.toList()); + //int changed = terminalMapper.changeStateTerminals(arrId, 2); + int changed = terminalMapper.deleteTerminal(terminal_id); + if (changed == 0) { + result.setErrCode(ErrorCode.QUERY_ERROR); + } + DbLogger.insert(2L, "카드단말기 삭제, terminal_id: " + terminal_id, 2L); + + changed = terminalMapper.deleteTerminalBizGroup(biz_group_id, terminal_id); // delete n:n relation + if (changed == 0) { + result.setErrCode(ErrorCode.QUERY_ERROR); + } + + return result; + } + + public CtResponse terminalState(String uid1, Long type, Long state) { + CtResponse result = new CtResponse(); + + if (terminalMapper.terminalState(uid1, type, state) == 0) { + result.setErrCode(ErrorCode.QUERY_ERROR); + } + DbLogger.insert(1L, "카드단말기 상태 변경, TID: " + uid1 + ", state: " + state, 2L); + + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/TransactionService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/TransactionService.java new file mode 100644 index 0000000..66d4fd6 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/TransactionService.java @@ -0,0 +1,137 @@ +package com.handong.smartservice.service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.math.BigInteger; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; + +import org.apache.ibatis.jdbc.SQL; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.handong.smartservice.mapper.TransactionMapper; +import com.handong.smartservice.mapper.BizGroupMapper; +import com.handong.smartservice.mapper.GoodsMapper; +import com.handong.smartservice.mapper.TerminalMapper; + +@Service +public class TransactionService { + + private final TransactionMapper transactionMapper; + private final GoodsMapper goodsMapper; + private final BizGroupMapper bizGroupMapper; + private final TerminalMapper terminalMapper; + + public TransactionService(TransactionMapper transactionMapper, GoodsMapper goodsMapper, BizGroupMapper bizGroupMapper, TerminalMapper terminalMapper) { + this.transactionMapper = transactionMapper; + this.goodsMapper = goodsMapper; + this.bizGroupMapper = bizGroupMapper; + this.terminalMapper = terminalMapper; + } + + public Map getTransactionList(Boolean is_excel, Long offset, Long limit, Boolean is_group_access, Long biz_group_id, String date_start, String date_end, + String uid1, Long uid1_type, String type, Long amount, String approval, String pay_name, String pay_vendor, String slot, String code, String goods_name) { + Map mapResult = new HashMap<>(); + + /* + if (is_group_access == false) { + List> listForTopId = bizGroupMapper.selectBizGroup(biz_group_id, false, 0L, 1L, null, null, null, null, null, null, null); + if (listForTopId != null && listForTopId.size() > 0) { + biz_group_id = (Long)listForTopId.get(0).get("top_group_id"); + if (biz_group_id == null) + biz_group_id = (Long)listForTopId.get(0).get("biz_group_id"); + } + } + */ + + List> listMap = (List>)transactionMapper.selectTransaction(false, is_excel, offset, limit, is_group_access, + biz_group_id, date_start, date_end, uid1, uid1_type, type, amount, approval, pay_name, pay_vendor, slot, code, goods_name); + mapResult.put("list", listMap); + + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", transactionMapper.selectTransaction(true, is_excel, offset, limit, is_group_access, + biz_group_id, date_start, date_end, uid1, uid1_type, type, amount, approval, pay_name, pay_vendor, slot, code, goods_name)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + return mapResult; + } + + public Map getUndefinedTransactionList(Boolean is_excel, Long offset, Long limit, String date_start, String date_end, + String uid1, Long uid1_type, String type, Long amount, String approval, String pay_name, String pay_vendor, String slot, String code, String goods_name) { + Map mapResult = new HashMap<>(); + + List> listMap = (List>)transactionMapper.selectTransactionBizGroup0( + false, is_excel, offset, limit, date_start, date_end, uid1, uid1_type, type, amount, approval, pay_name, pay_vendor, slot, code, goods_name); + mapResult.put("list", listMap); + + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", transactionMapper.selectTransactionBizGroup0( + true, is_excel, offset, limit, date_start, date_end, uid1, uid1_type, type, amount, approval, pay_name, pay_vendor, slot, code, goods_name)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + return mapResult; + } + + public CtResponse addTransaction(String uid1, Long uid1_type, String type, Long amount, String approval, String pay_name, String pay_vendor, String slot, String pay_unique_num, String pay_order_time) { + CtResponse result = new CtResponse(); + Long biz_group_id = 0L; + Long device_id = 0L; + + Map terminal = terminalMapper.selectTerminal3(uid1, uid1_type); + if (terminal != null) { + device_id = (Long)terminal.get("device_id"); + Map mapBizGroup = bizGroupMapper.selectBizGroupByDeviceId(device_id); + if (mapBizGroup != null) { + biz_group_id = (Long)mapBizGroup.get("biz_group_id"); + } + else { + Long terminal_id = (Long)terminal.get("terminal_id"); + Map mapBizGroup2 = bizGroupMapper.selectBizGroupByTerminalId(terminal_id); + if (mapBizGroup2 != null) { + biz_group_id = (Long)mapBizGroup2.get("biz_group_id"); + } + } + } + + //select uid1, uid1_type -> device_id ->device_goods (slot) -> goods_id + Map goods = goodsMapper.selectGoodsByUid1(uid1, uid1_type, slot); + if (goods != null) { + device_id = (Long)goods.get("device_id"); + } + + Map params = new HashMap<>(); + params.put("uid1", uid1); + params.put("uid1_type", uid1_type); + params.put("order_time", pay_order_time); + params.put("type", type); + params.put("amount", amount); + params.put("approval", approval); + params.put("pay_unique_num", pay_unique_num); + params.put("pay_name", pay_name); + params.put("pay_vendor", pay_vendor); + params.put("slot", slot); + params.put("biz_group_id", biz_group_id); + params.put("device_id", device_id); + + if (type.compareTo("D4") == 0) { + goodsMapper.updateDeviceGoodsPlusInventory(approval); + } + else if (goods != null) { + params.put("goods_name", goods.get("name")); + params.put("code", goods.get("code")); + params.put("price", goods.get("price")); + + goodsMapper.updateDeviceGoodsMinusInventory((Long)goods.get("device_id"), slot); + } + + transactionMapper.insertTransaction(params); + + return result; + } +} diff --git a/smartservice_backend/src/main/java/com/handong/smartservice/service/VocService.java b/smartservice_backend/src/main/java/com/handong/smartservice/service/VocService.java new file mode 100644 index 0000000..77f0709 --- /dev/null +++ b/smartservice_backend/src/main/java/com/handong/smartservice/service/VocService.java @@ -0,0 +1,92 @@ +package com.handong.smartservice.service; + +import com.handong.smartservice._AG; +import com.handong.smartservice.component.CtResponse; +import com.handong.smartservice.component.ErrorCode; +import com.handong.smartservice.mapper.VocMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + + +@Service +public class VocService { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final VocMapper vocMapper; + + + public VocService(VocMapper vocMapper) { + this.vocMapper = vocMapper; + } + + public CtResponse getVocDetail(String voc_id) { + CtResponse result = new CtResponse(); + + Map detail = vocMapper.selectDetailVoc(voc_id); + + if (voc_id == null || voc_id.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + result.put("result", detail); + return result; + } + + public Map getVocList(Long offset, Long limit, String date_start, String date_end, + String title, String content, String process) { + Map mapResult = new HashMap<>(); + + List> listMap = (List>)vocMapper.selectVoc(false, offset, limit, + date_start, date_end, title, content, process); + mapResult.put("list", listMap); + + //Long totalCount = _AG.getTotalCount(vocMapper.selectVoc(true, offset, limit, + // date_start, date_end, title, content, process)); + Long totalCount = _AG.getNumberFromQuery("COUNT(*)", vocMapper.selectVoc(true, offset, limit, + date_start, date_end, title, content, process)); + mapResult.put("totalCount", totalCount); + mapResult.put("offset", offset); + return mapResult; + } + + public CtResponse addOrModifyVoc(boolean isModify, String voc_id, String title, String content) { + CtResponse result = new CtResponse(); + + if (isModify) { + if (voc_id == null || voc_id.isEmpty()) { + result.setErrCode(ErrorCode.INVALID_PARAMETER); + return result; + } + + vocMapper.updateVoc(_AG.toLong(voc_id), title, content); + } + else { + vocMapper.insertVoc(title, content, 2L); + } + + return result; + } + + public CtResponse removeVoc(String ids) { + CtResponse result = new CtResponse(); + + List arrId = Arrays.stream(ids.split(",")) + .map(Long::parseLong) + .collect(Collectors.toList()); + + int changed = vocMapper.changeStateVoc(arrId, 2); + //if (changed == 0) { + //result.setErrCode(ErrorCode.QUERY_ERROR); + //} + + return result; + } +} diff --git a/smartservice_backend/src/main/resources/application.yaml b/smartservice_backend/src/main/resources/application.yaml new file mode 100644 index 0000000..9a9aff4 --- /dev/null +++ b/smartservice_backend/src/main/resources/application.yaml @@ -0,0 +1,50 @@ +spring: + application: + name: "smartservice" + project: "smartservice" + mvc: + pathmatch: + matching-strategy: ant_path_matcher + view: + prefix: /WEB-INF/ + suffix: .jsp + data: + redis: + host: localhost + port: 6379 + password: secret + datasource: + #url: jdbc:mysql://localhost:3306/smartservice?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + url: jdbc:mysql://sensemeka.ddns.net:19106/hdsmartsvc?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull + username: smartsvc2 + password: Gknehd!@wjdqhxhdtls + driver-class-name: com.mysql.jdbc.Driver + session: + jdbc: + initialize-schema: always + + +mybatis: + type-aliases-package: com.handong.smartservice.mapper + mapper-locations: classpath:mapper/**/*.xml + configuration: + map-underscore-to-camel-case: true + +jwt: + secret: c2VjcmV0L12AAsWtleS12ZXJ5LXN232DSJDSKDJWNsllY3VyZS1zZWNyZXQta2V5LXZlcnktc2VjdXJl + +logging: + level: + org: + hibernate: info + springframework: + security: debug + com: + handong: debug + +server: + port: + 18080 + error: + whitelabel: + enabled: FALSE diff --git a/smartservice_backend/src/main/resources/mapper/AccountMapper.xml b/smartservice_backend/src/main/resources/mapper/AccountMapper.xml new file mode 100644 index 0000000..c945194 --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/AccountMapper.xml @@ -0,0 +1,141 @@ + + + + + + + + + + + INSERT INTO account + + user_id, user_pw, + nick_name, + email, + state, + biz_group_id, + permission, + + VALUES + + #{user_id}, #{user_pw}, + #{nick_name}, + #{email}, + #{state}, + #{biz_group_id}, + #{permission}, + + + + + UPDATE account + + user_pw = #{user_pw}, + nick_name = #{nick_name}, + email = #{email}, + state = #{state}, + biz_group_id = #{biz_group_id}, + + WHERE gid = #{gid} + + + + + UPDATE account + SET state=#{state} + WHERE gid IN + + #{id} + + + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/resources/mapper/BizGroupMapper.xml b/smartservice_backend/src/main/resources/mapper/BizGroupMapper.xml new file mode 100644 index 0000000..64db8b9 --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/BizGroupMapper.xml @@ -0,0 +1,493 @@ + + + + + + + + + + + + + + + + + INSERT INTO biz_group + + + + name, biz_reg_num, gid + , email + , phone + , ceo + , address + + VALUES + + #{name}, #{biz_reg_num}, #{gid} + , #{email} + , #{phone} + , #{ceo} + , #{address} + + + + + top_group_id, pid, name, biz_reg_num, gid + , email + , phone + , ceo + , address + + SELECT + COALESCE(TGI.top_group_id, #{pid}) AS top_group_id, + #{pid}, #{name}, #{biz_reg_num}, #{gid} + , #{email} + , #{phone} + , #{ceo} + , #{address} + FROM ( + SELECT top_group_id + FROM biz_group + WHERE biz_group_id = #{pid} + LIMIT 1 + ) AS TGI; + + + + + + UPDATE biz_group + + name = #{name}, + biz_reg_num = #{biz_reg_num}, + email = #{email}, + phone = #{phone}, + ceo = #{ceo}, + address = #{address}, + pid = #{pid}, + + WHERE biz_group_id = #{biz_group_id} + + + + + UPDATE biz_group + SET state = #{state} + WHERE biz_group_id IN + + #{id} + + + + + + + UPDATE biz_group + + + SET pid = #{new_pid} + + + SET pid = NULL + + + WHERE pid IN + + #{id} + + + + + + UPDATE biz_group + SET state = #{state} + WHERE biz_group_id IN + + #{id} + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/resources/mapper/DeviceMapper.xml b/smartservice_backend/src/main/resources/mapper/DeviceMapper.xml new file mode 100644 index 0000000..228b5cc --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/DeviceMapper.xml @@ -0,0 +1,276 @@ + + + + + + + + + + + + + + + + + + INSERT INTO device + + name, gid, state, + manager_name, + + VALUES + + #{name}, #{gid}, #{state}, + #{manager_name}, + + + + + UPDATE device + + name = #{name}, + uid1 = #{uid1}, + manager_name = #{manager_name}, + gid = #{gid}, + + WHERE device_id = #{device_id} + + + + UPDATE terminal T + JOIN device D ON D.device_id = T.device_id + + T.connect_time = #{connect_time}, + T.disconnect_time = #{disconnect_time} + + WHERE D.device_id = #{device_id} + + + + + UPDATE device + SET state = #{state} + WHERE device_id IN + + #{id} + + + + + + + DELETE FROM device + WHERE device_id = #{device_id} + + + + + INSERT INTO device_biz_group + + biz_group_id, device_id, + + VALUES + + #{biz_group_id}, #{device_id}, + + + + + DELETE FROM device_biz_group + WHERE device_id = #{device_id} AND biz_group_id = #{biz_group_id} + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/resources/mapper/ErrorHistory.xml b/smartservice_backend/src/main/resources/mapper/ErrorHistory.xml new file mode 100644 index 0000000..db587b0 --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/ErrorHistory.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + INSERT INTO error_history + + uid1, uid1_type, slot, + + VALUES + + #{uid1}, #{uid1_type}, #{slot}, + + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/resources/mapper/GoodsMapper.xml b/smartservice_backend/src/main/resources/mapper/GoodsMapper.xml new file mode 100644 index 0000000..431c24a --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/GoodsMapper.xml @@ -0,0 +1,359 @@ + + + + + + + + + + + + + + + + + + + INSERT INTO goods + + biz_group_id, code, name, price, inventory, gid, + vendor, + + VALUES + + #{biz_group_id}, #{code}, #{name}, #{price}, #{inventory}, #{gid}, + #{vendor}, + + + + + UPDATE goods + + code = #{code}, + name = #{name}, + price = #{price}, + inventory = #{inventory}, + vendor = #{vendor}, + gid = #{gid}, + + WHERE goods_id = #{goods_id} + + + + + DELETE FROM goods + WHERE goods_id IN + + #{id} + + + + + + + + + INSERT INTO device_goods ( + device_id, slot, goods_id, price, inventory, idx, inventory_max, inventory_alarm + ) VALUES + + ( + #{device_id}, #{item.slot}, #{item.goods_id}, #{item.price}, #{item.inventory}, #{item.idx}, #{item.inventory_max}, #{item.inventory_alarm} + ) + + + + + + UPDATE device_goods dg + JOIN transactions t + ON dg.device_id = t.device_id + AND dg.slot = t.slot + SET dg.inventory = dg.inventory + 1 + WHERE t.approval = #{approval} + + + + UPDATE device_goods + + inventory = inventory - 1 + + WHERE device_id = #{device_id} AND slot = #{slot} + + + + + + UPDATE device_goods dg + JOIN transactions t + ON dg.device_id = t.device_id + AND dg.slot = t.slot + SET dg.inventory = dg.inventory + 1 + WHERE t.approval = #{approval} + + + UPDATE device_goods + + inventory = inventory - 1 + + WHERE device_id = #{device_id} AND slot = #{slot} + + + + + + + DELETE FROM device_goods + WHERE device_id = #{device_id} AND slot IN + + #{item.slot} + + + + + + + + + + + + INSERT INTO goods_template ( + biz_group_id, name, inventory, inventory_max, inventory_alarm + ) VALUES ( + #{biz_group_id}, #{name}, #{inventory}, #{inventory_max}, #{inventory_alarm} + ) + + + + + INSERT INTO goods_template_element ( + slot, goods_id, inventory, goods_template_id,idx,inventory_max,inventory_alarm + ) VALUES + + ( + #{item.slot}, #{item.goods_id}, #{item.inventory}, #{goods_template_id}, #{item.idx}, #{item.inventory_max}, #{item.inventory_alarm} + ) + + + + + + UPDATE goods_template + + name = #{name}, + + WHERE goods_template_id = #{goods_template_id} + + + + DELETE FROM goods_template_element + WHERE goods_template_id = #{goods_template_id} + + + + DELETE FROM goods_template + WHERE goods_template_id = #{goods_template_id} + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/resources/mapper/LocationMapper.xml b/smartservice_backend/src/main/resources/mapper/LocationMapper.xml new file mode 100644 index 0000000..6831208 --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/LocationMapper.xml @@ -0,0 +1,212 @@ + + + + + + + + + + + INSERT INTO location + + name, gid, + description, + address, + pid, + + VALUES + + #{name}, #{gid}, + #{description}, + #{address}, + #{pid}, + + + + + UPDATE location + + name = #{name}, + description = #{description}, + address = #{address}, + pid = #{pid}, + + WHERE location_id = #{location_id} + + + + + UPDATE location + SET state = #{state} + WHERE location_id IN + + #{id} + + + + + + UPDATE location + + + SET pid = #{new_pid} + + + SET pid = NULL + + + WHERE pid IN + + #{id} + + + + + + UPDATE location + SET state=#{state} + WHERE location_id IN + + #{id} + + + + + + + + + + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/resources/mapper/Notice.xml b/smartservice_backend/src/main/resources/mapper/Notice.xml new file mode 100644 index 0000000..7bc61f8 --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/Notice.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + INSERT INTO notice + + title, content, gid, + + VALUES + + #{title}, #{content}, #{gid}, + + + + + UPDATE notice + + title = #{title}, + content = #{content}, + + WHERE notice_id = #{notice_id} + + + + + UPDATE notice + SET state = #{state} + WHERE notice_id IN + + #{id} + + + + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/resources/mapper/OperatingHistory.xml b/smartservice_backend/src/main/resources/mapper/OperatingHistory.xml new file mode 100644 index 0000000..d26a49b --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/OperatingHistory.xml @@ -0,0 +1,44 @@ + + + + + + + + + INSERT INTO operating_history + + type, action, gid, + + VALUES + + #{type}, #{action}, #{gid}, + + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/resources/mapper/OrdersMapper.xml b/smartservice_backend/src/main/resources/mapper/OrdersMapper.xml new file mode 100644 index 0000000..137ffe2 --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/OrdersMapper.xml @@ -0,0 +1,174 @@ + + + + + + + AND o.state != 2 + + AND o.order_id = #{param.order_id} + + + + AND b.name LIKE CONCAT('%', #{param.biz_group_name}, '%') + + + + AND CONCAT(a.last_name, a.first_name) + LIKE CONCAT('%', #{param.name}, '%') + + + + AND o.reg_time >= #{param.date_start} + + + + AND o.reg_time <= #{param.date_end} + + + + + + + + INSERT INTO orders + + biz_group_id, + state, + is_doc_accept, + is_tid, + is_card, + is_samchip, + is_comm_open, + is_shipping, + is_tested, + is_parcel, + order_time, + goods_list_id, + delivery_address, + delivery_recv_name, + delivery_recv_phone, + delivery_invoice_no, + delivery_company, + delivery_req_time, + gid + + VALUES + + #{biz_group_id}, + #{state}, + #{is_doc_accept}, + #{is_tid}, + #{is_card}, + #{is_samchip}, + #{is_comm_open}, + #{is_shipping}, + #{is_tested}, + #{is_parcel}, + #{order_time}, + #{goods_list_id}, + #{delivery_address}, + #{delivery_recv_name}, + #{delivery_recv_phone}, + #{delivery_invoice_no}, + #{delivery_company}, + #{delivery_req_time}, + #{gid} + + + + + UPDATE orders + + biz_group_id = #{biz_group_id}, + state = #{state}, + is_doc_accept = #{is_doc_accept}, + is_tid = #{is_tid}, + is_card = #{is_card}, + is_samchip = #{is_samchip}, + is_comm_open = #{is_comm_open}, + is_shipping = #{is_shipping}, + is_tested = #{is_tested}, + is_parcel = #{is_parcel}, + goods_list_id = #{goods_list_id}, + delivery_address = #{delivery_address}, + delivery_recv_name = #{delivery_recv_name}, + delivery_recv_phone = #{delivery_recv_phone}, + delivery_invoice_no = #{delivery_invoice_no}, + delivery_company = #{delivery_company}, + + + WHERE order_id = #{order_id} + + + + UPDATE orders + SET state = #{state} + WHERE order_id = #{order_id} + + + + UPDATE orders + SET ${statusKey} = #{statusValue} + WHERE order_id = #{order_id} + + + + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/resources/mapper/ResourceBoardMapper.xml b/smartservice_backend/src/main/resources/mapper/ResourceBoardMapper.xml new file mode 100644 index 0000000..7f2b204 --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/ResourceBoardMapper.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + INSERT INTO resource_board + + title, content, gid, + + VALUES + + #{title}, #{content}, #{gid}, + + + + + UPDATE resource_board + + title = #{title}, + content = #{content}, + + WHERE resource_board_id = #{resource_board_id} + + + + + UPDATE resource_board + SET state = #{state} + WHERE resource_board_id IN + + #{id} + + + + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/resources/mapper/TerminalMapper.xml b/smartservice_backend/src/main/resources/mapper/TerminalMapper.xml new file mode 100644 index 0000000..d15bd67 --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/TerminalMapper.xml @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + INSERT INTO terminal + + name, uid1, gid, + state, + type, + manager_name, + device_id, + + VALUES + + #{name}, #{uid1}, #{gid}, + #{state}, + #{type}, + #{manager_name}, + #{device_id}, + + + + + UPDATE terminal + + name = #{name}, + uid1 = #{uid1}, + type = #{type}, + manager_name = #{manager_name}, + gid = #{gid}, + + WHERE terminal_id = #{terminal_id} + + + + UPDATE terminal + SET state = #{state} + WHERE terminal_id = ( + SELECT terminal_id + FROM device + WHERE device_id = #{device_id} + ) + + + + UPDATE terminal + SET state = #{state} + WHERE terminal_id = #{terminal_id} + + + + + UPDATE terminal + SET state = #{state} + WHERE terminal_id IN + + #{id} + + + + + + + DELETE FROM terminal + WHERE terminal_id = #{terminal_id} + + + + + UPDATE terminal + + device_id = #{device_id}, state = #{state}, name = #{name} + + WHERE terminal_id = #{terminal_id} + + + + UPDATE terminal + + device_id = NULL, state = 5 + + WHERE device_id = #{device_id} + + + + INSERT INTO terminal_biz_group + + biz_group_id, terminal_id, + + VALUES + + #{biz_group_id}, #{terminal_id}, + + + + + DELETE FROM terminal_biz_group + WHERE terminal_id = #{terminal_id} AND biz_group_id = #{biz_group_id} + + + + UPDATE terminal + + + connect_time = NOW(), + + + disconnect_time = NOW(), + + + WHERE uid1 = #{uid1} AND type = #{type} + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/resources/mapper/TransactionMapper.xml b/smartservice_backend/src/main/resources/mapper/TransactionMapper.xml new file mode 100644 index 0000000..c8bcdf0 --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/TransactionMapper.xml @@ -0,0 +1,353 @@ + + + + + + + + + + + + + + + INSERT INTO transactions + + reg_time, process, + biz_group_id, + device_id, + uid1, + uid1_type, + order_time, + type, + amount, + approval, + pay_unique_num, + slot, + code, + goods_name, + price, + pay_name, + pay_vendor + + VALUES + + NOW(), 1, + #{biz_group_id}, + #{device_id}, + #{uid1}, + #{uid1_type}, + #{order_time}, + #{type}, + #{amount}, + #{approval}, + #{pay_unique_num}, + #{slot}, + #{code}, + #{goods_name}, + #{price}, + #{pay_name}, + #{pay_vendor} + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/resources/mapper/VocMapper.xml b/smartservice_backend/src/main/resources/mapper/VocMapper.xml new file mode 100644 index 0000000..30a3844 --- /dev/null +++ b/smartservice_backend/src/main/resources/mapper/VocMapper.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + INSERT INTO voc + + title, content, gid, + + VALUES + + #{title}, #{content}, #{gid}, + + + + + UPDATE voc + + title = #{title}, + content = #{content}, + + WHERE voc_id = #{voc_id} + + + + + UPDATE voc + SET state = #{state} + WHERE voc_id IN + + #{id} + + + + + + \ No newline at end of file diff --git a/smartservice_backend/src/main/webapp/WEB-INF/index.jsp b/smartservice_backend/src/main/webapp/WEB-INF/index.jsp new file mode 100644 index 0000000..8e69cde --- /dev/null +++ b/smartservice_backend/src/main/webapp/WEB-INF/index.jsp @@ -0,0 +1,237 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" trimDirectiveWhitespaces="true" %> + + + + + + + + + + + + + + index.jsp

+ CRUD example



+ ---------------------------------------
+
+ ---------------------------------------
+
select1
+
select2
+
select3
+
select4
+
select5
+ ---------------------------------------
+ update
+ ---------------------------------------
+

delete

+ + + + diff --git a/smartservice_backend/src/test/java/com/handong/smartservice/SmartServiceApplicationTests.java b/smartservice_backend/src/test/java/com/handong/smartservice/SmartServiceApplicationTests.java new file mode 100644 index 0000000..69cc9f9 --- /dev/null +++ b/smartservice_backend/src/test/java/com/handong/smartservice/SmartServiceApplicationTests.java @@ -0,0 +1,13 @@ +package com.handong.smartservice; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class SmartServiceApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/smartservice_frontend/.env b/smartservice_frontend/.env new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/smartservice_frontend/.env @@ -0,0 +1 @@ + diff --git a/smartservice_frontend/.env.development b/smartservice_frontend/.env.development new file mode 100644 index 0000000..ecafb2b --- /dev/null +++ b/smartservice_frontend/.env.development @@ -0,0 +1 @@ +NEXT_OUTPUT=standalone diff --git a/smartservice_frontend/.env.production b/smartservice_frontend/.env.production new file mode 100644 index 0000000..e69de29 diff --git a/smartservice_frontend/.eslintrc.json b/smartservice_frontend/.eslintrc.json new file mode 100644 index 0000000..2d7948b --- /dev/null +++ b/smartservice_frontend/.eslintrc.json @@ -0,0 +1,7 @@ +{ + "extends": "next/core-web-vitals", + "rules": { //Bruce + "@typescript-eslint/no-unused-vars": "off", + "no-unused-vars": "off" + } +} diff --git a/smartservice_frontend/.gitignore b/smartservice_frontend/.gitignore new file mode 100644 index 0000000..ee7513e --- /dev/null +++ b/smartservice_frontend/.gitignore @@ -0,0 +1,34 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/.idea +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/smartservice_frontend/LICENSE b/smartservice_frontend/LICENSE new file mode 100644 index 0000000..cb92d41 --- /dev/null +++ b/smartservice_frontend/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 TailAdmin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/smartservice_frontend/README.md b/smartservice_frontend/README.md new file mode 100644 index 0000000..b472823 --- /dev/null +++ b/smartservice_frontend/README.md @@ -0,0 +1,37 @@ +## Overview + +- Next.js 15.x +- React 19 +- TypeScript +- Tailwind CSS V4 + + +> Windows Users: place the repository near the root of your drive if you face issues while cloning. + +1. Install dependencies: + ```bash + npm install + # or + yarn install + ``` + > Use `--legacy-peer-deps` flag if you face peer-dependency error during installation. + +2. Start the development server: + ```bash + npm run dev + # or + yarn dev + ``` + +3. 정적빌드 - SG (Static Generation) + npm run build + +4. 정적빌드 테스트 + node server.js + + + +* 환경변수 파일 +npm run dev : .env -> .env.development -> .env.local +npm run build : .env -> .env.production -> .env.local + diff --git a/smartservice_frontend/banner.png b/smartservice_frontend/banner.png new file mode 100644 index 0000000..1b8c2f3 Binary files /dev/null and b/smartservice_frontend/banner.png differ diff --git a/smartservice_frontend/eslint.config.mjs b/smartservice_frontend/eslint.config.mjs new file mode 100644 index 0000000..483cf97 --- /dev/null +++ b/smartservice_frontend/eslint.config.mjs @@ -0,0 +1,23 @@ +import { dirname } from "path"; +import { fileURLToPath } from "url"; +import { FlatCompat } from "@eslint/eslintrc"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const compat = new FlatCompat({ + baseDirectory: __dirname, +}); + +const eslintConfig = [ + ...compat.extends("next/core-web-vitals", "next/typescript"), + { + rules: { + //"@typescript-eslint/no-unused-vars": ["warn"], //Bruce + "@typescript-eslint/no-unused-vars": "off", //Bruce + "@typescript-eslint/no-explicit-any": "off", //Bruce + } + }, +]; + +export default eslintConfig; diff --git a/smartservice_frontend/jsvectormap.d.ts b/smartservice_frontend/jsvectormap.d.ts new file mode 100644 index 0000000..740f3c9 --- /dev/null +++ b/smartservice_frontend/jsvectormap.d.ts @@ -0,0 +1,4 @@ +declare module 'jsvectormap' { + const jsVectorMap: any; + export default jsVectorMap; +} diff --git a/smartservice_frontend/next.config.ts b/smartservice_frontend/next.config.ts new file mode 100644 index 0000000..95d355e --- /dev/null +++ b/smartservice_frontend/next.config.ts @@ -0,0 +1,19 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ + webpack(config) { + config.module.rules.push({ + test: /\.svg$/, + use: ["@svgr/webpack"], + }); + return config; + }, + //output: 'export', //Bruce + output: (process.env.NEXT_OUTPUT as any) ?? "export", //Bruce + images: { + unoptimized: true, //Bruce + }, +}; + +export default nextConfig; diff --git a/smartservice_frontend/package-lock.json b/smartservice_frontend/package-lock.json new file mode 100644 index 0000000..ff594c4 --- /dev/null +++ b/smartservice_frontend/package-lock.json @@ -0,0 +1,10967 @@ +{ + "name": "handong_frontend", + "version": "1.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "handong_frontend", + "version": "1.0.1", + "dependencies": { + "@fullcalendar/core": "^6.1.15", + "@fullcalendar/daygrid": "^6.1.15", + "@fullcalendar/interaction": "^6.1.15", + "@fullcalendar/list": "^6.1.15", + "@fullcalendar/react": "^6.1.15", + "@fullcalendar/timegrid": "^6.1.15", + "@react-jvectormap/core": "^1.0.4", + "@react-jvectormap/world": "^1.1.2", + "@tailwindcss/forms": "^0.5.9", + "@tailwindcss/postcss": "^4.0.9", + "apexcharts": "^4.3.0", + "autoprefixer": "^10.4.20", + "axios": "^1.6.0", + "express": "^5.1.0", + "flatpickr": "^4.6.13", + "http-proxy-middleware": "^3.0.5", + "jwt-decode": "^4.0.0", + "morgan": "^1.10.1", + "next": "^15.5.6", + "rc-tree": "^5.13.1", + "react": "^19.0.0", + "react-apexcharts": "^1.7.0", + "react-dnd": "^16.0.1", + "react-dnd-html5-backend": "^16.0.1", + "react-dom": "^19.0.0", + "react-dropzone": "^14.3.5", + "react-hook-form": "^7.66.0", + "swiper": "^11.2.0", + "tailwind-merge": "^2.6.0", + "zustand": "^5.0.8" + }, + "devDependencies": { + "@eslint/eslintrc": "^3", + "@svgr/webpack": "^8.1.0", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "@types/react-transition-group": "^4.4.12", + "eslint": "^9", + "eslint-config-next": "15.1.3", + "postcss": "^8", + "serve": "^14.2.5", + "tailwindcss": "^4.0.0", + "typescript": "^5" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "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/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", + "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.10" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", + "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", + "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", + "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", + "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", + "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", + "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", + "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", + "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", + "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", + "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz", + "integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", + "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", + "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", + "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", + "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", + "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", + "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", + "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", + "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-constant-elements": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz", + "integrity": "sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-display-name": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz", + "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz", + "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-development": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz", + "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-transform-react-jsx": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-pure-annotations": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", + "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", + "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", + "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz", + "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", + "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", + "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz", + "integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.27.1", + "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.28.0", + "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.5", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.28.3", + "@babel/plugin-transform-classes": "^7.28.4", + "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.0", + "@babel/plugin-transform-exponentiation-operator": "^7.28.5", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.28.5", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", + "@babel/plugin-transform-numeric-separator": "^7.27.1", + "@babel/plugin-transform-object-rest-spread": "^7.28.4", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.28.5", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.27.1", + "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.28.4", + "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-react": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz", + "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-transform-react-display-name": "^7.28.0", + "@babel/plugin-transform-react-jsx": "^7.27.1", + "@babel/plugin-transform-react-jsx-development": "^7.27.1", + "@babel/plugin-transform-react-pure-annotations": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz", + "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.6.0.tgz", + "integrity": "sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.6.0.tgz", + "integrity": "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "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/js": { + "version": "9.39.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.0.tgz", + "integrity": "sha512-BIhe0sW91JGPiaF1mOuPy5v8NflqfjIcDNpC+LbW9f609WVRX1rArrhi6Z2ymvrAry9jw+5POTj4t2t62o8Bmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@fullcalendar/core": { + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.19.tgz", + "integrity": "sha512-z0aVlO5e4Wah6p6mouM0UEqtRf1MZZPt4mwzEyU6kusaNL+dlWQgAasF2cK23hwT4cmxkEmr4inULXgpyeExdQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "preact": "~10.12.1" + } + }, + "node_modules/@fullcalendar/daygrid": { + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.19.tgz", + "integrity": "sha512-IAAfnMICnVWPjpT4zi87i3FEw0xxSza0avqY/HedKEz+l5MTBYvCDPOWDATpzXoLut3aACsjktIyw9thvIcRYQ==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.19" + } + }, + "node_modules/@fullcalendar/interaction": { + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/@fullcalendar/interaction/-/interaction-6.1.19.tgz", + "integrity": "sha512-GOciy79xe8JMVp+1evAU3ytdwN/7tv35t5i1vFkifiuWcQMLC/JnLg/RA2s4sYmQwoYhTw/p4GLcP0gO5B3X5w==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.19" + } + }, + "node_modules/@fullcalendar/list": { + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/@fullcalendar/list/-/list-6.1.19.tgz", + "integrity": "sha512-knZHpAVF0LbzZpSJSUmLUUzF0XlU/MRGK+Py2s0/mP93bCtno1k2L3XPs/kzh528hSjehwLm89RgKTSfW1P6cA==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.19" + } + }, + "node_modules/@fullcalendar/react": { + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/@fullcalendar/react/-/react-6.1.19.tgz", + "integrity": "sha512-FP78vnyylaL/btZeHig8LQgfHgfwxLaIG6sKbNkzkPkKEACv11UyyBoTSkaavPsHtXvAkcTED1l7TOunAyPEnA==", + "license": "MIT", + "peerDependencies": { + "@fullcalendar/core": "~6.1.19", + "react": "^16.7.0 || ^17 || ^18 || ^19", + "react-dom": "^16.7.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/@fullcalendar/timegrid": { + "version": "6.1.19", + "resolved": "https://registry.npmjs.org/@fullcalendar/timegrid/-/timegrid-6.1.19.tgz", + "integrity": "sha512-OuzpUueyO9wB5OZ8rs7TWIoqvu4v3yEqdDxZ2VcsMldCpYJRiOe7yHWKr4ap5Tb0fs7Rjbserc/b6Nt7ol6BRg==", + "license": "MIT", + "dependencies": { + "@fullcalendar/daygrid": "~6.1.19" + }, + "peerDependencies": { + "@fullcalendar/core": "~6.1.19" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.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, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.4.tgz", + "integrity": "sha512-sitdlPzDVyvmINUdJle3TNHl+AG9QcwiAMsXmccqsCOMZNIdW2/7S26w0LyU8euiLVzFBL3dXPwVCq/ODnf2vA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.3" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.4.tgz", + "integrity": "sha512-rZheupWIoa3+SOdF/IcUe1ah4ZDpKBGWcsPX6MT0lYniH9micvIU7HQkYTfrx5Xi8u+YqwLtxC/3vl8TQN6rMg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.3" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.3.tgz", + "integrity": "sha512-QzWAKo7kpHxbuHqUC28DZ9pIKpSi2ts2OJnoIGI26+HMgq92ZZ4vk8iJd4XsxN+tYfNJxzH6W62X5eTcsBymHw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.3.tgz", + "integrity": "sha512-Ju+g2xn1E2AKO6YBhxjj+ACcsPQRHT0bhpglxcEf+3uyPY+/gL8veniKoo96335ZaPo03bdDXMv0t+BBFAbmRA==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.3.tgz", + "integrity": "sha512-x1uE93lyP6wEwGvgAIV0gP6zmaL/a0tGzJs/BIDDG0zeBhMnuUPm7ptxGhUbcGs4okDJrk4nxgrmxpib9g6HpA==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.3.tgz", + "integrity": "sha512-I4RxkXU90cpufazhGPyVujYwfIm9Nk1QDEmiIsaPwdnm013F7RIceaCc87kAH+oUB1ezqEvC6ga4m7MSlqsJvQ==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.3.tgz", + "integrity": "sha512-Y2T7IsQvJLMCBM+pmPbM3bKT/yYJvVtLJGfCs4Sp95SjvnFIjynbjzsa7dY1fRJX45FTSfDksbTp6AGWudiyCg==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.3.tgz", + "integrity": "sha512-RgWrs/gVU7f+K7P+KeHFaBAJlNkD1nIZuVXdQv6S+fNA6syCcoboNjsV2Pou7zNlVdNQoQUpQTk8SWDHUA3y/w==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.3.tgz", + "integrity": "sha512-3JU7LmR85K6bBiRzSUc/Ff9JBVIFVvq6bomKE0e63UXGeRw2HPVEjoJke1Yx+iU4rL7/7kUjES4dZ/81Qjhyxg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.3.tgz", + "integrity": "sha512-F9q83RZ8yaCwENw1GieztSfj5msz7GGykG/BA+MOUefvER69K/ubgFHNeSyUu64amHIYKGDs4sRCMzXVj8sEyw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.3.tgz", + "integrity": "sha512-U5PUY5jbc45ANM6tSJpsgqmBF/VsL6LnxJmIf11kB7J5DctHgqm0SkuXzVWtIY90GnJxKnC/JT251TDnk1fu/g==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.4.tgz", + "integrity": "sha512-Xyam4mlqM0KkTHYVSuc6wXRmM7LGN0P12li03jAnZ3EJWZqj83+hi8Y9UxZUbxsgsK1qOEwg7O0Bc0LjqQVtxA==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.3" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.4.tgz", + "integrity": "sha512-YXU1F/mN/Wu786tl72CyJjP/Ngl8mGHN1hST4BGl+hiW5jhCnV2uRVTNOcaYPs73NeT/H8Upm3y9582JVuZHrQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.3" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.4.tgz", + "integrity": "sha512-F4PDtF4Cy8L8hXA2p3TO6s4aDt93v+LKmpcYFLAVdkkD3hSxZzee0rh6/+94FpAynsuMpLX5h+LRsSG3rIciUQ==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.3" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.4.tgz", + "integrity": "sha512-qVrZKE9Bsnzy+myf7lFKvng6bQzhNUAYcVORq2P7bDlvmF6u2sCmK2KyEQEBdYk+u3T01pVsPrkj943T1aJAsw==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.3" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.4.tgz", + "integrity": "sha512-ZfGtcp2xS51iG79c6Vhw9CWqQC8l2Ot8dygxoDoIQPTat/Ov3qAa8qpxSrtAEAJW+UjTXc4yxCjNfxm4h6Xm2A==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.3" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.4.tgz", + "integrity": "sha512-8hDVvW9eu4yHWnjaOOR8kHVrew1iIX+MUgwxSuH2XyYeNRtLUe4VNioSqbNkB7ZYQJj9rUTT4PyRscyk2PXFKA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.3" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.4.tgz", + "integrity": "sha512-lU0aA5L8QTlfKjpDCEFOZsTYGn3AEiO6db8W5aQDxj0nQkVrZWmN3ZP9sYKWJdtq3PWPhUNlqehWyXpYDcI9Sg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.3" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.4.tgz", + "integrity": "sha512-33QL6ZO/qpRyG7woB/HUALz28WnTMI2W1jgX3Nu2bypqLIKx/QKMILLJzJjI+SIbvXdG9fUnmrxR7vbi1sTBeA==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.5.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.4.tgz", + "integrity": "sha512-2Q250do/5WXTwxW3zjsEuMSv5sUU4Tq9VThWKlU2EYLm4MB7ZeMwF+SFJutldYODXF6jzc6YEOC+VfX0SZQPqA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.4.tgz", + "integrity": "sha512-3ZeLue5V82dT92CNL6rsal6I2weKw1cYu+rGKm8fOCCtJTR2gYeUfY3FqUnIJsMUPIH68oS5jmZ0NiJ508YpEw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.4.tgz", + "integrity": "sha512-xIyj4wpYs8J18sVN3mSQjwrw7fKUqRw+Z5rnHNCy5fYTxigBz81u5mOMPmFumwjcn8+ld1ppptMBCLic1nz6ig==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@next/env": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.12.tgz", + "integrity": "sha512-pUvdJN1on574wQHjaBfNGDt9Mz5utDSZFsIIQkMzPgNS8ZvT4H2mwOrOIClwsQOb6EGx5M76/CZr6G8i6pSpLg==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "15.1.3", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.1.3.tgz", + "integrity": "sha512-oeP1vnc5Cq9UoOb8SYHAEPbCXMzOgG70l+Zfd+Ie00R25FOm+CCVNrcIubJvB1tvBgakXE37MmqSycksXVPRqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "3.3.1" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.12.tgz", + "integrity": "sha512-RnRjBtH8S8eXCpUNkQ+543DUc7ys8y15VxmFU9HRqlo9BG3CcBUiwNtF8SNoi2xvGCVJq1vl2yYq+3oISBS0Zg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.12.tgz", + "integrity": "sha512-nqa9/7iQlboF1EFtNhWxQA0rQstmYRSBGxSM6g3GxvxHxcoeqVXfGNr9stJOme674m2V7r4E3+jEhhGvSQhJRA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.12.tgz", + "integrity": "sha512-dCzAjqhDHwmoB2M4eYfVKqXs99QdQxNQVpftvP1eGVppamXh/OkDAwV737Zr0KPXEqRUMN4uCjh6mjO+XtF3Mw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.12.tgz", + "integrity": "sha512-+fpGWvQiITgf7PUtbWY1H7qUSnBZsPPLyyq03QuAKpVoTy/QUx1JptEDTQMVvQhvizCEuNLEeghrQUyXQOekuw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.12.tgz", + "integrity": "sha512-jSLvgdRRL/hrFAPqEjJf1fFguC719kmcptjNVDJl26BnJIpjL3KH5h6mzR4mAweociLQaqvt4UyzfbFjgAdDcw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.12.tgz", + "integrity": "sha512-/uaF0WfmYqQgLfPmN6BvULwxY0dufI2mlN2JbOKqqceZh1G4hjREyi7pg03zjfyS6eqNemHAZPSoP84x17vo6w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.12.tgz", + "integrity": "sha512-xhsL1OvQSfGmlL5RbOmU+FV120urrgFpYLq+6U8C6KIym32gZT6XF/SDE92jKzzlPWskkbjOKCpqk5m4i8PEfg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.12.tgz", + "integrity": "sha512-Z1Dh6lhFkxvBDH1FoW6OU/L6prYwPSlwjLiZkExIAh8fbP6iI/M7iGTQAJPYJ9YFlWobCZ1PHbchFhFYb2ADkw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "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, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@react-dnd/asap": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz", + "integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==", + "license": "MIT" + }, + "node_modules/@react-dnd/invariant": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz", + "integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==", + "license": "MIT" + }, + "node_modules/@react-dnd/shallowequal": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz", + "integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==", + "license": "MIT" + }, + "node_modules/@react-jvectormap/core": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@react-jvectormap/core/-/core-1.0.4.tgz", + "integrity": "sha512-PefUtLG2Uwu6YVMldTqZCaVu5G+4wS3iQDq5aAV/jY/h8+djIgdSKWb1hEsHk/vb0s2pwallS+VvU7N2xCMncA==", + "license": "ISC", + "dependencies": { + "@react-jvectormap/lib": "^1.0.3", + "classnames": "^2.3.1" + }, + "peerDependencies": { + "jquery": "^3.6", + "react": "^16.8 || ^17 || ^18", + "react-dom": "^16.8 || ^17 || ^18" + } + }, + "node_modules/@react-jvectormap/jquery-mousewheel": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@react-jvectormap/jquery-mousewheel/-/jquery-mousewheel-1.0.2.tgz", + "integrity": "sha512-AmRnBdJfBjDUHreEDDs9qaSo3Q/6oC74m321VuzxkDX6ideVks2n2ouGiMcXq41GdJQoCUzSjfF8KyocL6M+SA==", + "license": "MIT", + "dependencies": { + "jquery": "^3.6.0" + } + }, + "node_modules/@react-jvectormap/lib": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@react-jvectormap/lib/-/lib-1.0.3.tgz", + "integrity": "sha512-EdPYen5GGrny7Mxc8IYvXtSdjTr3EfWjGCXuy6+0Yz9wZDmCfLFfjmuEOZirhe00BJOzi2LpnYMSp0WaJ2BH7Q==", + "license": "(AGPL OR Commercial)", + "dependencies": { + "@react-jvectormap/jquery-mousewheel": "^1.0.2" + } + }, + "node_modules/@react-jvectormap/world": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@react-jvectormap/world/-/world-1.1.2.tgz", + "integrity": "sha512-jDSy64DZz4mzEOrVni1zV5rak65+1WZhSGsvAvzHNIMHVx+tdD8R5OikyWUjYte8nxIkOUhQZtVJMK7VOIsmQA==", + "license": "MIT" + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.14.1.tgz", + "integrity": "sha512-jGTk8UD/RdjsNZW8qq10r0RBvxL8OWtoT+kImlzPDFilmozzM+9QmIJsmze9UiSBrFU45ZxhTYBypn9q9z/VfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@svgdotjs/svg.draggable.js": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.draggable.js/-/svg.draggable.js-3.0.6.tgz", + "integrity": "sha512-7iJFm9lL3C40HQcqzEfezK2l+dW2CpoVY3b77KQGqc8GXWa6LhhmX5Ckv7alQfUXBuZbjpICZ+Dvq1czlGx7gA==", + "license": "MIT", + "peerDependencies": { + "@svgdotjs/svg.js": "^3.2.4" + } + }, + "node_modules/@svgdotjs/svg.filter.js": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.filter.js/-/svg.filter.js-3.0.9.tgz", + "integrity": "sha512-/69XMRCDoam2HgC4ldHIaDgeQf1ViHIsa0Ld4uWgiXtZ+E24DWHe/9Ib6kbNiZ7WRIdlVokUDR1Fg0kjIpkfbw==", + "license": "MIT", + "dependencies": { + "@svgdotjs/svg.js": "^3.2.4" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/@svgdotjs/svg.js": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.js/-/svg.js-3.2.5.tgz", + "integrity": "sha512-/VNHWYhNu+BS7ktbYoVGrCmsXDh+chFMaONMwGNdIBcFHrWqk2jY8fNyr3DLdtQUIalvkPfM554ZSFa3dm3nxQ==", + "license": "MIT", + "peer": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Fuzzyma" + } + }, + "node_modules/@svgdotjs/svg.resize.js": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.resize.js/-/svg.resize.js-2.0.5.tgz", + "integrity": "sha512-4heRW4B1QrJeENfi7326lUPYBCevj78FJs8kfeDxn5st0IYPIRXoTtOSYvTzFWgaWWXd3YCDE6ao4fmv91RthA==", + "license": "MIT", + "engines": { + "node": ">= 14.18" + }, + "peerDependencies": { + "@svgdotjs/svg.js": "^3.2.4", + "@svgdotjs/svg.select.js": "^4.0.1" + } + }, + "node_modules/@svgdotjs/svg.select.js": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@svgdotjs/svg.select.js/-/svg.select.js-4.0.3.tgz", + "integrity": "sha512-qkMgso1sd2hXKd1FZ1weO7ANq12sNmQJeGDjs46QwDVsxSRcHmvWKL2NDF7Yimpwf3sl5esOLkPqtV2bQ3v/Jg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 14.18" + }, + "peerDependencies": { + "@svgdotjs/svg.js": "^3.2.4" + } + }, + "node_modules/@svgr/babel-plugin-add-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", + "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", + "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", + "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-dynamic-title": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", + "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-svg-em-dimensions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", + "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-react-native-svg": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", + "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-plugin-transform-svg-component": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", + "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/babel-preset": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", + "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-attribute": "8.0.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "8.0.0", + "@svgr/babel-plugin-replace-jsx-attribute-value": "8.0.0", + "@svgr/babel-plugin-svg-dynamic-title": "8.0.0", + "@svgr/babel-plugin-svg-em-dimensions": "8.0.0", + "@svgr/babel-plugin-transform-react-native-svg": "8.1.0", + "@svgr/babel-plugin-transform-svg-component": "8.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@svgr/core": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", + "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^8.1.3", + "snake-case": "^3.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/hast-util-to-babel-ast": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", + "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.21.3", + "entities": "^4.4.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@svgr/plugin-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", + "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@svgr/babel-preset": "8.1.0", + "@svgr/hast-util-to-babel-ast": "8.0.0", + "svg-parser": "^2.0.4" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/plugin-svgo": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", + "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^8.1.3", + "deepmerge": "^4.3.1", + "svgo": "^3.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + }, + "peerDependencies": { + "@svgr/core": "*" + } + }, + "node_modules/@svgr/webpack": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", + "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.21.3", + "@babel/plugin-transform-react-constant-elements": "^7.21.3", + "@babel/preset-env": "^7.20.2", + "@babel/preset-react": "^7.18.6", + "@babel/preset-typescript": "^7.21.0", + "@svgr/core": "8.1.0", + "@svgr/plugin-jsx": "8.1.0", + "@svgr/plugin-svgo": "8.1.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/gregberge" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tailwindcss/forms": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.10.tgz", + "integrity": "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==", + "license": "MIT", + "dependencies": { + "mini-svg-data-uri": "^1.2.3" + }, + "peerDependencies": { + "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1" + } + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.16.tgz", + "integrity": "sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.1", + "lightningcss": "1.30.2", + "magic-string": "^0.30.19", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.16" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.16.tgz", + "integrity": "sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg==", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.16", + "@tailwindcss/oxide-darwin-arm64": "4.1.16", + "@tailwindcss/oxide-darwin-x64": "4.1.16", + "@tailwindcss/oxide-freebsd-x64": "4.1.16", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.16", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.16", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.16", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.16", + "@tailwindcss/oxide-linux-x64-musl": "4.1.16", + "@tailwindcss/oxide-wasm32-wasi": "4.1.16", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.16", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.16" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.16.tgz", + "integrity": "sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.16.tgz", + "integrity": "sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.16.tgz", + "integrity": "sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.16.tgz", + "integrity": "sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.16.tgz", + "integrity": "sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.16.tgz", + "integrity": "sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.16.tgz", + "integrity": "sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.16.tgz", + "integrity": "sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.16.tgz", + "integrity": "sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.16.tgz", + "integrity": "sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.0.7", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.16.tgz", + "integrity": "sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.16.tgz", + "integrity": "sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.16.tgz", + "integrity": "sha512-Qn3SFGPXYQMKR/UtqS+dqvPrzEeBZHrFA92maT4zijCVggdsXnDBMsPFJo1eArX3J+O+Gi+8pV4PkqjLCNBk3A==", + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.16", + "@tailwindcss/oxide": "4.1.16", + "postcss": "^8.4.41", + "tailwindcss": "4.1.16" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.17", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz", + "integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.24.tgz", + "integrity": "sha512-FE5u0ezmi6y9OZEzlJfg37mqqf6ZDSF2V/NLjUyGrR9uTZ7Sb9F7bLNZ03S4XVUNRWGA7Ck4c1kK+YnuWjl+DA==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", + "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", + "devOptional": true, + "license": "MIT", + "peer": true, + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz", + "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.2.tgz", + "integrity": "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.46.2", + "@typescript-eslint/type-utils": "8.46.2", + "@typescript-eslint/utils": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.46.2", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.2.tgz", + "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz", + "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.2", + "@typescript-eslint/types": "^8.46.2", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz", + "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz", + "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.2.tgz", + "integrity": "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2", + "@typescript-eslint/utils": "8.46.2", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz", + "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz", + "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.2", + "@typescript-eslint/tsconfig-utils": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "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.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/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, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.2.tgz", + "integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz", + "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "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==", + "license": "MIT" + }, + "node_modules/@zeit/schemas": { + "version": "2.36.0", + "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.36.0.tgz", + "integrity": "sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==", + "dev": true, + "license": "MIT" + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "peer": 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, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "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, + "license": "MIT", + "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/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/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, + "license": "MIT" + }, + "node_modules/ansi-align/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, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/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, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "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, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/apexcharts": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-4.7.0.tgz", + "integrity": "sha512-iZSrrBGvVlL+nt2B1NpqfDuBZ9jX61X9I2+XV0hlYXHtTwhwLTHDKGXjNXAgFBDLuvSYCB/rq2nPWVPRv2DrGA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@svgdotjs/svg.draggable.js": "^3.0.4", + "@svgdotjs/svg.filter.js": "^3.0.8", + "@svgdotjs/svg.js": "^3.2.4", + "@svgdotjs/svg.resize.js": "^2.0.2", + "@svgdotjs/svg.select.js": "^4.0.1", + "@yr/monotone-cubic-spline": "^1.0.3" + } + }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "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" + } + ], + "license": "MIT" + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/attr-accept": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.5.tgz", + "integrity": "sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/autoprefixer": { + "version": "10.4.21", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz", + "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.24.4", + "caniuse-lite": "^1.0.30001702", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz", + "integrity": "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axios": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.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, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.23", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.23.tgz", + "integrity": "sha512-616V5YX4bepJFzNyOfce5Fa8fDJMfoxzOIzDCZwaGL8MKVpFrXqfNUoIpRn9YMI5pXf/VKgzjB4htFMsFKKdiQ==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "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==", + "license": "MIT", + "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==", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz", + "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "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, + "license": "ISC" + }, + "node_modules/boxen": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.0.tgz", + "integrity": "sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.0", + "chalk": "^5.0.1", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "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==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", + "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" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001753", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001753.tgz", + "integrity": "sha512-Bj5H35MD/ebaOV4iDLqPEtiliTN29qkGtEHCwawWn4cYm+bPJM2NsaP30vtZcnERClMzp52J4+aw2UNbK4o+zw==", + "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" + } + ], + "license": "CC-BY-4.0" + }, + "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, + "license": "MIT", + "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-template": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", + "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", + "license": "MIT" + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/clipboardy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz", + "integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arch": "^2.2.0", + "execa": "^5.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.1.0", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/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, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "dev": true, + "license": "MIT", + "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==", + "license": "MIT", + "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, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.46.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.46.0.tgz", + "integrity": "sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.26.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "devOptional": true, + "license": "MIT" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.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, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dnd-core": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz", + "integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==", + "license": "MIT", + "dependencies": { + "@react-dnd/asap": "^5.0.1", + "@react-dnd/invariant": "^4.0.1", + "redux": "^4.2.0" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.244", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.244.tgz", + "integrity": "sha512-OszpBN7xZX4vWMPJwB9illkN/znA8M36GQqQxi6MNy9axWxhOfJyZZJtSLQCpEFLHP2xK33BiWx9aIuIEXVCcw==", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "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": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.0.tgz", + "integrity": "sha512-iy2GE3MHrYTL5lrCtMZ0X1KLEKKUjmK0kzwcnefhR66txcEmXZD2YWgR5GNdcEwkNx3a0siYkSvl0vIC+Svjmg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.0", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.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" + }, + "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-config-next": { + "version": "15.1.3", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.1.3.tgz", + "integrity": "sha512-wGYlNuWnh4ujuKtZvH+7B2Z2vy9nONZE6ztd+DKF7hAsIabkrxmD4TzYHzASHENo42lmz2tnT2B+zN2sOHvpJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "15.1.3", + "@rushstack/eslint-patch": "^1.10.3", + "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-react": "^7.37.0", + "eslint-plugin-react-hooks": "^5.0.0" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", + "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.4.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^2.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.13", + "unrs-resolver": "^1.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "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": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "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/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "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, + "license": "BSD-2-Clause", + "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, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "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, + "license": "BSD-2-Clause", + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/express": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", + "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.0", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "license": "MIT", + "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, + "license": "ISC", + "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, + "license": "MIT" + }, + "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, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "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, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/file-selector": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-2.1.2.tgz", + "integrity": "sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==", + "license": "MIT", + "dependencies": { + "tslib": "^2.7.0" + }, + "engines": { + "node": ">= 12" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", + "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatpickr": { + "version": "4.6.13", + "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.13.tgz", + "integrity": "sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw==", + "license": "MIT" + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "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, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "license": "MIT", + "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.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "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==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz", + "integrity": "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==", + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", + "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "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, + "license": "MIT", + "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==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-bun-module/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "license": "MIT", + "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": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-port-reachable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-4.0.0.tgz", + "integrity": "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "license": "MIT", + "peer": 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==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "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, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT" + }, + "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, + "license": "MIT" + }, + "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, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/jwt-decode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz", + "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "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, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "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, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.0.3" + } + }, + "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, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "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, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "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==", + "license": "MIT", + "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==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mini-svg-data-uri": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", + "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", + "license": "MIT", + "bin": { + "mini-svg-data-uri": "cli.js" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/morgan": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz", + "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==", + "license": "MIT", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.1.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/morgan/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/morgan/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "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==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "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, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/next": { + "version": "15.5.12", + "resolved": "https://registry.npmjs.org/next/-/next-15.5.12.tgz", + "integrity": "sha512-Fi/wQ4Etlrn60rz78bebG1i1SR20QxvV8tVp6iJspjLUSHcZoeUXCt+vmWoEcza85ElZzExK/jJ/F6SvtGktjA==", + "license": "MIT", + "dependencies": { + "@next/env": "15.5.12", + "@swc/helpers": "0.5.15", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "15.5.12", + "@next/swc-darwin-x64": "15.5.12", + "@next/swc-linux-arm64-gnu": "15.5.12", + "@next/swc-linux-arm64-musl": "15.5.12", + "@next/swc-linux-x64-gnu": "15.5.12", + "@next/swc-linux-x64-musl": "15.5.12", + "@next/swc-win32-arm64-msvc": "15.5.12", + "@next/swc-win32-x64-msvc": "15.5.12", + "sharp": "^0.34.3" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "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.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "license": "MIT", + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "license": "MIT" + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "license": "BSD-2-Clause", + "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "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==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "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, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "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", + "peer": true, + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/preact": { + "version": "10.12.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", + "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "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==", + "license": "MIT", + "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==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "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" + } + ], + "license": "MIT" + }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc-motion": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.5.tgz", + "integrity": "sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.44.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-resize-observer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.3.tgz", + "integrity": "sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.7", + "classnames": "^2.2.1", + "rc-util": "^5.44.1", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tree": { + "version": "5.13.1", + "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.13.1.tgz", + "integrity": "sha512-FNhIefhftobCdUJshO7M8uZTA9F4OPGVXqGfZkkD/5soDeOhwO06T/aKTrg0WD8gRg/pyfq+ql3aMymLHCTC4A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.5.1" + }, + "engines": { + "node": ">=10.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-util": { + "version": "5.44.4", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.44.4.tgz", + "integrity": "sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "react-is": "^18.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-util/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/rc-virtual-list": { + "version": "3.19.2", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.19.2.tgz", + "integrity": "sha512-Ys6NcjwGkuwkeaWBDqfI3xWuZ7rDiQXlH1o2zLfFzATfEgXcqpk8CkgMfbJD81McqjcJVez25a3kPxCR807evA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.20.0", + "classnames": "^2.2.6", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.36.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", + "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-apexcharts": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/react-apexcharts/-/react-apexcharts-1.8.0.tgz", + "integrity": "sha512-MuEp56gc0NMO2UUgY94fxQzoBE4XEjmcCha4xYY0vJdRrc1yfFFZE4QrCekOt2wcS3nibghzca/q/CbgkAgN5w==", + "license": "SEE LICENSE IN LICENSE", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "apexcharts": ">=4.0.0", + "react": ">=0.13" + } + }, + "node_modules/react-dnd": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz", + "integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==", + "license": "MIT", + "dependencies": { + "@react-dnd/invariant": "^4.0.1", + "@react-dnd/shallowequal": "^4.0.1", + "dnd-core": "^16.0.1", + "fast-deep-equal": "^3.1.3", + "hoist-non-react-statics": "^3.3.2" + }, + "peerDependencies": { + "@types/hoist-non-react-statics": ">= 3.3.1", + "@types/node": ">= 12", + "@types/react": ">= 16", + "react": ">= 16.14" + }, + "peerDependenciesMeta": { + "@types/hoist-non-react-statics": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-dnd-html5-backend": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-16.0.1.tgz", + "integrity": "sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==", + "license": "MIT", + "dependencies": { + "dnd-core": "^16.0.1" + } + }, + "node_modules/react-dom": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", + "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, + "node_modules/react-dropzone": { + "version": "14.3.8", + "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.3.8.tgz", + "integrity": "sha512-sBgODnq+lcA4P296DY4wacOZz3JFpD99fp+hb//iBO2HHnyeZU3FwWyXJ6salNpqQdsZrgMrotuko/BdJMV8Ug==", + "license": "MIT", + "dependencies": { + "attr-accept": "^2.2.4", + "file-selector": "^2.1.0", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "react": ">= 16.8 || 18.0.0" + } + }, + "node_modules/react-hook-form": { + "version": "7.66.0", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.66.0.tgz", + "integrity": "sha512-xXBqsWGKrY46ZqaHDo+ZUYiMUgi8suYu5kdrS20EG8KiL7VRQitEbNjm+UcrDYrNi1YLyfpmAeGjCZYXLT9YBw==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-hook-form" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17 || ^18 || ^19" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/registry-auth-token": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", + "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", + "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==", + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/router/node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "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" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", + "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "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, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "mime-types": "^3.0.1", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/send/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/send/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/send/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==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve": { + "version": "14.2.6", + "resolved": "https://registry.npmjs.org/serve/-/serve-14.2.6.tgz", + "integrity": "sha512-QEjUSA+sD4Rotm1znR8s50YqA3kYpRGPmtd5GlFxbaL9n/FdUNbqMhxClqdditSk0LlZyA/dhud6XNRTOC9x2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zeit/schemas": "2.36.0", + "ajv": "8.18.0", + "arg": "5.0.2", + "boxen": "7.0.0", + "chalk": "5.0.1", + "chalk-template": "0.4.0", + "clipboardy": "3.0.0", + "compression": "1.8.1", + "is-port-reachable": "4.0.0", + "serve-handler": "6.1.7", + "update-check": "1.5.4" + }, + "bin": { + "serve": "build/main.js" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/serve-handler": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.7.tgz", + "integrity": "sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "mime-types": "2.1.18", + "minimatch": "3.1.5", + "path-is-inside": "1.0.2", + "path-to-regexp": "3.3.0", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/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, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-handler/node_modules/mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-handler/node_modules/mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "~1.33.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/serve/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/serve/node_modules/chalk": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", + "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/serve/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==", + "dev": true, + "license": "MIT" + }, + "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/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "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==", + "license": "ISC" + }, + "node_modules/sharp": { + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.4.tgz", + "integrity": "sha512-FUH39xp3SBPnxWvd5iib1X8XY7J0K0X7d93sie9CJg2PO8/7gmg89Nve6OjItK53/MlAushNNxteBYfM6DEuoA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.0", + "semver": "^7.7.2" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.4", + "@img/sharp-darwin-x64": "0.34.4", + "@img/sharp-libvips-darwin-arm64": "1.2.3", + "@img/sharp-libvips-darwin-x64": "1.2.3", + "@img/sharp-libvips-linux-arm": "1.2.3", + "@img/sharp-libvips-linux-arm64": "1.2.3", + "@img/sharp-libvips-linux-ppc64": "1.2.3", + "@img/sharp-libvips-linux-s390x": "1.2.3", + "@img/sharp-libvips-linux-x64": "1.2.3", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.3", + "@img/sharp-libvips-linuxmusl-x64": "1.2.3", + "@img/sharp-linux-arm": "0.34.4", + "@img/sharp-linux-arm64": "0.34.4", + "@img/sharp-linux-ppc64": "0.34.4", + "@img/sharp-linux-s390x": "0.34.4", + "@img/sharp-linux-x64": "0.34.4", + "@img/sharp-linuxmusl-arm64": "0.34.4", + "@img/sharp-linuxmusl-x64": "0.34.4", + "@img/sharp-wasm32": "0.34.4", + "@img/sharp-win32-arm64": "0.34.4", + "@img/sharp-win32-ia32": "0.34.4", + "@img/sharp-win32-x64": "0.34.4" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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, + "license": "MIT", + "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, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/snake-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", + "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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/stable-hash": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", + "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "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, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-parser": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", + "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/svgo": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.3.tgz", + "integrity": "sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^7.2.0", + "css-select": "^5.1.0", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.0.0", + "sax": "^1.5.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/swiper": { + "version": "11.2.10", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-11.2.10.tgz", + "integrity": "sha512-RMeVUUjTQH+6N3ckimK93oxz6Sn5la4aDlgPzB+rBrG/smPdCTicXyhxa+woIpopz+jewEloiEE3lKo1h9w2YQ==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "license": "MIT", + "engines": { + "node": ">= 4.7.0" + } + }, + "node_modules/tailwind-merge": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.0.tgz", + "integrity": "sha512-P+Vu1qXfzediirmHOC3xKGAYeZtPcV9g76X+xg2FD4tYgR71ewMA35Y3sCz3zhiN/dwefRpJX0yBcgwi1fXNQA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.16.tgz", + "integrity": "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==", + "license": "MIT", + "peer": true + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "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==", + "license": "MIT", + "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==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "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, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/update-check": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz", + "integrity": "sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "registry-auth-token": "3.3.2", + "registry-url": "3.1.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==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "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, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "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, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zustand": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz", + "integrity": "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } + } + } +} diff --git a/smartservice_frontend/package.json b/smartservice_frontend/package.json new file mode 100644 index 0000000..b4d42a3 --- /dev/null +++ b/smartservice_frontend/package.json @@ -0,0 +1,67 @@ +{ + "name": "handong_frontend", + "version": "1.0.1", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@fullcalendar/core": "^6.1.15", + "@fullcalendar/daygrid": "^6.1.15", + "@fullcalendar/interaction": "^6.1.15", + "@fullcalendar/list": "^6.1.15", + "@fullcalendar/react": "^6.1.15", + "@fullcalendar/timegrid": "^6.1.15", + "@react-jvectormap/core": "^1.0.4", + "@react-jvectormap/world": "^1.1.2", + "@tailwindcss/forms": "^0.5.9", + "@tailwindcss/postcss": "^4.0.9", + "apexcharts": "^4.3.0", + "autoprefixer": "^10.4.20", + "axios": "^1.6.0", + "express": "^5.1.0", + "flatpickr": "^4.6.13", + "http-proxy-middleware": "^3.0.5", + "jwt-decode": "^4.0.0", + "morgan": "^1.10.1", + "next": "^15.5.6", + "rc-tree": "^5.13.1", + "react": "^19.0.0", + "react-apexcharts": "^1.7.0", + "react-dnd": "^16.0.1", + "react-dnd-html5-backend": "^16.0.1", + "react-dom": "^19.0.0", + "react-dropzone": "^14.3.5", + "react-hook-form": "^7.66.0", + "swiper": "^11.2.0", + "tailwind-merge": "^2.6.0", + "zustand": "^5.0.8" + }, + "devDependencies": { + "@eslint/eslintrc": "^3", + "@svgr/webpack": "^8.1.0", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "@types/react-transition-group": "^4.4.12", + "eslint": "^9", + "eslint-config-next": "15.1.3", + "postcss": "^8", + "serve": "^14.2.5", + "tailwindcss": "^4.0.0", + "typescript": "^5" + }, + "overrides": { + "@react-jvectormap/core": { + "react": "^16.8.0 || ^17 || ^18 || ^19", + "react-dom": "^16.8.0 || ^17 || ^18 || ^19" + }, + "@react-jvectormap/world": { + "react": "^16.8.0 || ^17 || ^18 || ^19", + "react-dom": "^16.8.0 || ^17 || ^18 || ^19" + } + } +} diff --git a/smartservice_frontend/postcss.config.js b/smartservice_frontend/postcss.config.js new file mode 100644 index 0000000..e564072 --- /dev/null +++ b/smartservice_frontend/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + '@tailwindcss/postcss': {}, + }, +}; diff --git a/smartservice_frontend/prettier.config.js b/smartservice_frontend/prettier.config.js new file mode 100644 index 0000000..84faa16 --- /dev/null +++ b/smartservice_frontend/prettier.config.js @@ -0,0 +1,3 @@ +module.exports = { + plugins: ['prettier-plugin-tailwindcss'], +} \ No newline at end of file diff --git a/smartservice_frontend/public/images/brand/brand-01.svg b/smartservice_frontend/public/images/brand/brand-01.svg new file mode 100644 index 0000000..7321fbf --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-01.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/smartservice_frontend/public/images/brand/brand-02.svg b/smartservice_frontend/public/images/brand/brand-02.svg new file mode 100644 index 0000000..14da422 --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-02.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/smartservice_frontend/public/images/brand/brand-03.svg b/smartservice_frontend/public/images/brand/brand-03.svg new file mode 100644 index 0000000..8d29afa --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-03.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/smartservice_frontend/public/images/brand/brand-04.svg b/smartservice_frontend/public/images/brand/brand-04.svg new file mode 100644 index 0000000..837a4d4 --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-04.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/smartservice_frontend/public/images/brand/brand-05.svg b/smartservice_frontend/public/images/brand/brand-05.svg new file mode 100644 index 0000000..7044f46 --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-05.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/smartservice_frontend/public/images/brand/brand-06.svg b/smartservice_frontend/public/images/brand/brand-06.svg new file mode 100644 index 0000000..78c5d01 --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-06.svg @@ -0,0 +1,4 @@ + + + + diff --git a/smartservice_frontend/public/images/brand/brand-07.svg b/smartservice_frontend/public/images/brand/brand-07.svg new file mode 100644 index 0000000..5abb368 --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-07.svg @@ -0,0 +1,4 @@ + + + + diff --git a/smartservice_frontend/public/images/brand/brand-08.svg b/smartservice_frontend/public/images/brand/brand-08.svg new file mode 100644 index 0000000..71bc1e2 --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-08.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/smartservice_frontend/public/images/brand/brand-09.svg b/smartservice_frontend/public/images/brand/brand-09.svg new file mode 100644 index 0000000..1330ba2 --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-09.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/smartservice_frontend/public/images/brand/brand-10.svg b/smartservice_frontend/public/images/brand/brand-10.svg new file mode 100644 index 0000000..60308dd --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-10.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/smartservice_frontend/public/images/brand/brand-11.svg b/smartservice_frontend/public/images/brand/brand-11.svg new file mode 100644 index 0000000..b316bb4 --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-11.svg @@ -0,0 +1,4 @@ + + + + diff --git a/smartservice_frontend/public/images/brand/brand-12.svg b/smartservice_frontend/public/images/brand/brand-12.svg new file mode 100644 index 0000000..8396a56 --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-12.svg @@ -0,0 +1,4 @@ + + + + diff --git a/smartservice_frontend/public/images/brand/brand-13.svg b/smartservice_frontend/public/images/brand/brand-13.svg new file mode 100644 index 0000000..dd53f79 --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-13.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/smartservice_frontend/public/images/brand/brand-14.svg b/smartservice_frontend/public/images/brand/brand-14.svg new file mode 100644 index 0000000..381d72d --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-14.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/smartservice_frontend/public/images/brand/brand-15.svg b/smartservice_frontend/public/images/brand/brand-15.svg new file mode 100644 index 0000000..dfde3dd --- /dev/null +++ b/smartservice_frontend/public/images/brand/brand-15.svg @@ -0,0 +1,4 @@ + + + + diff --git a/smartservice_frontend/public/images/error/404-dark.svg b/smartservice_frontend/public/images/error/404-dark.svg new file mode 100644 index 0000000..4d14ec9 --- /dev/null +++ b/smartservice_frontend/public/images/error/404-dark.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/smartservice_frontend/public/images/error/404.svg b/smartservice_frontend/public/images/error/404.svg new file mode 100644 index 0000000..ff8b8a2 --- /dev/null +++ b/smartservice_frontend/public/images/error/404.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/smartservice_frontend/public/images/error/500-dark.svg b/smartservice_frontend/public/images/error/500-dark.svg new file mode 100644 index 0000000..c5ac764 --- /dev/null +++ b/smartservice_frontend/public/images/error/500-dark.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/smartservice_frontend/public/images/error/500.svg b/smartservice_frontend/public/images/error/500.svg new file mode 100644 index 0000000..82f5159 --- /dev/null +++ b/smartservice_frontend/public/images/error/500.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/smartservice_frontend/public/images/error/503-dark.svg b/smartservice_frontend/public/images/error/503-dark.svg new file mode 100644 index 0000000..8df2a94 --- /dev/null +++ b/smartservice_frontend/public/images/error/503-dark.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/smartservice_frontend/public/images/error/503.svg b/smartservice_frontend/public/images/error/503.svg new file mode 100644 index 0000000..a27a714 --- /dev/null +++ b/smartservice_frontend/public/images/error/503.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/smartservice_frontend/public/images/error/maintenance-dark.svg b/smartservice_frontend/public/images/error/maintenance-dark.svg new file mode 100644 index 0000000..e2a4499 --- /dev/null +++ b/smartservice_frontend/public/images/error/maintenance-dark.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/smartservice_frontend/public/images/error/maintenance.svg b/smartservice_frontend/public/images/error/maintenance.svg new file mode 100644 index 0000000..859d817 --- /dev/null +++ b/smartservice_frontend/public/images/error/maintenance.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/smartservice_frontend/public/images/error/success-dark.svg b/smartservice_frontend/public/images/error/success-dark.svg new file mode 100644 index 0000000..b57643f --- /dev/null +++ b/smartservice_frontend/public/images/error/success-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/smartservice_frontend/public/images/error/success.svg b/smartservice_frontend/public/images/error/success.svg new file mode 100644 index 0000000..91e1a76 --- /dev/null +++ b/smartservice_frontend/public/images/error/success.svg @@ -0,0 +1,3 @@ + + + diff --git a/smartservice_frontend/public/images/favicon.ico b/smartservice_frontend/public/images/favicon.ico new file mode 100644 index 0000000..379c72a Binary files /dev/null and b/smartservice_frontend/public/images/favicon.ico differ diff --git a/smartservice_frontend/public/images/icons/file-image-dark.svg b/smartservice_frontend/public/images/icons/file-image-dark.svg new file mode 100644 index 0000000..ff2d6df --- /dev/null +++ b/smartservice_frontend/public/images/icons/file-image-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/smartservice_frontend/public/images/icons/file-image.svg b/smartservice_frontend/public/images/icons/file-image.svg new file mode 100644 index 0000000..0303d63 --- /dev/null +++ b/smartservice_frontend/public/images/icons/file-image.svg @@ -0,0 +1,3 @@ + + + diff --git a/smartservice_frontend/public/images/icons/file-pdf-dark.svg b/smartservice_frontend/public/images/icons/file-pdf-dark.svg new file mode 100644 index 0000000..8fc5a47 --- /dev/null +++ b/smartservice_frontend/public/images/icons/file-pdf-dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/smartservice_frontend/public/images/icons/file-pdf.svg b/smartservice_frontend/public/images/icons/file-pdf.svg new file mode 100644 index 0000000..a525a26 --- /dev/null +++ b/smartservice_frontend/public/images/icons/file-pdf.svg @@ -0,0 +1,3 @@ + + + diff --git a/smartservice_frontend/public/images/icons/file-video-dark.svg b/smartservice_frontend/public/images/icons/file-video-dark.svg new file mode 100644 index 0000000..9415c3d --- /dev/null +++ b/smartservice_frontend/public/images/icons/file-video-dark.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/smartservice_frontend/public/images/icons/file-video.svg b/smartservice_frontend/public/images/icons/file-video.svg new file mode 100644 index 0000000..49732ca --- /dev/null +++ b/smartservice_frontend/public/images/icons/file-video.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/smartservice_frontend/public/images/logo/auth-logo.png b/smartservice_frontend/public/images/logo/auth-logo.png new file mode 100644 index 0000000..71cc709 Binary files /dev/null and b/smartservice_frontend/public/images/logo/auth-logo.png differ diff --git a/smartservice_frontend/public/images/logo/logo-dark.png b/smartservice_frontend/public/images/logo/logo-dark.png new file mode 100644 index 0000000..71cc709 Binary files /dev/null and b/smartservice_frontend/public/images/logo/logo-dark.png differ diff --git a/smartservice_frontend/public/images/logo/logo-icon.png b/smartservice_frontend/public/images/logo/logo-icon.png new file mode 100644 index 0000000..7d856a9 Binary files /dev/null and b/smartservice_frontend/public/images/logo/logo-icon.png differ diff --git a/smartservice_frontend/public/images/logo/logo.png b/smartservice_frontend/public/images/logo/logo.png new file mode 100644 index 0000000..73b20c9 Binary files /dev/null and b/smartservice_frontend/public/images/logo/logo.png differ diff --git a/smartservice_frontend/public/images/shape/grid-01.svg b/smartservice_frontend/public/images/shape/grid-01.svg new file mode 100644 index 0000000..6490367 --- /dev/null +++ b/smartservice_frontend/public/images/shape/grid-01.svg @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/smartservice_frontend/public/images/task/google-drive.svg b/smartservice_frontend/public/images/task/google-drive.svg new file mode 100644 index 0000000..2bdb033 --- /dev/null +++ b/smartservice_frontend/public/images/task/google-drive.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/smartservice_frontend/public/images/task/pdf.svg b/smartservice_frontend/public/images/task/pdf.svg new file mode 100644 index 0000000..4390c8d --- /dev/null +++ b/smartservice_frontend/public/images/task/pdf.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/smartservice_frontend/public/images/task/task.jpg b/smartservice_frontend/public/images/task/task.jpg new file mode 100644 index 0000000..5e6add1 Binary files /dev/null and b/smartservice_frontend/public/images/task/task.jpg differ diff --git a/smartservice_frontend/public/images/task/task.png b/smartservice_frontend/public/images/task/task.png new file mode 100644 index 0000000..0031cdb Binary files /dev/null and b/smartservice_frontend/public/images/task/task.png differ diff --git a/smartservice_frontend/public/images/user/owner.jpg b/smartservice_frontend/public/images/user/owner.jpg new file mode 100644 index 0000000..55985fe Binary files /dev/null and b/smartservice_frontend/public/images/user/owner.jpg differ diff --git a/smartservice_frontend/public/images/user/user-01.jpg b/smartservice_frontend/public/images/user/user-01.jpg new file mode 100644 index 0000000..4877840 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-01.jpg differ diff --git a/smartservice_frontend/public/images/user/user-02.jpg b/smartservice_frontend/public/images/user/user-02.jpg new file mode 100644 index 0000000..fe64d3e Binary files /dev/null and b/smartservice_frontend/public/images/user/user-02.jpg differ diff --git a/smartservice_frontend/public/images/user/user-03.jpg b/smartservice_frontend/public/images/user/user-03.jpg new file mode 100644 index 0000000..7a8647a Binary files /dev/null and b/smartservice_frontend/public/images/user/user-03.jpg differ diff --git a/smartservice_frontend/public/images/user/user-04.jpg b/smartservice_frontend/public/images/user/user-04.jpg new file mode 100644 index 0000000..0522414 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-04.jpg differ diff --git a/smartservice_frontend/public/images/user/user-05.jpg b/smartservice_frontend/public/images/user/user-05.jpg new file mode 100644 index 0000000..c0b7ddb Binary files /dev/null and b/smartservice_frontend/public/images/user/user-05.jpg differ diff --git a/smartservice_frontend/public/images/user/user-06.jpg b/smartservice_frontend/public/images/user/user-06.jpg new file mode 100644 index 0000000..d80d37e Binary files /dev/null and b/smartservice_frontend/public/images/user/user-06.jpg differ diff --git a/smartservice_frontend/public/images/user/user-07.jpg b/smartservice_frontend/public/images/user/user-07.jpg new file mode 100644 index 0000000..7e8f58d Binary files /dev/null and b/smartservice_frontend/public/images/user/user-07.jpg differ diff --git a/smartservice_frontend/public/images/user/user-08.jpg b/smartservice_frontend/public/images/user/user-08.jpg new file mode 100644 index 0000000..86d14ef Binary files /dev/null and b/smartservice_frontend/public/images/user/user-08.jpg differ diff --git a/smartservice_frontend/public/images/user/user-09.jpg b/smartservice_frontend/public/images/user/user-09.jpg new file mode 100644 index 0000000..35942ed Binary files /dev/null and b/smartservice_frontend/public/images/user/user-09.jpg differ diff --git a/smartservice_frontend/public/images/user/user-10.jpg b/smartservice_frontend/public/images/user/user-10.jpg new file mode 100644 index 0000000..e330208 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-10.jpg differ diff --git a/smartservice_frontend/public/images/user/user-11.jpg b/smartservice_frontend/public/images/user/user-11.jpg new file mode 100644 index 0000000..7aa2dd9 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-11.jpg differ diff --git a/smartservice_frontend/public/images/user/user-12.jpg b/smartservice_frontend/public/images/user/user-12.jpg new file mode 100644 index 0000000..2b9065c Binary files /dev/null and b/smartservice_frontend/public/images/user/user-12.jpg differ diff --git a/smartservice_frontend/public/images/user/user-13.jpg b/smartservice_frontend/public/images/user/user-13.jpg new file mode 100644 index 0000000..7657777 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-13.jpg differ diff --git a/smartservice_frontend/public/images/user/user-14.jpg b/smartservice_frontend/public/images/user/user-14.jpg new file mode 100644 index 0000000..28ef7a9 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-14.jpg differ diff --git a/smartservice_frontend/public/images/user/user-15.jpg b/smartservice_frontend/public/images/user/user-15.jpg new file mode 100644 index 0000000..e39fb30 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-15.jpg differ diff --git a/smartservice_frontend/public/images/user/user-16.jpg b/smartservice_frontend/public/images/user/user-16.jpg new file mode 100644 index 0000000..f23e96c Binary files /dev/null and b/smartservice_frontend/public/images/user/user-16.jpg differ diff --git a/smartservice_frontend/public/images/user/user-17.jpg b/smartservice_frontend/public/images/user/user-17.jpg new file mode 100644 index 0000000..4effac3 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-17.jpg differ diff --git a/smartservice_frontend/public/images/user/user-18.jpg b/smartservice_frontend/public/images/user/user-18.jpg new file mode 100644 index 0000000..4660835 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-18.jpg differ diff --git a/smartservice_frontend/public/images/user/user-19.jpg b/smartservice_frontend/public/images/user/user-19.jpg new file mode 100644 index 0000000..b8d2ae9 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-19.jpg differ diff --git a/smartservice_frontend/public/images/user/user-20.jpg b/smartservice_frontend/public/images/user/user-20.jpg new file mode 100644 index 0000000..6acae07 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-20.jpg differ diff --git a/smartservice_frontend/public/images/user/user-21.jpg b/smartservice_frontend/public/images/user/user-21.jpg new file mode 100644 index 0000000..d86084c Binary files /dev/null and b/smartservice_frontend/public/images/user/user-21.jpg differ diff --git a/smartservice_frontend/public/images/user/user-22.jpg b/smartservice_frontend/public/images/user/user-22.jpg new file mode 100644 index 0000000..9cf7e13 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-22.jpg differ diff --git a/smartservice_frontend/public/images/user/user-23.jpg b/smartservice_frontend/public/images/user/user-23.jpg new file mode 100644 index 0000000..b79ffec Binary files /dev/null and b/smartservice_frontend/public/images/user/user-23.jpg differ diff --git a/smartservice_frontend/public/images/user/user-24.jpg b/smartservice_frontend/public/images/user/user-24.jpg new file mode 100644 index 0000000..ee09128 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-24.jpg differ diff --git a/smartservice_frontend/public/images/user/user-25.jpg b/smartservice_frontend/public/images/user/user-25.jpg new file mode 100644 index 0000000..e930892 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-25.jpg differ diff --git a/smartservice_frontend/public/images/user/user-26.jpg b/smartservice_frontend/public/images/user/user-26.jpg new file mode 100644 index 0000000..c4934b4 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-26.jpg differ diff --git a/smartservice_frontend/public/images/user/user-27.jpg b/smartservice_frontend/public/images/user/user-27.jpg new file mode 100644 index 0000000..2a08ebe Binary files /dev/null and b/smartservice_frontend/public/images/user/user-27.jpg differ diff --git a/smartservice_frontend/public/images/user/user-28.jpg b/smartservice_frontend/public/images/user/user-28.jpg new file mode 100644 index 0000000..82cf2d1 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-28.jpg differ diff --git a/smartservice_frontend/public/images/user/user-29.jpg b/smartservice_frontend/public/images/user/user-29.jpg new file mode 100644 index 0000000..1a1fa49 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-29.jpg differ diff --git a/smartservice_frontend/public/images/user/user-30.jpg b/smartservice_frontend/public/images/user/user-30.jpg new file mode 100644 index 0000000..512e8dd Binary files /dev/null and b/smartservice_frontend/public/images/user/user-30.jpg differ diff --git a/smartservice_frontend/public/images/user/user-31.jpg b/smartservice_frontend/public/images/user/user-31.jpg new file mode 100644 index 0000000..0144b84 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-31.jpg differ diff --git a/smartservice_frontend/public/images/user/user-32.jpg b/smartservice_frontend/public/images/user/user-32.jpg new file mode 100644 index 0000000..712e336 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-32.jpg differ diff --git a/smartservice_frontend/public/images/user/user-33.jpg b/smartservice_frontend/public/images/user/user-33.jpg new file mode 100644 index 0000000..1f7796b Binary files /dev/null and b/smartservice_frontend/public/images/user/user-33.jpg differ diff --git a/smartservice_frontend/public/images/user/user-34.jpg b/smartservice_frontend/public/images/user/user-34.jpg new file mode 100644 index 0000000..40202f6 Binary files /dev/null and b/smartservice_frontend/public/images/user/user-34.jpg differ diff --git a/smartservice_frontend/public/images/user/user-35.jpg b/smartservice_frontend/public/images/user/user-35.jpg new file mode 100644 index 0000000..b78921a Binary files /dev/null and b/smartservice_frontend/public/images/user/user-35.jpg differ diff --git a/smartservice_frontend/public/images/user/user-36.jpg b/smartservice_frontend/public/images/user/user-36.jpg new file mode 100644 index 0000000..a023f2f Binary files /dev/null and b/smartservice_frontend/public/images/user/user-36.jpg differ diff --git a/smartservice_frontend/public/images/user/user-37.jpg b/smartservice_frontend/public/images/user/user-37.jpg new file mode 100644 index 0000000..6d3186e Binary files /dev/null and b/smartservice_frontend/public/images/user/user-37.jpg differ diff --git a/smartservice_frontend/server.js b/smartservice_frontend/server.js new file mode 100644 index 0000000..4d7809f --- /dev/null +++ b/smartservice_frontend/server.js @@ -0,0 +1,76 @@ +// for SG test + +const express = require("express"); +const { createProxyMiddleware } = require("http-proxy-middleware"); +const path = require("path"); +const morgan = require("morgan"); +const fs = require("fs"); + +const app = express(); +const port = 3000; + +app.use(morgan("dev")); // for log + + +const TARGET = "http://localhost:18080"; +app.use( + "/api", + createProxyMiddleware({ + target: TARGET, + changeOrigin: true, + pathRewrite: (path, req) => { + console.log("pathRewrite, path: ", path); + //console.log("pathRewrite, req.url: ", req.url); + //console.log("pathRewrite, req.headers: ", req.headers); + let convertedUrl = `/api${path}`; + console.log(`pathRewrite, convertedUrl: ${TARGET}${convertedUrl}`); + return convertedUrl; + }, + //fuck!!! + // + logLevel: "debug", + logProvider: () => console, + onError: (err, req, res) => { + console.error("onError, err: ", err); + }, + onProxyReq: (proxyReq, req, res) => { + console.log(">>> Sending request to target:"); + console.log("onProxyReq, req.originalUrl: ", req.originalUrl); + console.log("onProxyReq, proxyReq.getHeader('host'): ", proxyReq.getHeader("host")); + console.log("onProxyReq, proxyReq.path: ", proxyReq.path); + console.log("onProxyReq, target url: ", `${proxyReq.agent.protocol}//${proxyReq.getHeader("host")}${proxyReq.path}`); + }, + onProxyRes: (proxyRes, req, res) => { + console.log("<<< Response received from target:"); + console.log("onProxyRes, proxyRes.statusCode: ", proxyRes.statusCode); + }, + // + //fuck!!! + }) +); + +app.use( + express.static(path.join(__dirname, "out"), { + maxAge: 0, + etag: false, + lastModified: false, + redirect: false + }) +); + +app.use((req, res, next) => { + console.log("received request", req.method, req.url); + + const reqPath = req.path; + const htmlFilePath = path.join(__dirname, "out", reqPath + ".html"); + + if (fs.existsSync(htmlFilePath)) { + res.sendFile(htmlFilePath); + } else { + next(); + } +}); + +app.listen(port, () => { + console.log(`Static site with proxy running at http://localhost:${port}`); +}); diff --git a/smartservice_frontend/src/app/(admin)/account-group/page.tsx b/smartservice_frontend/src/app/(admin)/account-group/page.tsx new file mode 100644 index 0000000..8371acc --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/account-group/page.tsx @@ -0,0 +1,15 @@ +import { Metadata } from "next"; +import React from "react"; + + + +export const metadata: Metadata = { + title: "그룹관리", + description: "그룹관리", +}; + +export default function OrderPage() { + return ( +
+ ); +} diff --git a/smartservice_frontend/src/app/(admin)/account/Account.tsx b/smartservice_frontend/src/app/(admin)/account/Account.tsx new file mode 100644 index 0000000..31c5cd6 --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/account/Account.tsx @@ -0,0 +1,354 @@ +"use client" +import PageBreadcrumb from "@/components/common/PageBreadCrumb2"; +import ComponentCard from '@/components/common/ComponentCard2'; +import CtTable1 from '@/components/tables/CtTable1'; +import Button from '@/components/ui/button/Button2'; +import { DocsIcon, FileIcon, TableIcon, PlusIcon, TrashBinIcon, PencilIcon } from "@/icons"; +import WithLabel from '@/components/form/WithLabel'; +import Input from '@/components/form/input/InputField2'; +import DatePicker from '@/components/form/date-picker2'; +import Badge from "@/components/ui/badge/Badge"; + +import React, { Key } from "react"; +import { useEffect, useState } from 'react'; +import api, { convertDateTime2, convertDateTime3, postFileDownload, useAuthStore } from '@/lib/_AG'; + +import { useModal } from "@/hooks/useModal"; +import AddModifyAccountModal, { AccountModalProps } from './AddModifyAccountModal'; +import { useMultiState } from "@/hooks/useMultiState"; + +import CtTree, { CtTreeNode, expandAndSelectTreeNode, getAllNodeKeys, findParentKeys, findNodeByKey, addNodeByKey, deleteNodeByKey } from "@/components/CtTree"; +import { reqBizGroupTree2 } from "@/app/(admin)/biz-group/BizGroupContent"; + + +const SEARCH_LABEL_WIDTH = 24; +const COUNT_PER_PAGE = 10; +const PAGE_NUM_COUNT = 5; + + +export default function Account() { + const tokenPayload = useAuthStore((s) => s.tokenPayload); //Bruce, JWT + + const [ tableData, setTableData ] = useState([]); + const [ tableOffset, setTableOffset ] = useState(0); + const [ tableTotalCount, setTableTotalCount ] = useState(0); + + const [ treeData, setTreeData ] = useState([]); + const [ selectedTreeKeys, setSelectedTreeKeys ] = useState([]); + const [ expandedTreeKeys, setExpandedTreeKeys ] = useState([]); + + // group search fields + const [ name, setName ] = useState(""); + const [ biz_reg_num, setBizRegNum ] = useState(""); + + //search fields + const [ user_id, setUserId ] = useState(""); + const [ email, setEmail ] = useState(""); + const [ nick_name, setNickName ] = useState(""); + const [ date_start, setDateStart ] = useState(""); + const [ date_end, setDateEnd ] = useState(""); + + // modal + const { isOpen, openModal, closeModal } = useModal(); + const modalData = useMultiState({biz_group_name: "", isModify: false, gid: "", biz_group_id: "", user_id: "", user_pw: "", nick_name: "", email: "", state: "1"}); + + //function part + // + function reqAccountList(is_excel: boolean, biz_group_id: string) { + if (!biz_group_id) + return; + + const params = { + offset: tableOffset, + limit: COUNT_PER_PAGE, + user_id: user_id, + email: email, + nick_name: nick_name, + date_start: date_start, + date_end: date_end, + biz_group_id: biz_group_id, + } + + if (is_excel == true) { + postFileDownload('/api/get-account.do', params); + return; + } + + api.post('/api/get-account.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode === 0) { + if (resp.data.result.list.length == 0) { + alert("조회 결과가 없습니다."); + setTableTotalCount(0); + setTableData([]); + return; + } + setTableTotalCount(resp.data.result.totalCount); + setTableData(resp.data.result.list); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)); + } + + function reqRemoveAccount(gid: string) { + const params = { + ids: gid + } + + api.post('/api/remove-account.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + reqAccountList(false, selectedTreeKeys[0] as string); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + // + + + // event processing part + // + const handleClickGroupSearch = () => { + if (tokenPayload?.permission == 1) { + if (name == "" && biz_reg_num == "") { + alert("그룹명(사업자명) 또는 사업자등록번호를 입력하셔야 합니다."); + return; + } + if (name != "" && name.length < 3) { + alert("그룹명(사업자명)은 세글자 이상 입력해야 합니다."); + return; + } + if (biz_reg_num != "" && biz_reg_num.length < 3) { + alert("사업자등록번호는 세글자 이상 입력해야 합니다."); + return; + } + + //reqBizGroupTree3("", setTreeData, setSelectedTreeKeys, setExpandedTreeKeys); + reqBizGroupTree2(true, "", "", "", "", name, biz_reg_num, treeData, setTreeData); + } + }; + + const handleClickNode = (key: Key) => { + //console.log("handleClickNode, key = ", key); + setTableOffset(0); + reqAccountList(false, key as string); + } + + const handleClickTreeExpanded = (key: Key) => { + //console.log("handleClickTreeExpanded, key = ", key); + //const node = findNodeByKey(treeData, key); + //if (node.children == undefined) + // reqBizGroupTree2(false, key as string, "", "", "", "", "", treeData, setTreeData); + } + + const handleClickAdd = () => { + if (selectedTreeKeys.length <= 0) { + alert("생성할 계정의 사업자를 선택하세요."); + return; + } + + const node = findNodeByKey(treeData, selectedTreeKeys[0]); + modalData.setAll({biz_group_name: node.name, biz_reg_num: node.biz_reg_num, + isModify: false, gid: "", user_id: "", user_pw: "", nick_name: "", email: "", state: "1", biz_group_id: node.key}); + openModal(); + }; + + const handleClickDownload = () => { + reqAccountList(true, selectedTreeKeys[0] as string); + }; + + const handleClickSearch = () => { + if (selectedTreeKeys.length <= 0) { + alert("조회하려면 사업자를 선택해야 합니다."); + return; + } + + reqAccountList(false, selectedTreeKeys[0] as string); + }; + + const handlePageChange = (page: number) => { + setTableOffset((page - 1) * COUNT_PER_PAGE); + }; + + const handleRowClickModify = (row: number) => { + const node = findNodeByKey(treeData, selectedTreeKeys[0]); + modalData.setAll({...tableData[row], + biz_group_name: node.name, + biz_reg_num: node.biz_reg_num, + isModify: true}); + openModal(); + }; + + const handleRowClickDelete = (row: number) => { + if (confirm("'" + tableData[row].user_id + "' 계정을 삭제하시겠습니까?")) { + reqRemoveAccount(tableData[row].gid); + } + }; + + const handleModalOk = () => { + closeModal(); + reqAccountList(false, selectedTreeKeys[0] as string); + } + + //useEffect(() => { + //}, []); + + useEffect(() => { + //reqAccountList(false, selectedTreeKeys[0] as string); + }, [tableOffset]); + + const columns = [ + { + title: "등록일", + key: "reg_time" , + renderItem: (item:any) => convertDateTime3(item.reg_time), + }, + { + title: "그룹", + key: "biz_group_name", + }, + { + title: "아이디", + key: "user_id", + }, + { + title: "닉네임", + key: "nick_name", + }, + { + title: "이메일", + key: "email", + }, + { + title: "상태", + key: "state", + renderItem: (item : any) => ( + + {item.state === 1 ? "정상" : "정지"} + + ) + }, + { + title: "수정", + key: "_", + renderItem: (item: any, row: number) => ( +
+ {handleRowClickModify(row)}} /> +
+ ), + }, + { + title: "삭제", + key: "_", + renderItem: (item: any, row: number) => ( +
+ {handleRowClickDelete(row)}} /> +
+ ), + }, + ]; + + return ( +
+ + +
+
+ +
+ {/*
*/} +
+ + setName(e.target.value)} + onKeyDown={(e) => {if (e.key === "Enter") handleClickGroupSearch()}} /> + + + setBizRegNum(e.target.value)} + onKeyDown={(e) => {if (e.key === "Enter") handleClickGroupSearch()}} /> + +
+
+ +
+
+
+ + +
+ +
+
+
+ + }> + +
+
+ + setUserId(e.target.value)} /> + + + setEmail(e.target.value)} /> + + + setNickName(e.target.value)} /> + +
+
+ +
+ { setDateStart(currentDateString); }} + /> + { setDateEnd(currentDateString); }} + /> +
+
+
+ + +
+
+
+ + + +
+ +
+ +
+ + + +
+
+ ); +} diff --git a/smartservice_frontend/src/app/(admin)/account/AddModifyAccountModal.tsx b/smartservice_frontend/src/app/(admin)/account/AddModifyAccountModal.tsx new file mode 100644 index 0000000..0557a7e --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/account/AddModifyAccountModal.tsx @@ -0,0 +1,122 @@ +"use client"; +import React, { useState, useRef, useEffect } from "react"; +import CtModal from "@/components/CtModal"; +import Label from '@/components/form/Label2'; +import Input from '@/components/form/input/InputField2'; +import Select from '@/components/form/Select2'; +import { useMultiState } from "@/hooks/useMultiState"; +import api from '@/lib/_AG'; + + + +export interface AccountModalProps { + biz_group_name?: string; // internal use + biz_reg_num?: string; // internal use + isModify: boolean; // external set + gid: string; // external set + // + biz_group_id: string; + user_id: string; + user_pw: string; + nick_name: string; + email: string; + state: string; +} + + +interface AddModifyAccountModalProps { + multiState: ReturnType>; + onOk: () => void; + isOpen: boolean; + closeModal: () => void; +} + +export default function AddModifyAccountModal({ multiState, onOk, isOpen, closeModal }: AddModifyAccountModalProps) { + + const handleClickAddOrModify = () => { + if (multiState.values.user_id == "") { + alert("계정 아이디를 입력하셔야 합니다."); + return; + } + else if (multiState.values.user_pw == "") { + alert("계정 비밀번호를 입력하셔야 합니다."); + return; + } + + if (multiState.values.isModify) { + api.post('/api/modify-account.do', multiState.values).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("수정되었습니다."); + onOk(); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + else { + api.post('/api/add-account.do', multiState.values).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("추가되었습니다."); + onOk(); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + } + + + return ( + //
+ +
+ + +
+
+ + multiState.set("user_id", e.target.value)} disabled={multiState.values.isModify ? true : false} /> +
+
+ + multiState.set("user_pw", e.target.value)} /> +
+
+ + multiState.set("nick_name", e.target.value)} /> +
+
+ + multiState.set("email", e.target.value)} /> +
+
+ + multiState.set("name", e.target.value)} /> +
+
+ + multiState.set("biz_reg_num", e.target.value)} /> +
+
+ + multiState.set("phone", e.target.value)} /> +
+
+ + multiState.set("email", e.target.value)} /> +
+
+ + multiState.set("ceo", e.target.value)} /> +
+
+ + multiState.set("address", e.target.value)} /> +
+
+ //
+ ); +}; diff --git a/smartservice_frontend/src/app/(admin)/biz-group-old/BizGroup.tsx b/smartservice_frontend/src/app/(admin)/biz-group-old/BizGroup.tsx new file mode 100644 index 0000000..c71e1d5 --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/biz-group-old/BizGroup.tsx @@ -0,0 +1,330 @@ +"use client" +import PageBreadcrumb from "@/components/common/PageBreadCrumb2"; +import ComponentCard from '@/components/common/ComponentCard2'; +import CtTable1 from '@/components/tables/CtTable1'; +import Button from '@/components/ui/button/Button2'; +import { DocsIcon, FileIcon, PlusIcon, TableIcon, TrashBinIcon, PencilIcon } from "@/icons"; +import WithLabel from '@/components/form/WithLabel'; +import Input from '@/components/form/input/InputField2'; +import DatePicker from '@/components/form/date-picker2'; + +import React, { Key } from "react"; +import { useEffect, useState } from 'react'; +import api, { convertDateTime3 } from '@/lib/_AG'; + +import { useModal } from "@/hooks/useModal"; +import AddModifyBizGroupModal, { BizGroupModalProps } from './AddModifyBizGroupModal'; +import { useMultiState } from "@/hooks/useMultiState"; + +import CtTree, { CtTreeNode, expandAndSelectTreeNode, getAllNodeKeys, findParentKeys, findNodeByKey, deleteNodeByKey } from "@/components/CtTree"; + + +const SEARCH_LABEL_WIDTH = 24; +const COUNT_PER_PAGE = 10; +const PAGE_NUM_COUNT = 5; + + +export default function BizGroup() { + const [ tableData, setTableData ] = useState([]); + const [ tableOffset, setTableOffset ] = useState(0); + const [ tableTotalCount, setTableTotalCount ] = useState(0); + + const [ treeData, setTreeData ] = useState([]); + const [ selectedTreeKeys, setSelectedTreeKeys ] = useState([]); + const [ expandedTreeKeys, setExpandedTreeKeys ] = useState([]); + + // search fields + const [ name, setName ] = useState(""); + const [ biz_reg_num, setBizRegNum ] = useState(""); + const [ email, setEmail ] = useState(""); + const [ phone, setPhone ] = useState(""); + const [ address, setAddress ] = useState(""); + const [ date_start, setDateStart ] = useState(""); + const [ date_end, setDateEnd ] = useState(""); + // + + // modal + const { isOpen, openModal, closeModal } = useModal(); + const modalData = useMultiState( {isModify: false, pid: "", name: "", biz_reg_num: "", phone: "", email: "", ceo: "", address: "" }); + + + // function part + function reqBizGroupList() { + const params = { + offset: tableOffset, + limit: COUNT_PER_PAGE, + name: name, + biz_reg_num: biz_reg_num, + email: email, + phone: phone, + address: address, + date_start: date_start, + date_end: date_end, + } + + api.post('/api/get-biz-group.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + if (resp.data.result.list.length == 0) { + alert("조회 결과가 없습니다."); + setTableTotalCount(0); + setTableData([]); + setTreeData([]); + return; + } + + setTableTotalCount(resp.data.result.totalCount); + setTableData(resp.data.result.list); + + setTreeData(resp.data.result.tree); + + const keys = getAllNodeKeys(resp.data.result.tree); + setExpandedTreeKeys(keys); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + + function reqRemoveBizGroup(biz_group_id: Key) { + const params = { + ids: biz_group_id + } + + api.post('/api/remove-biz-group.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + reqBizGroupList(); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + // + + // event processing part + // + const handleClickDownload = () => { + //... + }; + + const handleClickSearch = () => { + reqBizGroupList(); + }; + + const handleClickTableRow = (row: number) => { + expandAndSelectTreeNode(treeData, "" + tableData[row].biz_group_id, setSelectedTreeKeys, expandedTreeKeys, setExpandedTreeKeys); + }; + + const handleClickTreeExpanded = (key: Key) => { + //console.log("onClickExpanded, key = ", key); + } + + const handleClickAdd = () => { + if (selectedTreeKeys.length > 0) { + modalData.setAll({ + isModify: false, + pid: selectedTreeKeys[0] as string, + name: "", + biz_reg_num: "", + phone: "", + email: "", + ceo: "", + address: "", + }); + } + else { + modalData.reset(); + } + openModal(); + }; + + const handleRowClickModify = (row: number) => { + expandAndSelectTreeNode(treeData, "" + tableData[row].biz_group_id, setSelectedTreeKeys, expandedTreeKeys, setExpandedTreeKeys); + + modalData.setAll({...tableData[row], isModify: true}); + openModal(); + }; + + const handleRowClickDelete = (row: number) => { + if (confirm("'" + tableData[row].name + "' 사업자를 삭제하시겠습니까?")) { + reqRemoveBizGroup(tableData[row].biz_group_id); + } + }; + + const handleClickDelete = () => { + if (selectedTreeKeys.length <= 0) + return; + + const node = findNodeByKey(treeData, selectedTreeKeys[0]); + if (confirm("'" + node.title + "' 사업자를 삭제하시겠습니까?")) { + //const newTreeData = deleteNodeByKey(treeData, selectedTreeKeys[0]); + //setTreeData(newTreeData); + reqRemoveBizGroup(selectedTreeKeys[0]); + } + }; + + const handlePageChange = (page: number) => { + setTableOffset((page - 1) * COUNT_PER_PAGE); + }; + + const handleModalOk = () => { + closeModal(); + reqBizGroupList(); + }; + // + + useEffect(() => { + reqBizGroupList(); + }, []); + + useEffect(() => { + reqBizGroupList(); + }, [tableOffset]); + + // UI part + const columns = [ + { + title: "등록일", + key: "reg_time", + renderItem: (item: any, row: number) => convertDateTime3(item.reg_time) + }, + { + title: "그룹명(사업자명)", + key: "name", + }, + { + title: "사업자번호", + key: "biz_reg_num", + }, + { + title: "이메일", + key: "email", + }, + { + title: "전화번호", + key: "phone", + }, + { + title: "주소", + key: "address", + }, + { + title: "등록자", + key: "reg_id", + renderItem: (item: any, row: number) => ( +
+ 한동관리자 +
+ ), + }, + { + title: "수정", + key: "_", + renderItem: (item: any, row: number) => ( +
+ {handleRowClickModify(row)}} /> +
+ ), + }, + { + title: "삭제", + key: "_", + renderItem: (item: any, row: number) => ( +
+ {handleRowClickDelete(row)}} /> +
+ ), + }, + ]; + + return ( +
+ + +
+ }> + +
+
+ + setName(e.target.value)} /> + + + setBizRegNum(e.target.value)} /> + + + setEmail(e.target.value)} /> + +
+
+ + setPhone(e.target.value)} /> + + + setAddress(e.target.value)} /> + +
+
+ +
+ { setDateStart(currentDateString); }} + /> + { setDateEnd(currentDateString); }} + /> +
+
+
+ + +
+
+
+ +
+ +
+ +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ ); +} diff --git a/smartservice_frontend/src/app/(admin)/biz-group-old/page.tsx b/smartservice_frontend/src/app/(admin)/biz-group-old/page.tsx new file mode 100644 index 0000000..740805d --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/biz-group-old/page.tsx @@ -0,0 +1,16 @@ +import BizGroup from './BizGroup'; +import PageBreadcrumb from "@/components/common/PageBreadCrumb2"; +import { Metadata } from "next"; +import React from "react"; + + +export const metadata: Metadata = { + title: "사업자원장 관리", + description: "사업자원장 관리", +}; + +export default function GroupPage() { + return ( + + ); +} diff --git a/smartservice_frontend/src/app/(admin)/biz-group/AddModifyBizGroupModal.tsx b/smartservice_frontend/src/app/(admin)/biz-group/AddModifyBizGroupModal.tsx new file mode 100644 index 0000000..17b5280 --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/biz-group/AddModifyBizGroupModal.tsx @@ -0,0 +1,125 @@ +"use client"; +import React, { useState } from "react"; +import Label from '@/components/form/Label2'; +import Input from '@/components/form/input/InputField2'; +import CtModal from "@/components/CtModal"; +import { useMultiState } from "@/hooks/useMultiState"; +import api, { formatBusinessNumber } from '@/lib/_AG'; + + +export interface BizGroupModalProps { + isModify: boolean; // external set + pid: string; // external set + // + name: string; + biz_reg_num: string; + phone: string; + email: string; + ceo: string; + address: string; +} + +interface AddModifyBizGroupModalProps { + multiState: ReturnType>; + onOk: (insertedId: number) => void; + isOpen: boolean; + closeModal: () => void; +} + +export default function AddModifyBizGroupModal({ multiState, onOk, isOpen, closeModal }: AddModifyBizGroupModalProps) { + + const handleClickAddOrModify = () => { + if (multiState.values.name == "") { + alert("그룹명(사업자명)을 입력하셔야 합니다."); + return; + } + //else if (multiState.values.biz_reg_num == "") { + // alert("사업자등록번호를 입력하셔야 합니다."); + // return; + //} + + if (multiState.values.isModify) { + api.post('/api/modify-biz-group.do', multiState.values).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("수정되었습니다."); + onOk(-1); + } + else if (resp.data.errCode == -11) { + alert("이미 존재하는 사업자번호입니다."); + } + else if (resp.data.errCode == -17) { + alert("잘못된 형식의 사업자번호입니다."); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + else { + api.post('/api/add-biz-group.do', multiState.values).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("추가되었습니다."); + onOk(resp.data.result.biz_group_id); + } + else if (resp.data.errCode == -11) { + alert("이미 존재하는 사업자번호입니다."); + } + else if (resp.data.errCode == -17) { + alert("잘못된 형식의 사업자번호입니다."); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + } + + const handleChangeBizRegNum = (value: string) => { + multiState.set("biz_reg_num", formatBusinessNumber(value)); + } + + return ( + //
+ +
+ + multiState.set("name", e.target.value)} /> +
+
+ + handleChangeBizRegNum(e.target.value)} /> +
+
+ + multiState.set("phone", e.target.value)} /> +
+
+ + multiState.set("email", e.target.value)} /> +
+
+ + multiState.set("ceo", e.target.value)} /> +
+
+ + multiState.set("address", e.target.value)} /> +
+
+ //
+ ); +}; diff --git a/smartservice_frontend/src/app/(admin)/biz-group/BizGroup.tsx b/smartservice_frontend/src/app/(admin)/biz-group/BizGroup.tsx new file mode 100644 index 0000000..9ac41db --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/biz-group/BizGroup.tsx @@ -0,0 +1,15 @@ +"use client" +import PageBreadcrumb from "@/components/common/PageBreadCrumb2"; +import React from "react"; +import { DocsIcon, FileIcon, PlusIcon, TrashBinIcon, TableIcon, PencilIcon } from "@/icons"; +import BizGroupContent from "./BizGroupContent"; + +export default function BizGroup() { + return ( +
+ + + } /> +
+ ); +} diff --git a/smartservice_frontend/src/app/(admin)/biz-group/BizGroupContent.tsx b/smartservice_frontend/src/app/(admin)/biz-group/BizGroupContent.tsx new file mode 100644 index 0000000..9f5f83f --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/biz-group/BizGroupContent.tsx @@ -0,0 +1,437 @@ +"use client" +import PageBreadcrumb from "@/components/common/PageBreadCrumb2"; +import ComponentCard from '@/components/common/ComponentCard2'; +import Button from '@/components/ui/button/Button2'; +import { DocsIcon, FileIcon, PlusIcon, TrashBinIcon, TableIcon, PencilIcon } from "@/icons"; +import Label from '@/components/form/Label'; +import WithLabel from '@/components/form/WithLabel'; +import Input from '@/components/form/input/InputField2'; +import DatePicker from '@/components/form/date-picker2'; +import React, { Key } from "react"; +import { useEffect, useState } from 'react'; +import api, { convertDateTime3, formatBusinessNumber, useAuthStore } from '@/lib/_AG'; + +import { useModal } from "@/hooks/useModal"; +import AddModifyBizGroupModal, { BizGroupModalProps } from './AddModifyBizGroupModal'; +import { useMultiState } from "@/hooks/useMultiState"; + +import CtTree, { CtTreeNode, expandAndSelectTreeNode, getAllNodeKeys, findParentKeys, findNodeByKey, addNodeByKey, changeNodeByKey, deleteNodeByKey } from "@/components/CtTree"; +import { tree } from "next/dist/build/templates/app-page"; +import { useRouter } from "next/router"; + +const SEARCH_LABEL_WIDTH = 24; + + +// api component +// +export function reqBizGroupTree2( + isRoot: boolean, + pid: string, + top_group_id: string, + date_start: string, + date_end: string, + name: string, + biz_reg_num: string, + treeData: CtTreeNode[], + setTreeData: React.Dispatch>, + onResponse?: (resp: any) => void +) { + const params: any = { + isRoot: isRoot, + pid: pid, + top_group_id: top_group_id, + date_start: date_start, + date_end: date_end, + } + + if (isRoot == true) { + params.name = name; + params.biz_reg_num = biz_reg_num; + } + + api.post('/api/get-biz-group2.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + if (resp.data.result.tree.length == 0) { + if (isRoot == true) { + alert("조회 결과가 없습니다."); + setTreeData([]); + } + return; + } + + if (pid == "") { + setTreeData(resp.data.result.tree); + } + else { + setTreeData(treeData => addNodeByKey(treeData, pid, resp.data.result.tree)); + } + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + + onResponse?.(resp); + }) + .catch((err) => console.error(err)) +} + +export async function reqBizGroupTree3( + biz_group_id: string, + setTreeData: React.Dispatch>, + setSelectedTreeKeys: React.Dispatch>, + setExpandedTreeKeys: React.Dispatch>, + onSuccess?: (resp: any) => void +) { + try { + const params = { biz_group_id }; + + const resp = await api.post('/api/get-biz-group3.do', params); + //console.log(resp); + + if (resp.data.errCode === 0) { + if (resp.data.result.tree.length === 0) { + setTreeData([]); + return; + } + + setTreeData(resp.data.result.tree); + setSelectedTreeKeys([resp.data.result.tree[0].key]); + + const keys = getAllNodeKeys(resp.data.result.tree); + setExpandedTreeKeys(keys); + } else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + + if (onSuccess) onSuccess(resp); + } catch (err) { + console.error(err); + } +} +// + + +interface BizGroupContentProps { + title?: string; + titleIcon?: React.ReactNode; + preloadTreeData?: CtTreeNode[]; +} + +export default function BizGroupContent({ + title, + titleIcon, + preloadTreeData +}: BizGroupContentProps) { + const tokenPayload = useAuthStore((s) => s.tokenPayload); //Bruce, JWT + + const {isOpen, openModal, closeModal} = useModal(); + + // tree part + const [treeData, setTreeData] = useState(preloadTreeData ? preloadTreeData : []); + const [selectedTreeKeys, setSelectedTreeKeys] = useState(preloadTreeData ? [preloadTreeData[0].key as string] : []); + const [expandedTreeKeys, setExpandedTreeKeys] = useState(preloadTreeData ? getAllNodeKeys(preloadTreeData) : []); + + // search fields + const [name, setName] = useState(""); + const [biz_reg_num, setBizRegNum] = useState(""); + const [date_start, setDateStart] = useState(""); + const [date_end, setDateEnd] = useState(""); + // + + // form fields + const [formInfo, setFormInfo] = useState({name: "", biz_reg_num: "", email: "", phone: "", ceo: "", address: ""}); + const handleChangeFormInfo = (field: string, value?: string | number) => { setFormInfo(prev => ({ ...prev, [field]: value ?? "" })); }; + + // modal values + const modalData = useMultiState({isModify: false, pid: "", name: "", biz_reg_num: "", phone: "", email: "", ceo: "", address: "" }); + + + + // function part + // + function reqRemoveBizGroup(biz_group_id: Key) { + const params = { + ids: biz_group_id + } + + api.post('/api/remove-biz-group.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + setTreeData(treeData => deleteNodeByKey(treeData, biz_group_id)); + + setSelectedTreeKeys([]); + setFormInfo({name: "", biz_reg_num: "", email: "", phone: "", ceo: "", address: ""}); + alert("삭제되었습니다."); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + + function reqModifyBizGroup(biz_group_id: Key) { + if (formInfo.name == "") { + alert("그룹명(사업자명)을 입력하셔야 합니다."); + return; + } + //else if (formInfo.biz_reg_num == "") { + // alert("사업자등록번호를 입력하셔야 합니다."); + // return; + //} + + const params = { + biz_group_id: biz_group_id, + name: formInfo.name, + biz_reg_num: formInfo.biz_reg_num, + email: formInfo.email, + phone: formInfo.phone, + ceo: formInfo.ceo, + address: formInfo.address, + } + + api.post('/api/modify-biz-group.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + const node = findNodeByKey(treeData, biz_group_id); + node.key = biz_group_id; + //... node.title = formInfo.name + "(" + formInfo.biz_reg_num + ")"; + node.title = formInfo.name; + node.name = formInfo.name; + node.biz_reg_num = formInfo.biz_reg_num; + node.email = formInfo.email; + node.phone = formInfo.phone; + node.ceo = formInfo.ceo; + node.address = formInfo.address; + + setTreeData(treeData => changeNodeByKey(treeData, biz_group_id, node)); + + alert("수정되었습니다."); + } + else if (resp.data.errCode == -11) { + alert("이미 존재하는 사업자번호입니다."); + } + else if (resp.data.errCode == -17) { + alert("잘못된 형식의 사업자번호입니다."); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + // + + // event processing part + // + const handleChangeBizRegNum = (value: string) => { + setBizRegNum(formatBusinessNumber(value)); + } + + const handleClickSearch = () => { + if (tokenPayload?.permission == 1) { + if (name == "" && biz_reg_num == "") { + alert("그룹명(사업자명) 또는 사업자등록번호를 입력하셔야 합니다."); + return; + } + if (name != "" && name.length < 3) { + alert("그룹명(사업자명)은 세글자 이상 입력해야 합니다."); + return; + } + if (biz_reg_num != "" && biz_reg_num.length < 3) { + alert("사업자등록번호는 세글자 이상 입력해야 합니다."); + return; + } + + setSelectedTreeKeys(preloadTreeData ? [preloadTreeData[0].key as string] : []); + setExpandedTreeKeys(preloadTreeData ? getAllNodeKeys(preloadTreeData) : []); + reqBizGroupTree2(true, "", "", "", "", name, biz_reg_num, treeData, setTreeData); + } + else { + + } + }; + + const handleClickTreeExpanded = (key: Key) => { + const node = findNodeByKey(treeData, key); + if (node.children == undefined) + reqBizGroupTree2(false, key as string, "", "", "", "", "", treeData, setTreeData); + } + + const handleClickNode = (key: Key) => { + console.log("handleClickNode, ", key); + const node = findNodeByKey(treeData, key); + setFormInfo({name: node.name, biz_reg_num: node.biz_reg_num, email: node?.email ?? "", phone: node?.phone ?? "", ceo: node?.ceo ?? "", address: node?.address ?? ""}); + } + + const handleClickAdd = () => { + modalData.reset(); + + if (selectedTreeKeys.length > 0) { + modalData.set("pid", String(selectedTreeKeys[0])); + } + + openModal(); + }; + + const handleClickModify = () => { + if (selectedTreeKeys.length <= 0) + return; + + const node = findNodeByKey(treeData, selectedTreeKeys[0]); + if (confirm("수정 하시겠습니까?")) { + reqModifyBizGroup(selectedTreeKeys[0]); + } + }; + + const handleClickDelete = () => { + if (selectedTreeKeys.length <= 0) + return; + + const node = findNodeByKey(treeData, selectedTreeKeys[0]); + if (confirm("'" + node.title + "' 사업자를 삭제하시겠습니까?")) { + //const newTreeData = deleteNodeByKey(treeData, selectedTreeKeys[0]); + //setTreeData(newTreeData); + reqRemoveBizGroup(selectedTreeKeys[0]); + } + }; + + const handleModalOk = (insertedId: number) => { + closeModal(); + + const newNode = { + isModify: false, + key: String(insertedId), + //... title: modalData.values.name + "(" + modalData.values.biz_reg_num + ")", + title: modalData.values.name, + pid: modalData.values.pid, + name: modalData.values.name, + biz_reg_num: modalData.values.biz_reg_num, + phone: modalData.values.phone, + email: modalData.values.email, + ceo: modalData.values.ceo, + address: modalData.values.address, + isLeaf: true, + }; + setTreeData(treeData => addNodeByKey(treeData, newNode.pid, newNode)); + expandAndSelectTreeNode(treeData, selectedTreeKeys[0], setSelectedTreeKeys, expandedTreeKeys, setExpandedTreeKeys); + setExpandedTreeKeys((prev) => Array.from(new Set([...prev, ...selectedTreeKeys]))); + + setFormInfo({name: newNode.name, biz_reg_num: newNode.biz_reg_num, email: newNode.email, phone: newNode.phone, ceo: newNode.ceo, address: newNode.address}); + }; + + const handleChangeFormBizRegNum = (value: string) => { + handleChangeFormInfo("biz_reg_num", formatBusinessNumber(value)); + } + + + useEffect(() => { + //reqBizGroupTree2(true, ''); + }, []); + + + return ( +
+ +
+
+ + setName(e.target.value)} + onKeyDown={(e) => {if (e.key === "Enter") handleClickSearch()}} /> + + + handleChangeBizRegNum(e.target.value)} + onKeyDown={(e) => {if (e.key === "Enter") handleClickSearch()}} /> + +
+ +
+
+ {/* +
+ +
+ { setDateStart(currentDateString); }} + /> + { setDateEnd(currentDateString); }} + /> +
+
+
+ +
+
+ */} +
+ +
+ +
+ +
+
+

+ + 사업자를 선택하고 [신규추가] 버튼을 클릭하면 하위에 추가됩니다.
+ + 계층구조를 변경하려면 원하는 사업자에 마우스로 끌어다 놓으면 됩니다. +

+ + +
+
+
+
+
+ + handleChangeFormInfo("name", e.target.value)} /> +
+
+ + handleChangeFormBizRegNum(e.target.value)} /> +
+
+ + handleChangeFormInfo("email", e.target.value)} /> +
+
+ + handleChangeFormInfo("phone", e.target.value)} /> +
+
+ + handleChangeFormInfo("ceo", e.target.value)} /> +
+
+ + handleChangeFormInfo("address", e.target.value)} /> +
+ +
+
+
+
+ + + +
+ ); +} diff --git a/smartservice_frontend/src/app/(admin)/biz-group/ManageBizGroupModal.tsx b/smartservice_frontend/src/app/(admin)/biz-group/ManageBizGroupModal.tsx new file mode 100644 index 0000000..06cbb46 --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/biz-group/ManageBizGroupModal.tsx @@ -0,0 +1,27 @@ +"use client"; +import React, { useState } from "react"; +import CtModal from "@/components/CtModal"; +import BizGroupContent from './BizGroupContent'; +import { CtTreeNode } from "@/components/CtTree"; + +interface ManageBizGroupModalProps { + treeData: CtTreeNode[]; + isOpen: boolean; + closeModal: () => void; +} + +export default function ManageBizGroupModal({ treeData, isOpen, closeModal }: ManageBizGroupModalProps) { + return ( + //
+ + + + //
+ ); +}; diff --git a/smartservice_frontend/src/app/(admin)/biz-group/page.tsx b/smartservice_frontend/src/app/(admin)/biz-group/page.tsx new file mode 100644 index 0000000..380953f --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/biz-group/page.tsx @@ -0,0 +1,15 @@ +import BizGroup from './BizGroup'; +import { Metadata } from "next"; +import React from "react"; + + +export const metadata: Metadata = { + title: "사업자원장 관리", + description: "사업자원장 관리", +}; + +export default function GroupPage() { + return ( + + ); +} diff --git a/smartservice_frontend/src/app/(admin)/customer-account/AddModifyCustomerAccountModal.tsx b/smartservice_frontend/src/app/(admin)/customer-account/AddModifyCustomerAccountModal.tsx new file mode 100644 index 0000000..2fbdc70 --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/customer-account/AddModifyCustomerAccountModal.tsx @@ -0,0 +1,125 @@ +"use client"; +import React, { useState, useRef, useEffect } from "react"; +import CtModal from "@/components/CtModal"; +import Label from '@/components/form/Label2'; +import Input from '@/components/form/input/InputField2'; +import Select from '@/components/form/Select2'; +import { useMultiState } from "@/hooks/useMultiState"; +import api from '@/lib/_AG'; + + + +export interface CustomerAccountModalProps { + biz_group_name?: string; // internal use + biz_reg_num?: string; // internal use + isModify: boolean; // external set + gid: string; // external set + // + biz_group_id: string; + new_biz_group_id: string; + user_id: string; + user_pw: string; + nick_name: string; + email: string; + state: string; +} + + +interface AddModifyCustomerAccountModalProps { + multiState: ReturnType>; + onOk: () => void; + isOpen: boolean; + closeModal: () => void; +} + +export default function AddModifyCustomerAccountModal({ multiState, onOk, isOpen, closeModal }: AddModifyCustomerAccountModalProps) { + + const handleClickAddOrModify = () => { + if (multiState.values.user_id == "") { + alert("계정 아이디를 입력하셔야 합니다."); + return; + } + else if (multiState.values.user_pw == "") { + alert("계정 비밀번호를 입력하셔야 합니다."); + return; + } + + const { biz_group_name, biz_reg_num, ...params } = multiState.values; + + if (multiState.values.isModify) { + api.post('/api/modify-account.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("수정되었습니다."); + onOk(); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + else { + api.post('/api/add-account.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("추가되었습니다."); + onOk(); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + } + + + return ( + //
+ +
+ + +
+
+ + multiState.set("user_id", e.target.value)} disabled={multiState.values.isModify ? true : false} /> +
+
+ + multiState.set("user_pw", e.target.value)} /> +
+
+ + multiState.set("nick_name", e.target.value)} /> +
+
+ + multiState.set("email", e.target.value)} /> +
+
+ + setUserId(e.target.value)} /> + + + setEmail(e.target.value)} /> + + + setNickName(e.target.value)} /> + +
+
+ +
+ { setDateStart(currentDateString); }} + /> + { setDateEnd(currentDateString); }} + /> +
+
+
+ handleClickGroupAccess(value)} /> + + 그룹단위로 조회 + +
+
+ + +
+
+
+ + + +
+ +
+ + + + + + + + + + ); +} diff --git a/smartservice_frontend/src/app/(admin)/customer-account/page.tsx b/smartservice_frontend/src/app/(admin)/customer-account/page.tsx new file mode 100644 index 0000000..ace11fb --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/customer-account/page.tsx @@ -0,0 +1,15 @@ +import CustomerAccount from './CustomerAccount'; +import { Metadata } from "next"; +import React from "react"; + + +export const metadata: Metadata = { + title: "계정관리", + description: "계정관리", +}; + +export default function AccountPage() { + return ( + + ); +} diff --git a/smartservice_frontend/src/app/(admin)/device/AddModifyDeviceModal.tsx b/smartservice_frontend/src/app/(admin)/device/AddModifyDeviceModal.tsx new file mode 100644 index 0000000..33b4fe9 --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/device/AddModifyDeviceModal.tsx @@ -0,0 +1,200 @@ +"use client"; +import React, { useEffect, useState } from "react"; +import Label from '@/components/form/Label2'; +import Input from '@/components/form/input/InputField2'; +import Select from '@/components/form/Select2'; +import CtModal from "@/components/CtModal"; +import { useMultiState } from "@/hooks/useMultiState"; +import api from '@/lib/_AG'; +import Button from "@/components/ui/button/Button2"; + + +export interface DeviceModalProps { + biz_group_name?: string; // internal use + biz_reg_num?: string; // internal use + optTid: { label: string; value: string; }[]; + optBizGroup: { label: string; value: string; }[]; + tid: string; + // + isModify: boolean; + // + device_id: string; + biz_group_id: string; + new_biz_group_id: string; + name: string; + terminal_id: string; + manager_name: string; +} + +interface AddModifyDeviceModalProps { + multiState: ReturnType>; + onOk: () => void; + isOpen: boolean; + closeModal: () => void; +} + +export default function AddModifyDeviceModal({ multiState, onOk, isOpen, closeModal }: AddModifyDeviceModalProps) { + + const handleReboot = () => { + if (confirm("정말로 단말기를 리부팅 하시겠습니까?") == false) + return; + + const params = "tid=" + multiState.values.tid; + + const res = fetch("/tapi/reboot.do", { + method: 'POST', + headers: { + 'Content-Type': 'text/plain; charset=UTF-8', + }, + body: params, + }); + } + + const handleResetTime = () => { + const params = { + device_id: multiState.values.device_id + } + + api.post('/api/config-device.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("초기화 완료."); + onOk(); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + + const handleTest1 = () => { + const params = "tid=" + multiState.values.tid; + + const res = fetch("/tapi/test1.do", { + method: 'POST', + headers: { + 'Content-Type': 'text/plain; charset=UTF-8', + }, + body: params + "&type=1", + }); + } + const handleTest2 = () => { + const params = "tid=" + multiState.values.tid; + + const res = fetch("/tapi/test1.do", { + method: 'POST', + headers: { + 'Content-Type': 'text/plain; charset=UTF-8', + }, + body: params + "&type=2", + }); + } + const handleTest3 = () => { + const params = "tid=" + multiState.values.tid; + + const res = fetch("/tapi/test1.do", { + method: 'POST', + headers: { + 'Content-Type': 'text/plain; charset=UTF-8', + }, + body: params + "&type=3", + }); + } + + const handleClickAddOrModify = () => { + //if (multiState.values.name == "") { + // alert("기기 명칭을 입력하셔야 합니다."); + // return; + //} + + const { biz_group_name, biz_reg_num, optTid, optBizGroup, ...params } = multiState.values; + + if (multiState.values.isModify) { + api.post('/api/modify-device.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("수정되었습니다."); + onOk(); + } + else if (resp.data.errCode == -11) { + alert("기기명이나 TID는 중복될 수 없습니다."); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + else { + api.post('/api/add-device.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("추가되었습니다."); + onOk(); + } + else if (resp.data.errCode == -11) { + alert("이미 추가된 장치 입니다."); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + } + + return ( + //
+ +
+ + {/**/} + multiState.set("name", e.target.value)} /> +
+
+ + multiState.set("manager_name", e.target.value)} /> +
+
+ + + {/** + + + + */} +
+
+ //
+ ); +}; diff --git a/smartservice_frontend/src/app/(admin)/device/Device.tsx b/smartservice_frontend/src/app/(admin)/device/Device.tsx new file mode 100644 index 0000000..90b98f7 --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/device/Device.tsx @@ -0,0 +1,666 @@ +"use client" +import PageBreadcrumb from "@/components/common/PageBreadCrumb2"; +import ComponentCard from '@/components/common/ComponentCard2'; +import BizGroupPanel from "@/components/common/BizGroupPanel"; +import CtTable1 from '@/components/tables/CtTable1'; +import Button from '@/components/ui/button/Button2'; +import { DocsIcon, PlusIcon, TrashBinIcon, TableIcon, BoxCubeIcon, PencilIcon } from "@/icons"; +import WithLabel from '@/components/form/WithLabel'; +import Input from '@/components/form/input/InputField2'; +import Select from '@/components/form/Select2'; +import DatePicker from '@/components/form/date-picker2'; +import Checkbox from '@/components/form/input/Checkbox'; +import Badge from "@/components/ui/badge/Badge"; + +import React, { Key } from "react"; +import { useEffect, useState } from 'react'; +import { useRouter } from "next/navigation"; +import api, { useAuthStore, postFileDownload, convertDateTime3, useUiLoadingStore } from '@/lib/_AG'; + +import { useModal } from "@/hooks/useModal"; +import AddModifyDeviceModal, { DeviceModalProps } from './AddModifyDeviceModal'; +import ManageGoodsModal, { GoodsModalProps } from './ManageGoodsModal'; +import ManageTemplateModal, { TemplateModalProps } from './ManageTemplateModal'; +import { useMultiState } from "@/hooks/useMultiState"; + +import CtTree, { CtTreeNode, expandAndSelectTreeNode, getAllNodeKeys, findParentKeys, findNodeByKey, treeToList, addNodeByKey, deleteNodeByKey, findRootNodeByKey } from "@/components/CtTree"; +import { reqBizGroupTree2, reqBizGroupTree3 } from "@/app/(admin)/biz-group/BizGroupContent"; +import ManageBizGroupModal from "../biz-group/ManageBizGroupModal"; + + +const SEARCH_LABEL_WIDTH = 24; +const COUNT_PER_PAGE = 10; +const PAGE_NUM_COUNT = 5; + + + +export default function Device() { + const router = useRouter(); + const tokenPayload = useAuthStore((s) => s.tokenPayload); //Bruce, JWT + + const [ tableData, setTableData ] = useState([]); + const [ tableOffset, setTableOffset ] = useState(0); + const [ tableTotalCount, setTableTotalCount ] = useState(0); + + const [ treeData, setTreeData ] = useState([]); + const [ selectedTreeKeys, setSelectedTreeKeys ] = useState([]); + const [ expandedTreeKeys, setExpandedTreeKeys ] = useState([]); + const [ isGroupAccess, setGroupAccess ] = useState(tokenPayload?.permission == 1); //TempCode + const [ isTreeOpen, setTreeOpen ] = useState(tokenPayload?.permission == 1); //TempCode + + // group search fields + const [ name, setName ] = useState(""); + const [ biz_reg_num, setBizRegNum ] = useState(""); + + // device search fields + const [ date_start, setDateStart ] = useState(""); + const [ date_end, setDateEnd ] = useState(""); + const [ listIdleTerminal, setListIdelTerminal ] = useState([]); + const [ listGoods, setListGoods ] = useState([]); + const isLoadingGlobal = useUiLoadingStore((s) => s.isLoading); + + // modal + const { isOpen, openModal, closeModal } = useModal(); + const modalData = useMultiState( {biz_group_name: "", biz_reg_num: "", isModify: false, tid: "", device_id: "", biz_group_id: "", new_biz_group_id: "", terminal_id: "", name: "", manager_name: "", optTid: [], optBizGroup: [] }); + + const { isOpen: isOpenManageBizGroup, openModal: openModalManageBizGroup, closeModal: closeModalManageBizGroup } = useModal(); + + const { isOpen: isOpenManageGoods, openModal: openModalManageGoods, closeModal: closeModalManageGoods } = useModal(); + const modalDataManageGoods = useMultiState( {biz_group_name: "", biz_reg_num: "", device_name: "", device_id: "", + prev_device_goods: [], new_device_goods: [], optGoodsList: [] }); + + const { isOpen: isOpenManageTemplate, openModal: openModalManageTemplate, closeModal: closeModalManageTemplate } = useModal(); + const modalDataManageTemplate = useMultiState({ biz_group_id: 0, optGoodsList: [] }); + + + // function part + // + function reqDeviceList(is_excel: boolean, biz_group_id: string, groupAccess: boolean) { + if (!biz_group_id) + return; + + const params = { + is_excel: is_excel, + is_group_access: groupAccess, + offset: tableOffset, + limit: COUNT_PER_PAGE, + biz_group_id: biz_group_id, + date_start: date_start, + date_end: date_end, + } + + if (is_excel == true) { + postFileDownload('/api/get-device.do', params); + return; + } + + api.post('/api/get-device.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + if (resp.data.result.list.length == 0) { + //alert("조회 결과가 없습니다."); + setTableData([]); + return; + } + + setTableTotalCount(resp.data.result.totalCount); + setTableData(resp.data.result.list); + + //if (selectedTreeKeys.length == 0) + // setSelectedTreeKeys([String(biz_group_id)]); + + reqTerminalList(biz_group_id); + //reqGoodsList(biz_group_id); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + + function reqRemoveDevice(biz_group_id: string, device_id: string) { + const params = { + biz_group_id: biz_group_id, + device_id: device_id + } + + api.post('/api/remove-device.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + reqDeviceList(false, biz_group_id, isGroupAccess); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + + function reqTerminalList(biz_group_id: string) { + const params = { + limit: 100, // max 100 + biz_group_id: biz_group_id, + state: 5, // 미사용 + } + + api.post('/api/get-terminal.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + if (resp.data.result.list.length == 0) { + setListIdelTerminal([]); + return; + } + setListIdelTerminal(resp.data.result.list); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + + function reqGoodsList(biz_group_id: string) { + const params = { + limit: 100, // max 100 + biz_group_id: biz_group_id + } + + api.post('/api/get-goods.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + if (resp.data.result.list.length == 0) { + setListGoods([]); + return; + } + setListGoods(resp.data.result.list); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + + function reqDeviceGoodsList(device_id: string) { + const params = { + device_id: device_id + } + + api.post('/api/get-device-goods.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + if (resp.data.result.list.length > 0) { + const prev_device_goods = structuredClone(resp.data.result.list); + modalDataManageGoods.set("prev_device_goods", prev_device_goods); + + const new_device_goods = structuredClone(resp.data.result.list); + modalDataManageGoods.set("new_device_goods", new_device_goods); + } + + openModalManageGoods(); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + // + + + // event processing part + // + // tree part ////////// + const handleClickGroupManage = () => { + openModalManageBizGroup(); + } + + const handleManageBizGroupModalClose = () => { + closeModalManageBizGroup(); + reqBizGroupTree3(String(tokenPayload?.biz_group_id), setTreeData, setSelectedTreeKeys, setExpandedTreeKeys, (resp: any) => { + reqDeviceList(false, String(resp.data.result.tree[0].key), tokenPayload?.permission == 1); + }); + }; + + const handleClickGroupSearch = () => { + if (tokenPayload?.permission == 1) { + if (name == "" && biz_reg_num == "") { + alert("그룹명(사업자명) 또는 사업자등록번호를 입력하셔야 합니다."); + return; + } + if (name != "" && name.length < 3) { + alert("그룹명(사업자명)은 세글자 이상 입력해야 합니다."); + return; + } + if (biz_reg_num != "" && biz_reg_num.length < 3) { + alert("사업자등록번호는 세글자 이상 입력해야 합니다."); + return; + } + + //reqBizGroupTree3("", setTreeData, setSelectedTreeKeys, setExpandedTreeKeys); + reqBizGroupTree2(true, "", "", "", "", name, biz_reg_num, treeData, setTreeData); + } + else { + reqBizGroupTree3(String(tokenPayload?.biz_group_id), setTreeData, setSelectedTreeKeys, setExpandedTreeKeys, (resp: any) => { + //reqDeviceList(false, String(resp.data.result.tree[0].key), tokenPayload?.permission == 1); + reqDeviceList(false, String(resp.data.result.tree[0].key), isGroupAccess); + }); + } + }; + + const handleClickNode = (key: Key) => { + if (isGroupAccess == false) { + const root = findRootNodeByKey(treeData, key as string); + reqDeviceList(false, root.key as string, isGroupAccess); + return; + } + + setTableOffset(0); + reqDeviceList(false, key as string, isGroupAccess); + } + + const handleClickTreeExpanded = (key: Key) => { + const node = findNodeByKey(treeData, key); + if (node.children == undefined) + reqBizGroupTree2(false, key as string, "", "", "", "", "2", treeData, setTreeData); + } + + const handleClickGroupAccess = (value: boolean) => { + setGroupAccess(value); + + if (tokenPayload?.permission == 1) { + if (selectedTreeKeys.length <= 0) { + return; + } + + reqDeviceList(false, selectedTreeKeys[0] as string, value); + return; + } + + if (value == false || selectedTreeKeys.length <= 0) { + reqDeviceList(false, String(tokenPayload?.biz_group_id), value); + } + else { + reqDeviceList(false, selectedTreeKeys[0] as string, value); + } + } + // tree part ////////// + + + const handleClickDownload = () => { + reqDeviceList(true, selectedTreeKeys[0] as string, isGroupAccess); + }; + + const handleClickSearch = () => { + if (selectedTreeKeys.length <= 0) { + alert("조회하려면 사업자를 선택해야 합니다."); + return; + } + + reqDeviceList(false, selectedTreeKeys[0] as string, isGroupAccess); + }; + + const handleClickAdd = () => { + if (selectedTreeKeys.length <= 0) { + alert("신규 추가하려면 사업자를 선택해야 합니다."); + return; + } + + // m: 0 = isModify is false, 1 = isModify is true + // bgid: biz_group_id + //router.push("/device/detail?m=0&bgid=" + selectedTreeKeys[0]); + + const tidList = [{ label: "카드단말기없음", value: "0" }]; + + listIdleTerminal.map((item: any) => ( + tidList.push({ + label: item.uid1 + "(" + (item.type == 1 ? "KICC" : "NICE") + ")", + value: String(item.terminal_id) + }) + )); + modalData.set("optTid", tidList); + + const treeList = treeToList(treeData); + //console.log("treeList: ", treeList) + const optBizGroup = treeList.map((item: any) => ( + { label: item.title, value: item.key } + )); + //console.log("optBizGroup: ", optBizGroup) + modalData.set("optBizGroup", optBizGroup); + + const node = findNodeByKey(treeData, selectedTreeKeys[0]); + modalData.setAll({ + isModify: false, + biz_group_name: node.name, + biz_reg_num: node.biz_reg_num, + device_id: "", + biz_group_id: node.key, + terminal_id: "", + name: "", + }); + openModal(); + }; + + const handleRowClickGoods = (row: number) => { + //if (listGoods.length == 0) { + // alert("등록된 상품이 없습니다. 좌측 '상품관리' 메뉴에서 상품목록을 등록하세요."); + // return; + //} + + router.push(`/device/manage-goods?id=${tableData[row].device_id}`); + /* + const goodsList: { label: string; value: string; }[] = []; + listGoods.map((item: any) => ( + goodsList.push({ label: item.name + "(" + item.code + ")", value: item.goods_id }) + )); + //modalDataManageGoods.set("optGoodsList", goodsList); + + const node = findNodeByKey(treeData, String(tableData[row].biz_group_id)); + modalDataManageGoods.setAll({ + biz_group_name: node.name, + biz_reg_num: node.biz_reg_num, + device_name: tableData[row].name, + optGoodsList: goodsList, + device_id: tableData[row].device_id, + }); + + //openModalManageGoods(); + modalDataManageGoods.set("prev_device_goods", []); + modalDataManageGoods.set("new_device_goods", []); + reqDeviceGoodsList(tableData[row].device_id); + */ + } + + const handleRowClickModify = (row: number) => { + const tidList = [{ label: tableData[row].uid1 ? (tableData[row].uid1 + + "(" + (tableData[row].type == 1 ? "KICC" : "NICE") + + (tableData[row].state == 1 ? ") - 사용중" : ")")) + : "카드단말기없음", value: "0" }]; + + if (tableData[row].state == 1) { + listIdleTerminal.map((item: any) => ( + tidList.push({ + label: item.uid1 + "(" + (item.type == 1 ? "KICC" : "NICE") + ")", + value: String(item.terminal_id) + }) + )); + } + modalData.set("optTid", tidList); + modalData.set("tid", tableData[row].uid1); + + + const treeList = treeToList(treeData); + //console.log("treeList: ", treeList) + const optBizGroup = treeList.map((item: any) => ( + { label: item.title, value: item.key } + )); + //console.log("optBizGroup: ", optBizGroup) + modalData.set("optBizGroup", optBizGroup); + + const node = findNodeByKey(treeData, String(tableData[row].biz_group_id)); + modalData.setAll({ + ...tableData[row], + isModify: true, + biz_group_name: node.name, + biz_reg_num: node.biz_reg_num, + }); + openModal(); + }; + + const handleRowClickDelete = (row: number) => { + if (confirm("정말로 삭제하시겠습니까?")) { + reqRemoveDevice(tableData[row].biz_group_id, tableData[row].device_id); + } + }; + + const handlePageChange = (page: number) => { + setTableOffset((page - 1) * COUNT_PER_PAGE); + }; + + const handleModalOk = () => { + closeModal(); + reqDeviceList(false, selectedTreeKeys[0] as string, isGroupAccess); + }; + + //const handleManageGoodsModalOk = () => { + // closeModalManageGoods(); + //}; + + const handleClickTemplateManage = () => { + if (selectedTreeKeys.length <= 0) { + alert("템플릿을 관리하려면 사업자를 선택해야 합니다."); + return; + } + + if (listGoods.length == 0) { + alert("등록된 상품이 없습니다. 좌측 '상품관리' 메뉴에서 상품목록을 등록하세요."); + return; + } + + const goodsList: { label: string; value: string; }[] = []; + listGoods.map((item: any) => ( + goodsList.push({ label: item.name + "(" + item.code + ")", value: item.goods_id }) + )); + + modalDataManageTemplate.setAll({ + biz_group_id: Number(selectedTreeKeys[0]), + optGoodsList: goodsList + }); + + openModalManageTemplate(); + }; + + const handleManageTemplateModalOk = () => { + // 템플릿 관리 완료 후 필요한 경우 추가 작업 + }; + // + + useEffect(() => { + if (tokenPayload == undefined) + return; + + if (tokenPayload?.permission == 1) + return; + + reqBizGroupTree3(String(tokenPayload?.biz_group_id), setTreeData, setSelectedTreeKeys, setExpandedTreeKeys, (resp: any) => { + setGroupAccess(tokenPayload?.permission == 1); + setTreeOpen(tokenPayload?.permission == 1); + + reqDeviceList(false, String(resp.data.result.tree[0].key), tokenPayload?.permission == 1); + }); + }, [tokenPayload]); + + useEffect(() => { + reqDeviceList(false, selectedTreeKeys[0] as string, isGroupAccess); + }, [tableOffset]); + + + // UI part + // + const columns = [ + { + title: "등록일", + key: "reg_time", + renderItem: (item: any, row: number) => convertDateTime3(item.reg_time) + }, + { + title: "그룹", + key: "biz_group_name", + }, + { + title: "무인기기명", + key: "name", + }, + { + title: "단말기 TID", + key: "uid1", + renderItem: (item: any, row: number) => { + return item.uid1 ? (item.uid1 + " (" + (item.type == 1 ? "KICC" : "NICE") +")") : "" + } + }, + { + title: "상태", + key: "state", + renderItem: (item: any) => { + const connectTime = item.connect_time ? new Date(item.connect_time.replace(' ', 'T')) : null; + const disconnectTime = item.disconnect_time ? new Date(item.disconnect_time.replace(' ', 'T')) : null; + + let color: "success" | "error" | "info" = "info"; + let text = ""; + + if (connectTime && (!disconnectTime || disconnectTime < connectTime)) { + color = "success"; + text = "가동중"; + } else if (connectTime && disconnectTime && disconnectTime > connectTime) { + color = "error"; + text = "장애"; + } + + return ( + + {text} + + ); + }, + }, + { + title: "가동시간", + key: "connect_time", + renderItem: (item: any, row: number) => convertDateTime3(item.connect_time) + }, + { + title: "장애발생시간", + key: "disconnect_time", + renderItem: (item: any, row: number) => convertDateTime3(item.disconnect_time) + }, + { + title: "관리자", + key: "manager_name", + }, + { + title: "상품관리", + key: "_", + renderItem: (item: any, row: number) => ( +
+ {handleRowClickGoods(row)}} /> +
+ ), + }, + { + title: "설정", + key: "_", + renderItem: (item: any, row: number) => ( +
+ {handleRowClickModify(row)}} /> +
+ ), + }, + { + title: "삭제", + key: "_", + renderItem: (item: any, row: number) => ( +
+ {handleRowClickDelete(row)}} /> +
+ ), + }, + ]; + + return ( +
+ + +
+ + + + + } > +
+
+ +
+ { setDateStart(currentDateString); }} + /> + { setDateEnd(currentDateString); }} + /> +
+
+ +
+ { isTreeOpen && <> + handleClickGroupAccess(value)} /> + + 그룹단위로 조회 + + } +
+ +
+ {/**/} + + +
+
+
+ + + {/* +
+ +
+ */} + +
+ + + + + + {/**/} + + +
+
+ ); +} diff --git a/smartservice_frontend/src/app/(admin)/device/ManageGoodsModal.tsx b/smartservice_frontend/src/app/(admin)/device/ManageGoodsModal.tsx new file mode 100644 index 0000000..312e72a --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/device/ManageGoodsModal.tsx @@ -0,0 +1,202 @@ +"use client"; +import React, { useEffect, useState } from "react"; +import Label from '@/components/form/Label2'; +import Input from '@/components/form/input/InputField2'; +import Select from '@/components/form/Select2'; +import CtModal from "@/components/CtModal"; +import { useMultiState } from "@/hooks/useMultiState"; +import api from '@/lib/_AG'; +import Button from "@/components/ui/button/Button2"; +import { PlusIcon, TrashBinIcon } from "@/icons"; + + +interface DeviceGooodsItem { + slot: string; + goods_id: number; + price?: number; + inventory?: number; +} + +export interface GoodsModalProps { + biz_group_name?: string; // internal use + biz_reg_num?: string; // internal use + device_name?: string; // internal use + optGoodsList: { label: string; value: string; }[]; + // + device_id: string; + prev_device_goods: DeviceGooodsItem[]; + new_device_goods: DeviceGooodsItem[]; +} + +interface ManageGoodsModalProps { + multiState: ReturnType>; + onOk: () => void; + isOpen: boolean; + closeModal: () => void; +} + + +export default function ManageGoodsModal({ multiState, onOk, isOpen, closeModal }: ManageGoodsModalProps) { + + function computeGoods(modal: GoodsModalProps): GoodsModalProps { + // 1 & 2. 우선 slot이 빈 문자열("")이 아닌 아이템들만 추출 (1차 필터링) + const filteredPrev = modal.prev_device_goods.filter(item => item.slot !== ""); + const filteredNew = modal.new_device_goods.filter(item => item.slot !== ""); + + // 3. slot이 같으면서 goods_id까지 같은 아이템은 양쪽에서 제거 + // 즉, "상대방 배열에 나랑 똑같은(slot & goods_id) 애가 없는" 것들만 남깁니다. + + // device_goods 정제 + const final_device_goods = filteredPrev.filter(prevItem => + !filteredNew.find(newItem => + newItem.slot === prevItem.slot && newItem.goods_id === prevItem.goods_id + ) + ); + + // new_device_goods 정제 + const final_new_device_goods = filteredNew.filter(newItem => + !filteredPrev.find(prevItem => + prevItem.slot === newItem.slot && prevItem.goods_id === newItem.goods_id + ) + ); + + // 결과 저장 + return { + ...modal, + prev_device_goods: final_device_goods, + new_device_goods: final_new_device_goods, + }; + } + + + /* + const handleSelectGoods = (goods_id: number, newValue: string) => { + setGoodsList((prev) => + prev.map((item) => (item.goods_id === id ? { ...item, value: newValue } : item)) + ); + }; + */ + + const handleClickAddOrModify = () => { + //if (multiState.values.name == "") { + // alert("기기 명칭을 입력하셔야 합니다."); + // return; + //} + + console.log("1 - ", multiState.values.prev_device_goods); + console.log("2 - ", multiState.values.new_device_goods); + + //const { biz_group_name, biz_reg_num, device_name, optGoodsList, ...params } = multiState.values; + const { biz_group_name, biz_reg_num, device_name, optGoodsList, ...params } = computeGoods(multiState.values); + + console.log("5 - ", params.prev_device_goods); + console.log("6 - ", params.new_device_goods); + + + //console.log(params); + + api.post('/api/manage-device-goods.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("저장되었습니다."); + onOk(); + } + else if (resp.data.errCode == -11) { + alert("컬럼번호는 중복될 수 없습니다."); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + + const handleClickAdd = () => { + if (multiState.values.optGoodsList.length == 0) { + //alert("등록된 상품이 없습니다. 좌측 '상품관리' 메뉴에서 상품목록을 등록하세요."); + return; + } + + const newItem: DeviceGooodsItem = { slot: "", goods_id: parseInt(multiState.values.optGoodsList[0].value) } + const newArray: DeviceGooodsItem[] = [...multiState.values.new_device_goods, newItem]; + + multiState.set("new_device_goods", newArray); + } + + const handleClickDel = (row: number) => { + const newArray: DeviceGooodsItem[] = + multiState.values.new_device_goods.filter((_, index) => index !== row); + + multiState.set("new_device_goods", newArray); + } + + const handleChangeSlot = (index: number, newValue: string) => { + const newArray: DeviceGooodsItem[] = [...multiState.values.new_device_goods]; + newArray[index].slot = newValue; + + multiState.set("new_device_goods", newArray); + }; + + const handleChangeInventory = (index: number, newValue: string) => { + const newArray: DeviceGooodsItem[] = [...multiState.values.new_device_goods]; + newArray[index].inventory = Number(newValue); + + multiState.set("new_device_goods", newArray); + }; + + const handleChangeGoods = (index: number, newValue: string) => { + const newArray: DeviceGooodsItem[] = [...multiState.values.new_device_goods]; + newArray[index].goods_id = Number(newValue); + + multiState.set("new_device_goods", newArray); + }; + + return ( + //
+ +
+ + +
+
+ + +
+ {multiState.values.new_device_goods.map((item, index) => ( +
+ +
+
+ handleChangeSlot(index, e.target.value)} /> +
+
+ handleChangeInventory(index, e.target.value)} /> +
+ +
+
+ ))} +
+ +
+
+ //
+ ); +}; diff --git a/smartservice_frontend/src/app/(admin)/device/ManageTemplateModal.tsx b/smartservice_frontend/src/app/(admin)/device/ManageTemplateModal.tsx new file mode 100644 index 0000000..378adcd --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/device/ManageTemplateModal.tsx @@ -0,0 +1,396 @@ +"use client"; +import React, { useEffect, useState } from "react"; +import Label from '@/components/form/Label2'; +import Input from '@/components/form/input/InputField2'; +import Select from '@/components/form/Select2'; +import CtModal from "@/components/CtModal"; +import { useMultiState } from "@/hooks/useMultiState"; +import api from '@/lib/_AG'; +import Button from "@/components/ui/button/Button2"; +import { PlusIcon, TrashBinIcon } from "@/icons"; + +interface TemplateElement { + slot: string; + goods_id: number; + inventory?: number; +} + +interface Template { + goods_template_id: number; + template_name: string; + elements: TemplateElement[]; +} + +export interface TemplateModalProps { + biz_group_id: number; + optGoodsList: { label: string; value: string; }[]; +} + +interface ManageTemplateModalProps { + multiState: ReturnType>; + onOk: () => void; + isOpen: boolean; + closeModal: () => void; +} + +type Mode = 'list' | 'create' | 'edit'; + +export default function ManageTemplateModal({ multiState, onOk, isOpen, closeModal }: ManageTemplateModalProps) { + const [templates, setTemplates] = useState([]); + const [mode, setMode] = useState('list'); + const [selectedTemplateId, setSelectedTemplateId] = useState(null); + const [templateName, setTemplateName] = useState(""); + const [currentElements, setCurrentElements] = useState([]); + + // function part + function groupTemplatesByTemplateId(data: any[]): Template[] { + const templateMap = new Map(); + + data.forEach((item) => { + const templateId = item.goods_template_id; + + if (!templateMap.has(templateId)) { + templateMap.set(templateId, { + goods_template_id: templateId, + template_name: item.template_name, + elements: [] + }); + } + + const template = templateMap.get(templateId)!; + template.elements.push({ + slot: item.slot, + goods_id: item.goods_id, + inventory: item.inventory + }); + }); + + return Array.from(templateMap.values()); + } + + function reqTemplateList() { + if (!multiState.values.biz_group_id) { + return; + } + + const params = { + biz_group_id: multiState.values.biz_group_id + }; + + api.post('/api/get-goods-template.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + if (resp.data.result && resp.data.result.length > 0) { + const groupedTemplates = groupTemplatesByTemplateId(resp.data.result); + setTemplates(groupedTemplates); + } else { + setTemplates([]); + } + } else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => { + console.error(err); + alert("템플릿 조회 중 오류가 발생했습니다."); + }); + } + + function reqRemoveTemplate(templateId: number) { + if (!confirm("템플릿을 삭제하시겠습니까?")) { + return; + } + + const params = { + goods_template_id: templateId + }; + + api.post('/api/remove-goods-template.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("삭제되었습니다."); + reqTemplateList(); + } else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => { + console.error(err); + alert("템플릿 삭제 중 오류가 발생했습니다."); + }); + } + + function reqAddTemplate() { + if (currentElements.length === 0) { + alert("최소 하나 이상의 상품을 등록해야 합니다."); + return; + } + + // slot이 빈 문자열인 항목 필터링 + const validElements = currentElements.filter(item => item.slot !== ""); + + if (validElements.length === 0) { + alert("컬럼번호를 입력한 상품이 없습니다."); + return; + } + + const params = { + biz_group_id: multiState.values.biz_group_id, + goods_template_elements: validElements.map(item => ({ + slot: item.slot, + goods_id: item.goods_id, + inventory: item.inventory || null + })) + }; + + api.post('/api/add-goods-template.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("생성되었습니다."); + resetToInitialState(); + reqTemplateList(); + onOk(); + } else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => { + console.error(err); + alert("템플릿 생성 중 오류가 발생했습니다."); + }); + } + + function reqModifyTemplate() { + if (!selectedTemplateId) { + return; + } + + if (currentElements.length === 0) { + alert("최소 하나 이상의 상품을 등록해야 합니다."); + return; + } + + // slot이 빈 문자열인 항목 필터링 + const validElements = currentElements.filter(item => item.slot !== ""); + + if (validElements.length === 0) { + alert("컬럼번호를 입력한 상품이 없습니다."); + return; + } + + const params = { + goods_template_id: selectedTemplateId, + goods_template_name: templateName || undefined, + goods_template_elements: validElements.map(item => ({ + slot: item.slot, + goods_id: item.goods_id, + inventory: item.inventory || null + })) + }; + + api.post('/api/modify-goods-template.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("수정되었습니다."); + resetToInitialState(); + reqTemplateList(); + onOk(); + } else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => { + console.error(err); + alert("템플릿 수정 중 오류가 발생했습니다."); + }); + } + + function resetToInitialState() { + setMode('list'); + setSelectedTemplateId(null); + setTemplateName(""); + setCurrentElements([]); + } + + // event handler function part + const handleClickCreate = () => { + setMode('create'); + setCurrentElements([]); + setTemplateName(""); + }; + + const handleClickEdit = (template: Template) => { + setMode('edit'); + setSelectedTemplateId(template.goods_template_id); + setTemplateName(template.template_name); + setCurrentElements([...template.elements]); + }; + + const handleClickCancel = () => { + resetToInitialState(); + }; + + const handleClickAdd = () => { + if (multiState.values.optGoodsList.length == 0) { + alert("등록된 상품이 없습니다. 좌측 '상품관리' 메뉴에서 상품목록을 등록하세요."); + return; + } + + const newItem: TemplateElement = { + slot: "", + goods_id: parseInt(multiState.values.optGoodsList[0].value) + }; + setCurrentElements([...currentElements, newItem]); + }; + + const handleClickDel = (index: number) => { + const newArray = currentElements.filter((_, i) => i !== index); + setCurrentElements(newArray); + }; + + const handleChangeSlot = (index: number, newValue: string) => { + const newArray = [...currentElements]; + newArray[index].slot = newValue; + setCurrentElements(newArray); + }; + + const handleChangeInventory = (index: number, newValue: string) => { + const newArray = [...currentElements]; + newArray[index].inventory = Number(newValue); + setCurrentElements(newArray); + }; + + const handleChangeGoods = (index: number, newValue: string) => { + const newArray = [...currentElements]; + newArray[index].goods_id = Number(newValue); + setCurrentElements(newArray); + }; + + // useEffect part + useEffect(() => { + if (isOpen && multiState.values.biz_group_id) { + reqTemplateList(); + resetToInitialState(); + } + }, [isOpen, multiState.values.biz_group_id]); + + // UI part + return ( + //
+ { + resetToInitialState(); + closeModal(); + }} + className="max-w-[700px] p-6 lg:p-10" + > + {mode === 'list' && ( + <> +
+ {templates.length === 0 ? ( +
등록된 템플릿이 없습니다.
+ ) : ( + templates.map((template) => ( +
handleClickEdit(template)} + > + {template.template_name} +
e.stopPropagation()}> +
+
+ )) + )} +
+
+ +
+ + )} + + {(mode === 'create' || mode === 'edit') && ( + <> + {mode === 'edit' && ( +
+ + setTemplateName(e.target.value)} + /> +
+ )} + {currentElements.map((item, index) => ( +
+ +
+
+ handleChangeSlot(index, e.target.value)} + /> +
+
+ handleChangeInventory(index, e.target.value)} + /> +
+
+
+ ))} +
+ + +
+ + )} +
+ //
+ ); +} + diff --git a/smartservice_frontend/src/app/(admin)/device/manage-goods/GoodsTemplateNameModal.tsx b/smartservice_frontend/src/app/(admin)/device/manage-goods/GoodsTemplateNameModal.tsx new file mode 100644 index 0000000..cd45ec4 --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/device/manage-goods/GoodsTemplateNameModal.tsx @@ -0,0 +1,49 @@ +"use client" +import React, { useState } from "react"; +import CtModal from '@/components/CtModal'; +import Label from '@/components/form/Label2'; +import Input from '@/components/form/input/InputField2'; + +interface SaveTemplateNameModalProps { + isOpen: boolean; + closeModal: (tName: string) => void; +} + +export default function SaveTemplateNameModal({ isOpen, closeModal }: SaveTemplateNameModalProps) { + const [inputValue, setInputValue] = useState(""); + + const handleClickSave = () => { + if (!inputValue || inputValue.trim() === "") { + alert("사전설정의 설정명을 입력해주세요."); + return; + } + closeModal(inputValue); + }; + + const handleClose = () => { + setInputValue(""); + closeModal(""); + }; + + return ( + +
+ + setInputValue(e.target.value)} + /> +
+
+ ); +} diff --git a/smartservice_frontend/src/app/(admin)/device/manage-goods/ManageGoods.tsx b/smartservice_frontend/src/app/(admin)/device/manage-goods/ManageGoods.tsx new file mode 100644 index 0000000..d67cdd0 --- /dev/null +++ b/smartservice_frontend/src/app/(admin)/device/manage-goods/ManageGoods.tsx @@ -0,0 +1,381 @@ +"use client" +import PageBreadcrumb from "@/components/common/PageBreadCrumb2"; +import ComponentCard from '@/components/common/ComponentCard2'; +import CtTable1 from '@/components/tables/CtTable1'; +import Button from '@/components/ui/button/Button2'; +import { DocsIcon, FileIcon, PlusIcon, TrashBinIcon, TableIcon, PencilIcon, GridIcon } from "@/icons"; +import Label from '@/components/form/Label2'; +import Input from '@/components/form/input/InputField2'; +import Select from '@/components/form/Select2'; +import DatePicker from '@/components/form/date-picker2'; +import Badge from "@/components/ui/badge/Badge"; +import Checkbox from '@/components/form/input/Checkbox'; +import SaveTemplateNameModal from './GoodsTemplateNameModal'; + +import React, { Key } from "react"; +import { useEffect, useState } from 'react'; +//import { useSearchParams, useRouter } from "next/navigation"; +import { useRouter, useSearchParams } from "next/navigation"; +import api, { convertDateTime3, getUrlParam, useAuthStore } from '@/lib/_AG'; +import DeviceGoodsList from '@/components/DeviceGoodsItem'; + + + +interface DeviceGooodsItem { + slot: string; + goods_id: number; + price?: number; + inventory?: number; + inventory_max?: number; + inventory_alarm?: number; + idx?: number; +} + +interface GoodsTemplateItem { + goods_template_id: number; + template_name: string; + template_reg_time?: string; + template_inventory: number; + template_inventory_max: number; + template_inventory_alarm: number; + goods_template_elements: Array<{ + goods_template_element_id: number; + goods_id: number; + slot: string; + inventory: number; + inventory_max?: number; + inventory_alarm?: number; + idx: number; + }>; +} + +function makeParams(device_id: string, prev_device_goods: DeviceGooodsItem[], new_device_goods: DeviceGooodsItem[], isSaveTemplate: boolean, templateName: string, biz_group_id: string | undefined, inventorySetValue: { inventory: number; inventory_max: number; inventory_alarm: number } ) { + const filteredPrev = prev_device_goods.filter(item => item.slot !== "" && item.goods_id !== 0); + const filteredNew = new_device_goods.filter(item => item.slot !== "" && item.goods_id !== 0); + + const final_device_goods = filteredPrev.filter(prevItem => + !filteredNew.find(newItem => + newItem.slot === prevItem.slot && newItem.goods_id === prevItem.goods_id && newItem.inventory === prevItem.inventory && newItem.inventory_max === prevItem.inventory_max && newItem.inventory_alarm === prevItem.inventory_alarm + ) + ); + + const final_new_device_goods = filteredNew.filter(newItem => + !filteredPrev.find(prevItem => + prevItem.slot === newItem.slot && prevItem.goods_id === newItem.goods_id && newItem.inventory === prevItem.inventory && newItem.inventory_max === prevItem.inventory_max && newItem.inventory_alarm === prevItem.inventory_alarm + ) + ); + + console.log("saved prev_device_goods: " + JSON.stringify(prev_device_goods)); + console.log("saved new_device_goods: " + JSON.stringify(new_device_goods)); + console.log("filteredNew: " + JSON.stringify(filteredNew)); + console.log("final_device_goods: " + JSON.stringify(final_device_goods)); + console.log("final_new_device_goods: " + JSON.stringify(final_new_device_goods)); + + const params: any = { + device_id: Number(device_id), + prev_device_goods: final_device_goods, + new_device_goods: final_new_device_goods + }; + + params.isSaveTemplate = isSaveTemplate; + params.templateName = templateName; + params.biz_group_id = biz_group_id; + params.goods_template_elements = filteredNew; + params.goods_template_inventory = { + inventory_count: inventorySetValue?.inventory || 0, + inventory_max: inventorySetValue?.inventory_max || 0, + inventory_alarm: inventorySetValue?.inventory_alarm || 0 + }; + + + console.log("params: " + JSON.stringify(params)); + return params; +} + +export default function ManageGoods() { + + const searchParams = useSearchParams(); + const device_id = searchParams?.get('id') ?? ""; + + const router = useRouter(); + const tokenPayload = useAuthStore((s) => s.tokenPayload); //Bruce, JWT + + const [ biz_group_id, setBiz_group_id ] = useState(""); + const [ biz_group_name, setBiz_group_name ] = useState(""); + const [ biz_reg_num, setBiz_reg_num ] = useState(""); + const [ device_name, setDevice_name ] = useState(""); + + const [ optGoodsList, setOptGoodsList ] = useState([]); + + const [ prev_device_goods, setPrev_device_goods ] = useState([]); + const [ new_device_goods, setNew_device_goods ] = useState(Array.from({ length: 30 }, (_, i) => ({ idx: i + 1, slot: String(i + 1).padStart(2, "0"), goods_id: 0, inventory: 0, inventory_max: 0, inventory_alarm: 0 }))); + + const [ isSaveTemplate, setIsSaveTemplate ] = useState(false); + const [ isModalOpen, setIsModalOpen ] = useState(false); + const [ goodsTemplateList, setGoodsTemplateList ] = useState([]); + const [ inventorySetValue, setInventorySetValue ] = useState<{ inventory: number; inventory_max: number; inventory_alarm: number }>({ inventory: 0, inventory_max: 0, inventory_alarm: 0 }); + + function reqDeviceGoodsList(device_id: string) { + const params = { + device_id: device_id + } + + api.post('/api/get-device-goods.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + if (resp.data.result.goods_list.length == 0) { + alert("등록된 상품이 없습니다. 좌측 '상품관리' 메뉴에서 상품목록을 등록하세요."); + //router.back(); + router.push("/device"); + return; + } + /* + biz_group_id를 goods_list 에서 가져옮으로서 잘못된 biz_group이 선택되고 있는 문제 해결 필요 + */ + setDevice_name(resp.data.result.device_name); + setBiz_group_name(resp.data.result.goods_list[0].biz_group_name); + setBiz_reg_num(resp.data.result.goods_list[0].biz_reg_num); + + const goodsList: { label: string; value: string; }[] = []; + resp.data.result.goods_list.map((item: any) => ( + goodsList.push({ label: item.name + "(" + item.code + ")", value: String(item.goods_id) }) + )); + setOptGoodsList(goodsList); + + setBiz_group_id(resp.data.result.goods_list[0].biz_group_id); + if (resp.data.result.device_goods_list.length > 0) { + setPrev_device_goods(structuredClone(resp.data.result.device_goods_list)); + + setNew_device_goods(prev => prev.map(item => { + const updated = resp.data.result.device_goods_list.find((u: { idx: string; }) => u.idx === item.idx); + return updated ? { ...item, ...updated } : item; + })); + } + + if (resp.data.result.goods_template_list && resp.data.result.goods_template_list.length > 0) { + setGoodsTemplateList(resp.data.result.goods_template_list); + setInventorySetValue( { inventory: resp.data.result.goods_template_list[0].inventory_count || 0, inventory_max: resp.data.result.goods_template_list[0].inventory_max || 0, inventory_alarm: resp.data.result.goods_template_list[0].inventory_alarm || 0 } ); + } + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + + // function part + // + function onGoback() { + //router.back(); + router.push("/device"); + } + + // event processing part + // + const handleClickDel = (row: number) => { + const newArray: DeviceGooodsItem[] = + new_device_goods.filter((_, index) => index !== row); + + setNew_device_goods(newArray); + } + + const handleChangeSlot = (index: number, newValue: string) => { + const newArray: DeviceGooodsItem[] = [...new_device_goods]; + newArray[index].slot = newValue; + + setNew_device_goods(newArray); + }; + + const handleChangeInventory = (index: number, newValue: string) => { + const newArray: DeviceGooodsItem[] = [...new_device_goods]; + newArray[index].inventory = Number(newValue); + + setNew_device_goods(newArray); + }; + + const handleChangeInventoryMax = (index: number, newValue: string) => { + const newArray: DeviceGooodsItem[] = [...new_device_goods]; + newArray[index].inventory_max = Number(newValue); + + setNew_device_goods(newArray); + }; + + const handleChangeInventoryAlarm = (index: number, newValue: string) => { + const newArray: DeviceGooodsItem[] = [...new_device_goods]; + newArray[index].inventory_alarm = Number(newValue); + + setNew_device_goods(newArray); + }; + + const handleChangeGoods = (index: number, newValue: string) => { + const newArray: DeviceGooodsItem[] = [...new_device_goods]; + newArray[index].goods_id = Number(newValue); + + setNew_device_goods(newArray); + }; + + const handleChangeInventorySetValue = (field: 'inventory' | 'inventory_max' | 'inventory_alarm', value: number) => { + setInventorySetValue(prev => ({ ...prev, [field]: value })); + }; + + const handleClickAdd = () => { + //const newItem: DeviceGooodsItem = { slot: "", goods_id: parseInt(optGoodsList[0].value) } + const newItem: DeviceGooodsItem = { slot: "", goods_id: 0 } + const newArray: DeviceGooodsItem[] = [...new_device_goods, newItem]; + + setNew_device_goods(newArray); + } + // + + const handleClickAddOrModify = () => { + if (isSaveTemplate) { + setIsModalOpen(true); + return; + } else { + executeSave(false, ""); + } + } + + const handleModalClose = (tName: string) => { + setIsModalOpen(false); + if (tName !== "") { + executeSave(true, tName); + } else { + return; // 사전저장하기 했는데 이름안정했으면 저장 취소되도록함. + } + }; + + const executeSave = (saveTemplate: boolean, name: string) => { + const params = makeParams(device_id, prev_device_goods, new_device_goods, saveTemplate, name, biz_group_id, inventorySetValue); + + api.post('/api/manage-device-goods.do', params).then((resp) => { + console.log(resp); + + if (resp.data.errCode == 0) { + alert("자판기에 상품내용이 적용되었습니다."); + router.push("/device"); + //onOk(); + } + else if (resp.data.errCode == -11) { + alert("컬럼번호는 중복될 수 없습니다."); + } + else { + alert("일시적으로 사용할 수 없습니다 : " + resp.data.errCode); + } + }) + .catch((err) => console.error(err)) + } + + const handleApplyGoodsTemplate = (goodsTemplateId: number) => { + const goodsTemplate = goodsTemplateList.find((item: GoodsTemplateItem) => item.goods_template_id === goodsTemplateId); + if (goodsTemplate && goodsTemplate.goods_template_elements) { + // 기존 값을 모두 비우고 초기 상태로 리셋 + const resetGoods = Array.from({ length: 30 }, (_, i) => ({ + idx: i + 1, + slot: String(i + 1).padStart(2, "0"), + goods_id: 0, + inventory: 0 + })); + + setInventorySetValue( { inventory: goodsTemplate.template_inventory, inventory_max: goodsTemplate.template_inventory_max, inventory_alarm: goodsTemplate.template_inventory_alarm } ); + + + // 템플릿의 goods_template_elements를 DeviceGooodsItem 형태로 변환 + const mappedGoods: DeviceGooodsItem[] = goodsTemplate.goods_template_elements.map((element) => ({ + slot: element.slot, + goods_id: Number(element.goods_id), + inventory: element.inventory, + inventory_max: element.inventory_max, + inventory_alarm: element.inventory_alarm, + idx: element.idx + })); + + // 템플릿 요소로 채우기 + const updatedGoods = resetGoods.map(item => { + const templateItem = mappedGoods.find((t: DeviceGooodsItem) => t.idx === item.idx); + return templateItem ? { ...item, ...templateItem } : item; + }); + + setNew_device_goods(updatedGoods); + } + } + + useEffect(() => { + reqDeviceGoodsList(device_id); + // reqGoodsTemplateList(tokenPayload?.biz_group_id || ""); + }, [tokenPayload]); + + return ( +
+ + +
+ + +
+
+ + +
+
+ + +
+
+
+ + setTitle(e.target.value)} /> + + + setCategory(e.target.value)} /> + +
+
+ +
+ { setDateStart(currentDateString); }} + /> + { setDateEnd(currentDateString); }} + /> +
+
+
+ + +
+
+
+ + + +
+ +
+ +
+ + {/* FAQ 등록 모달 (fake용, 실제 저장은 하지 않음) */} + setIsModalOpen(false)} + className="max-w-[700px] p-6 lg:p-10" + > +
+ + setNewTitle(e.target.value)} + /> +
+
+ +