├── .gitignore ├── README.md ├── api ├── machine │ ├── cpu.go │ ├── memory.go │ ├── network.go │ ├── osinfo.go │ ├── processes.go │ └── storage.go └── utils │ └── headers.go ├── go.mod ├── go.sum ├── machine ├── README.md ├── cpu │ ├── cpu.go │ ├── stat.go │ ├── thermal.go │ └── usage.go ├── memory │ └── memory.go ├── network │ └── network.go ├── osinfo │ └── osinfo.go ├── processes │ └── processes.go ├── storage │ ├── disk.go │ ├── mounts.go │ ├── partition.go │ ├── stat.go │ └── storage.go └── utils │ ├── cat.go │ └── grep.go ├── main.go └── web ├── .gitignore ├── README.md ├── index.html ├── jsconfig.json ├── package-lock.json ├── package.json ├── src ├── App.svelte └── main.js ├── svelte.config.js └── vite.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | /tmp -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Statee 2 | 3 | **As for now, not a complete app but a bunch of internal APIs for fetching host information easily.** 4 | 5 | Now, I want to achieve universal scalability and versatility to make this project essential for many Linux-based environments, and not only small homeservers. 6 | 7 | On top of them, a new fresh system monitoring web app will be created. 8 | 9 | **Instead, please use [Status](https://github.com/dani3l0/Status)** 10 | -------------------------------------------------------------------------------- /api/machine/cpu.go: -------------------------------------------------------------------------------- 1 | package machine 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | "statee/api/utils" 7 | "statee/machine/cpu" 8 | ) 9 | 10 | func GetCpu(w http.ResponseWriter, r *http.Request) { 11 | utils.SetHeaders(w) 12 | rawData := cpu.GetCpu() 13 | jsonData, _ := json.Marshal(rawData) 14 | 15 | w.Write(jsonData) 16 | } 17 | -------------------------------------------------------------------------------- /api/machine/memory.go: -------------------------------------------------------------------------------- 1 | package machine 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | "statee/api/utils" 7 | "statee/machine/memory" 8 | ) 9 | 10 | func GetMemory(w http.ResponseWriter, r *http.Request) { 11 | utils.SetHeaders(w) 12 | rawData := memory.GetMemory() 13 | jsonData, _ := json.Marshal(rawData) 14 | 15 | w.Write(jsonData) 16 | } 17 | -------------------------------------------------------------------------------- /api/machine/network.go: -------------------------------------------------------------------------------- 1 | package machine 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | "statee/api/utils" 7 | "statee/machine/network" 8 | ) 9 | 10 | func GetNetwork(w http.ResponseWriter, r *http.Request) { 11 | utils.SetHeaders(w) 12 | rawData := network.GetNetwork() 13 | jsonData, _ := json.Marshal(rawData) 14 | 15 | w.Write(jsonData) 16 | } 17 | -------------------------------------------------------------------------------- /api/machine/osinfo.go: -------------------------------------------------------------------------------- 1 | package machine 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | "statee/api/utils" 7 | "statee/machine/osinfo" 8 | ) 9 | 10 | func GetOsInfo(w http.ResponseWriter, r *http.Request) { 11 | utils.SetHeaders(w) 12 | rawData := osinfo.GetOsInfo() 13 | jsonData, _ := json.Marshal(rawData) 14 | 15 | w.Write(jsonData) 16 | } 17 | -------------------------------------------------------------------------------- /api/machine/processes.go: -------------------------------------------------------------------------------- 1 | package machine 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | "statee/api/utils" 7 | "statee/machine/processes" 8 | ) 9 | 10 | func GetProcesses(w http.ResponseWriter, r *http.Request) { 11 | utils.SetHeaders(w) 12 | rawData := processes.GetProcesses() 13 | jsonData, _ := json.Marshal(rawData) 14 | 15 | w.Write(jsonData) 16 | } 17 | -------------------------------------------------------------------------------- /api/machine/storage.go: -------------------------------------------------------------------------------- 1 | package machine 2 | 3 | import ( 4 | "encoding/json" 5 | "net/http" 6 | "statee/api/utils" 7 | "statee/machine/storage" 8 | ) 9 | 10 | func GetStorage(w http.ResponseWriter, r *http.Request) { 11 | utils.SetHeaders(w) 12 | rawData := storage.GetDisks() 13 | jsonData, _ := json.Marshal(rawData) 14 | 15 | w.Write(jsonData) 16 | } 17 | -------------------------------------------------------------------------------- /api/utils/headers.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import "net/http" 4 | 5 | func SetHeaders(w http.ResponseWriter) { 6 | w.Header().Set("Content-Type", "application/json") 7 | w.Header().Set("Access-Control-Allow-Origin", "*") 8 | } 9 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module statee 2 | 3 | go 1.21.2 4 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dani3l0/Statee/c143d8e489fa25451d06ff7a63e7cda4542992fc/go.sum -------------------------------------------------------------------------------- /machine/README.md: -------------------------------------------------------------------------------- 1 | # Statee internal APIs 2 | 3 | The 'core' part being entirely responsible for fetching hardware information. 4 | Designed to be easy and simple, yet verbose and scalable. 5 | 6 | Can be used as an independent module. 7 | 8 | 9 | 10 | ## Special values 11 | 12 | - **`-127` - unknown number**; returned when value couldn't be fetched or parsed properly due to an internal error; sometimes such behaviour is expected 13 | 14 | 15 | 16 | ## Structure 17 | 18 | Each directory is responsible for different hardware parts, and is independent. 19 | Apart from all helper functions, which are localed inside `utils`. 20 | -------------------------------------------------------------------------------- /machine/cpu/cpu.go: -------------------------------------------------------------------------------- 1 | package cpu 2 | 3 | import ( 4 | "statee/machine/utils" 5 | "strings" 6 | ) 7 | 8 | type Cpu struct { 9 | Model string 10 | Cores int 11 | Threads int 12 | Cache int 13 | Flags []string 14 | Usage []Usage 15 | } 16 | 17 | // Main function, get all cpu information 18 | func GetCpu() Cpu { 19 | var cpu Cpu 20 | 21 | // Basic info 22 | cpuinfo, _ := utils.Cat("/proc/cpuinfo") 23 | cpu.Model, _ = utils.Grep(cpuinfo, "model name") 24 | cpu.Cache, _ = utils.GrepInt(cpuinfo, "cache size") 25 | 26 | // Flags & capabilities 27 | _flags, _ := utils.Grep(cpuinfo, "flags") 28 | flags := strings.Fields(_flags) 29 | selected_flags := "avx avx2 avx512f aes vmx ht svm smt" 30 | for _, flag := range flags { 31 | if strings.Contains(selected_flags, flag) { 32 | cpu.Flags = append(cpu.Flags, flag) 33 | } 34 | } 35 | 36 | // Load, temperatures, frequencies per each thread/core 37 | cpu.Usage = GetUsage() 38 | cpu.Threads = len(cpu.Usage) 39 | cores := 0 40 | for _, v := range cpu.Usage { 41 | if v.Core > cores { 42 | cores = v.Core 43 | } 44 | } 45 | cpu.Cores = 1 + cores 46 | 47 | return cpu 48 | } 49 | -------------------------------------------------------------------------------- /machine/cpu/stat.go: -------------------------------------------------------------------------------- 1 | package cpu 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | // Stat line 9 | // cpu[x](0) user(1) nice{2} system(3) idle(4) iowait(5) irq(6) softirq(7) steal(8) guest(9) 10 | // cpu5 13184 3 3630 405391 160 759 326 0 0 11 | 12 | // {"cpu0": [27424, 3228]} etc. 13 | var statCache = make(map[string][]int) 14 | 15 | func getLoadFor(stat string, cpuId int) float32 { 16 | for _, line := range strings.Split(stat, "\n") { 17 | fields := strings.Fields(line) 18 | name := fields[0] 19 | if len(fields) > 0 && name == "cpu"+strconv.Itoa(cpuId) { 20 | idle := statDiff(name, 0, atoi(fields[4])) 21 | load := statDiff(name, 1, statUsed(fields)) 22 | total := idle + load 23 | return 100.0 * float32(load) / float32(total) 24 | } 25 | } 26 | return -127 27 | } 28 | 29 | // Auto-compute difference between current and previous results 30 | // for live data 31 | // Sum stat fields considered as an actual load 32 | func statDiff(cpuName string, mapId int, newValue int) int { 33 | if _, ok := statCache[cpuName]; !ok { 34 | statCache[cpuName] = []int{0, 0} 35 | } 36 | sth := newValue 37 | sthLast := statCache[cpuName][mapId] 38 | sthDiff := sth - sthLast 39 | statCache[cpuName][mapId] = sth 40 | return sthDiff 41 | } 42 | 43 | // Sum stat fields considered as an actual load 44 | func statUsed(fields []string) int { 45 | used := 0 46 | used += atoi(fields[1]) 47 | used += atoi(fields[2]) 48 | used += atoi(fields[3]) 49 | used += atoi(fields[6]) 50 | used += atoi(fields[7]) 51 | return used 52 | } 53 | 54 | func atoi(a string) int { 55 | i, err := strconv.Atoi(a) 56 | if err != nil { 57 | return 0 58 | } 59 | return i 60 | } 61 | -------------------------------------------------------------------------------- /machine/cpu/thermal.go: -------------------------------------------------------------------------------- 1 | package cpu 2 | 3 | import ( 4 | "os" 5 | "path" 6 | "regexp" 7 | "statee/machine/utils" 8 | "strings" 9 | ) 10 | 11 | // Some data structs 12 | type coretemp struct { 13 | Temp float32 14 | Melt float32 15 | } 16 | type coretemps struct { 17 | Ok bool 18 | PerCore bool 19 | Temps map[string]coretemp 20 | } 21 | 22 | // Gets CPU temperature for each core 23 | func getCoretemps() coretemps { 24 | result := coretemps{} 25 | hwpath := "/sys/class/hwmon" 26 | hwmons, _ := os.ReadDir(hwpath) 27 | found := "" 28 | 29 | // Find proper hwmon id for CPU 30 | for _, hwmon := range hwmons { 31 | p := path.Join(hwpath, hwmon.Name()) 32 | name, err := utils.Cat(p, "name") 33 | if err != nil || name != "coretemp" { 34 | continue 35 | } 36 | found = p 37 | break 38 | } 39 | 40 | if found == "" { 41 | return result 42 | } 43 | 44 | pattern := regexp.MustCompile(`^Core \d+$`) 45 | result.Temps = make(map[string]coretemp) 46 | sensors, _ := os.ReadDir(found) 47 | 48 | // Read temperatures, core by core 49 | for _, v := range sensors { 50 | _name := v.Name() 51 | name := strings.Split(_name, "_") 52 | if len(name) != 2 || name[1] != "label" { 53 | continue 54 | } 55 | label, _ := utils.Cat(found, _name) 56 | if !pattern.MatchString(label) { 57 | continue 58 | } 59 | result.Ok = true 60 | result.PerCore = true 61 | temp_raw, _ := utils.CatInt(found, name[0]+"_input") 62 | melt_raw, _ := utils.CatInt(found, name[0]+"_crit") 63 | key := strings.Replace(label, "Core ", "", 1) 64 | result.Temps[key] = coretemp{ 65 | Temp: float32(temp_raw) / 1000, 66 | Melt: float32(melt_raw) / 1000, 67 | } 68 | } 69 | 70 | return result 71 | } 72 | -------------------------------------------------------------------------------- /machine/cpu/usage.go: -------------------------------------------------------------------------------- 1 | package cpu 2 | 3 | import ( 4 | "os" 5 | "path" 6 | "regexp" 7 | "sort" 8 | "statee/machine/utils" 9 | "strconv" 10 | "strings" 11 | ) 12 | 13 | type Usage struct { 14 | Id int 15 | Core int 16 | Load float32 17 | Online bool 18 | Freq int 19 | BaseFreq int 20 | MinFreq int 21 | MaxFreq int 22 | Temp float32 23 | Melt float32 24 | } 25 | 26 | // Gets information for all cores for one cpu 27 | func GetUsage() []Usage { 28 | usage := []Usage{} 29 | pattern := regexp.MustCompile(`^cpu\d+$`) 30 | stat, _ := utils.Cat("/proc/stat") 31 | sys := "/sys/devices/system/cpu" 32 | cpus, _ := os.ReadDir(sys) 33 | 34 | temps := getCoretemps() 35 | 36 | for _, v := range cpus { 37 | // Check if dir is named 'cpu[x]' 38 | name := v.Name() 39 | if !pattern.MatchString(name) { 40 | continue 41 | } 42 | 43 | // Runtime parameters 44 | u := Usage{} 45 | x := path.Join(sys, name) 46 | 47 | id := strings.Replace(name, "cpu", "", 1) 48 | u.Id = atoi(id) 49 | online, _ := utils.CatInt(x, "online") 50 | u.Online = online != 0 51 | 52 | // Online CPUs stuff 53 | if u.Online { 54 | u.Core, _ = utils.CatInt(x, "topology/core_id") 55 | u.Load = getLoadFor(stat, u.Id) 56 | 57 | // Frequencies 58 | u.Freq, _ = utils.CatInt(x, "cpufreq/scaling_cur_freq") 59 | u.BaseFreq, _ = utils.CatInt(x, "cpufreq/base_frequency") 60 | u.MinFreq, _ = utils.CatInt(x, "cpufreq/scaling_min_freq") 61 | u.MaxFreq, _ = utils.CatInt(x, "cpufreq/scaling_max_freq") 62 | u.Freq /= 1000 63 | u.BaseFreq /= 1000 64 | u.MinFreq /= 1000 65 | u.MaxFreq /= 1000 66 | u.Temp = temps.Temps[strconv.Itoa(u.Core)].Temp 67 | u.Melt = temps.Temps[strconv.Itoa(u.Core)].Melt 68 | } 69 | 70 | usage = append(usage, u) 71 | } 72 | 73 | // Sort ascending by Id 74 | sort.Slice(usage, func(i, j int) bool { 75 | return usage[i].Id < usage[j].Id 76 | }) 77 | 78 | return usage 79 | } 80 | -------------------------------------------------------------------------------- /machine/memory/memory.go: -------------------------------------------------------------------------------- 1 | package memory 2 | 3 | import utils "statee/machine/utils" 4 | 5 | type Memory struct { 6 | Available int 7 | Cached int 8 | Total int 9 | SwapAvailable int 10 | SwapTotal int 11 | } 12 | 13 | // Parse meminfo 14 | func GetMemory() Memory { 15 | var memory Memory 16 | meminfo, _ := utils.Cat("/proc/meminfo") 17 | 18 | // RAM 19 | mem_available, _ := utils.GrepInt(meminfo, "MemAvailable") 20 | memory.Available = mem_available * 1024 / 1000 21 | mem_cached, _ := utils.GrepInt(meminfo, "Cached") 22 | memory.Cached = mem_cached * 1024 / 1000 23 | mem_total, _ := utils.GrepInt(meminfo, "MemTotal") 24 | memory.Total = mem_total * 1024 / 1000 25 | 26 | // Swap or zram 27 | swap_total, _ := utils.GrepInt(meminfo, "SwapTotal") 28 | swap_free, _ := utils.GrepInt(meminfo, "SwapFree") 29 | memory.SwapTotal = swap_total * 1024 / 1000 30 | memory.SwapAvailable = swap_free * 1024 / 1000 31 | 32 | return memory 33 | } 34 | -------------------------------------------------------------------------------- /machine/network/network.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | import ( 4 | "os" 5 | "path" 6 | "statee/machine/utils" 7 | "strings" 8 | ) 9 | 10 | var NET_PATH = "/sys/class/net" 11 | 12 | type Interface struct { 13 | Rx int 14 | Tx int 15 | Speed int 16 | MacAddress string 17 | Wired bool 18 | Enabled bool 19 | } 20 | 21 | // Find all interfaces and fetch information 22 | func GetNetwork() map[string]Interface { 23 | interfaces := make(map[string]Interface) 24 | ifaces, _ := os.ReadDir(NET_PATH) 25 | 26 | for _, x := range ifaces { 27 | name := x.Name() 28 | 29 | ignored := name == "lo" || // loopback 30 | strings.HasPrefix(name, "docker") || // docker 31 | strings.HasPrefix(name, "veth") || // virtual 32 | strings.HasPrefix(name, "virt") || // virtual 33 | strings.HasPrefix(name, "br") // bridge 34 | 35 | if ignored { 36 | continue 37 | } 38 | interfaces[name] = GetInterface(name) 39 | } 40 | return interfaces 41 | } 42 | 43 | // Get specified interface information 44 | func GetInterface(name string) Interface { 45 | rx, _ := utils.CatInt(NET_PATH, name, "statistics/rx_bytes") 46 | tx, _ := utils.CatInt(NET_PATH, name, "statistics/tx_bytes") 47 | speed, _ := utils.CatInt(NET_PATH, name, "speed") 48 | mac_address, _ := utils.Cat(NET_PATH, name, "address") 49 | _, wireless := os.Stat(path.Join(NET_PATH, name, "wireless")) 50 | state, _ := utils.Cat(NET_PATH, name, "operstate") 51 | 52 | return Interface{ 53 | Rx: rx, 54 | Tx: tx, 55 | Speed: speed, 56 | MacAddress: mac_address, 57 | Wired: wireless != nil, 58 | Enabled: state == "up", 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /machine/osinfo/osinfo.go: -------------------------------------------------------------------------------- 1 | package osinfo 2 | 3 | import ( 4 | "runtime" 5 | "statee/machine/utils" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | type OsInfo struct { 11 | Name string 12 | Version string 13 | Hostname string 14 | Arch string 15 | Is64 bool 16 | Kernel string 17 | Uptime uint32 18 | LoadAvg []float32 19 | LoadAvgMax int 20 | } 21 | 22 | func GetOsInfo() OsInfo { 23 | osinfo := OsInfo{} 24 | 25 | // Gets distro name & version 26 | os_release, _ := utils.Cat("/etc/os-release") 27 | for _, line := range strings.Split(os_release, "\n") { 28 | line = strings.ReplaceAll(line, "\"", "") 29 | entry := strings.Split(line, "=") 30 | switch entry[0] { 31 | case "NAME": 32 | osinfo.Name = entry[1] 33 | case "VERSION_ID": 34 | osinfo.Version = entry[1] 35 | } 36 | } 37 | 38 | // Gets some other stuff 39 | osinfo.Hostname, _ = utils.Cat("/proc/sys/kernel/hostname") 40 | osinfo.Kernel, _ = utils.Cat("/proc/sys/kernel/osrelease") 41 | osinfo.Arch, _ = utils.Cat("/proc/sys/kernel/arch") 42 | osinfo.Is64 = strings.Contains(osinfo.Arch, "64") 43 | uptime_raw, _ := utils.Cat("/proc/uptime") 44 | uptime_tmp, _ := strconv.ParseFloat(strings.Fields(uptime_raw)[0], 64) 45 | osinfo.Uptime = uint32(uptime_tmp) 46 | 47 | // Gets loadavg 48 | loadavg_raw, _ := utils.Cat("/proc/loadavg") 49 | for i, entry := range strings.Fields(loadavg_raw) { 50 | if i == 3 { 51 | break 52 | } 53 | parsed, _ := strconv.ParseFloat(entry, 64) 54 | osinfo.LoadAvg = append(osinfo.LoadAvg, float32(parsed)) 55 | } 56 | osinfo.LoadAvgMax = runtime.NumCPU() 57 | 58 | // Return pretty info 59 | return osinfo 60 | } 61 | -------------------------------------------------------------------------------- /machine/processes/processes.go: -------------------------------------------------------------------------------- 1 | package processes 2 | 3 | import ( 4 | "os" 5 | "path" 6 | "statee/machine/utils" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | type Processes struct { 12 | Processes []Process 13 | } 14 | 15 | type Process struct { 16 | Name string 17 | Memory int 18 | Pid int 19 | Uid int 20 | } 21 | 22 | // Get information of a process with provided id 23 | func GetProcess(id int) (Process, error) { 24 | var process Process 25 | var err error 26 | raw, _ := utils.Cat(path.Join("/proc", strconv.Itoa(id), "status")) 27 | process.Name, err = utils.Grep(raw, "Name") 28 | if err != nil { 29 | return process, err 30 | } 31 | process.Name = strings.Trim(process.Name, "\t") 32 | process.Memory, err = utils.GrepInt(raw, "RssAnon") 33 | if err != nil { 34 | return process, err 35 | } 36 | process.Pid = id 37 | uid_raw, _ := utils.Grep(raw, "Uid") 38 | uid_raw = strings.Fields(uid_raw)[0] 39 | process.Uid, err = strconv.Atoi(uid_raw) 40 | return process, err 41 | } 42 | 43 | // List all PIDs 44 | func GetProcesses() Processes { 45 | var processes Processes 46 | proc, _ := os.ReadDir("/proc") 47 | for _, process_id := range proc { 48 | pid, err := strconv.Atoi(process_id.Name()) 49 | if err != nil { 50 | continue 51 | } 52 | process, err := GetProcess(pid) 53 | if err == nil { 54 | processes.Processes = append(processes.Processes, process) 55 | } 56 | } 57 | return processes 58 | } 59 | -------------------------------------------------------------------------------- /machine/storage/disk.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "os" 5 | "path" 6 | "statee/machine/utils" 7 | "strings" 8 | ) 9 | 10 | type Disk struct { 11 | Name string 12 | Model string 13 | Space int 14 | Removable bool 15 | ReadSpeed int 16 | WriteSpeed int 17 | IOPS int 18 | AvgResp int 19 | Partitions map[string]Partition 20 | } 21 | 22 | // Get disk with ids such as 'sda', 'sdb' 23 | func GetDisk(id string) (Disk, error) { 24 | var disk = Disk{} 25 | disk.Name = id 26 | pathTo := path.Join("/sys/block", id) 27 | 28 | // Disk parameters 29 | sectors, _ := utils.CatInt(pathTo, "size") 30 | sector_size, _ := utils.CatInt(pathTo, "queue/hw_sector_size") 31 | disk.Space = sectors * sector_size / 1000 32 | removable, _ := utils.CatInt(pathTo, "removable") 33 | disk.Removable = removable != 0 34 | disk.Model, _ = utils.Cat(pathTo, "device/model") 35 | 36 | // Available partitions 37 | parts, _ := os.ReadDir("/sys/class/block") 38 | disk.Partitions = make(map[string]Partition) 39 | for _, part := range parts { 40 | if strings.HasPrefix(part.Name(), id) && len(part.Name()) > len(id) { 41 | part_info, err := GetPartition(part.Name(), sector_size) 42 | if err != nil { 43 | continue 44 | } 45 | disk.Partitions[part.Name()] = part_info 46 | } 47 | } 48 | 49 | // IO Stats 50 | p := parseDiskStat(pathTo) 51 | disk.AvgResp = (p.ReadDelay + p.WriteDelay) / 2 52 | disk.ReadSpeed = p.ReadSectors * sector_size / 1000 53 | disk.WriteSpeed = p.WriteSectors * sector_size / 1000 54 | disk.IOPS = p.ReadIOPS + p.WriteIOPS 55 | return disk, nil 56 | } 57 | -------------------------------------------------------------------------------- /machine/storage/mounts.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "path" 5 | "statee/machine/utils" 6 | "strings" 7 | ) 8 | 9 | type Mount struct { 10 | Path string 11 | Mountpoint string 12 | Filesystem string 13 | } 14 | 15 | var systemMounts map[string]Mount 16 | 17 | func GetMounts() { 18 | mounts := map[string]Mount{} 19 | mounts_raw, _ := utils.Cat("/proc/mounts") 20 | 21 | // [0]/dev/nvme0n1p3 [1]/home [2]ext4 [3]rw,seclabel,relatime [4]0 [5]0 22 | for _, mnt_raw := range strings.Split(mounts_raw, "\n") { 23 | mount := strings.Fields(mnt_raw) 24 | if !strings.HasPrefix(mount[0], "/dev") { 25 | continue 26 | } 27 | mounts[path.Base(mount[0])] = Mount{ 28 | Path: mount[0], 29 | Mountpoint: mount[1], 30 | Filesystem: mount[2], 31 | } 32 | } 33 | 34 | systemMounts = mounts 35 | } 36 | -------------------------------------------------------------------------------- /machine/storage/partition.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "errors" 5 | "path" 6 | "statee/machine/utils" 7 | "strings" 8 | "syscall" 9 | ) 10 | 11 | type Partition struct { 12 | Name string 13 | Free int 14 | Total int 15 | Filesystem string 16 | Mountpoint string 17 | ReadOnly bool 18 | } 19 | 20 | // Get full info about specified partition 21 | func GetPartition(id string, sector_size int) (Partition, error) { 22 | partition := Partition{} 23 | pathTo := path.Join("/sys/class/block/", id) 24 | 25 | props, exists := systemMounts[id] 26 | if !exists { 27 | return partition, errors.New("no such partition") 28 | } 29 | 30 | // Space data 31 | statfs := syscall.Statfs_t{} 32 | syscall.Statfs(props.Mountpoint, &statfs) 33 | partition.Free = int(statfs.Bfree*uint64(statfs.Bsize)) / 1000 34 | partition.Total = int(statfs.Blocks*uint64(statfs.Bsize)) / 1000 35 | 36 | // If exists, fetch info about specified partition 37 | pretty_name := strings.ToTitle(path.Base(props.Mountpoint)) 38 | partition.Name = pretty_name 39 | partition.Mountpoint = props.Mountpoint 40 | partition.Filesystem = props.Filesystem 41 | ro, _ := utils.CatInt(pathTo, "ro") 42 | partition.ReadOnly = ro == 1 43 | 44 | return partition, nil 45 | } 46 | -------------------------------------------------------------------------------- /machine/storage/stat.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "statee/machine/utils" 5 | "strconv" 6 | "strings" 7 | "time" 8 | ) 9 | 10 | type DiskStat struct { 11 | ReadIOPS int 12 | WriteIOPS int 13 | ReadSectors int 14 | WriteSectors int 15 | ReadDelay int 16 | WriteDelay int 17 | } 18 | 19 | type DiskStatHist struct { 20 | Now DiskStat 21 | Last DiskStat 22 | TimeLast time.Time 23 | } 24 | 25 | var statsHist DiskStatHist 26 | 27 | // @TODO: last data timestamp and diff calculation 28 | // to provide value accurately 29 | func parseDiskStat(path string) DiskStat { 30 | var result DiskStat 31 | stats := DiskStat{} 32 | contents, _ := utils.Cat(path, "stat") 33 | values := strings.Fields(contents) 34 | time_diff := time.Since(statsHist.TimeLast).Seconds() 35 | 36 | // IOPS 37 | readIOPS, _ := strconv.Atoi(values[0]) 38 | stats.ReadIOPS = readIOPS 39 | result.ReadIOPS = perSecond((readIOPS - statsHist.Last.ReadIOPS), time_diff) 40 | writeIOPS, _ := strconv.Atoi(values[4]) 41 | stats.WriteIOPS = writeIOPS 42 | result.WriteIOPS = perSecond((writeIOPS - statsHist.Last.WriteIOPS), time_diff) 43 | 44 | // RW Speed 45 | readSectors, _ := strconv.Atoi(values[2]) 46 | stats.ReadSectors = readSectors 47 | result.ReadSectors = perSecond((readSectors - statsHist.Last.ReadSectors), time_diff) 48 | writeSectors, _ := strconv.Atoi(values[6]) 49 | stats.WriteSectors = writeSectors 50 | stats.WriteSectors = perSecond((writeSectors - statsHist.Last.WriteSectors), time_diff) 51 | 52 | // Response time 53 | readDelay, _ := strconv.Atoi(values[3]) 54 | stats.ReadDelay = readDelay 55 | result.ReadDelay = perSecond((readDelay - statsHist.Last.ReadDelay), time_diff) 56 | writeDelay, _ := strconv.Atoi(values[7]) 57 | stats.WriteDelay = writeDelay 58 | result.WriteDelay = perSecond((writeDelay - statsHist.Last.WriteDelay), time_diff) 59 | 60 | // Update cache 61 | statsHist.Last = statsHist.Now 62 | statsHist.TimeLast = time.Now() 63 | statsHist.Now = stats 64 | 65 | return result 66 | } 67 | 68 | func perSecond(raw_value int, seconds float64) int { 69 | return int(float64(raw_value) / seconds) 70 | } 71 | -------------------------------------------------------------------------------- /machine/storage/storage.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | import ( 4 | "os" 5 | "strings" 6 | ) 7 | 8 | // Only those devices are considered physical disks 9 | var whitelist = []string{ 10 | "nvme", // NVMe drives (nvme0n1, nvme0n2, ...) 11 | "sd", // SATA, SCSI, USB drives (sda, sdb, ...) 12 | "mmcblk", // SD Cards, eMMCs, etc. (mmcblk0, mmcblk1, ...) 13 | "vd", // QEMU virtual disk devices (vda, vdb, ...) 14 | } 15 | 16 | // Find all appropriate disks 17 | func GetDisks() []Disk { 18 | disks := []Disk{} 19 | devices, _ := os.ReadDir("/sys/block") 20 | GetMounts() 21 | 22 | for _, v := range devices { 23 | x := v.Name() 24 | for _, y := range whitelist { 25 | if strings.HasPrefix(x, y) { 26 | disk, err := GetDisk(x) 27 | if err != nil { 28 | continue 29 | } 30 | disks = append(disks, disk) 31 | } 32 | } 33 | } 34 | 35 | return disks 36 | } 37 | -------------------------------------------------------------------------------- /machine/utils/cat.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "os" 5 | "path" 6 | "regexp" 7 | "strconv" 8 | "strings" 9 | ) 10 | 11 | // Directly reads and trims string from fire 12 | func Cat(target ...string) (string, error) { 13 | rawdata, err := os.ReadFile(path.Join(target...)) 14 | if err != nil { 15 | return "", err 16 | } 17 | data := string(rawdata) 18 | data = strings.Trim(data, "\n") 19 | data = strings.Trim(data, " ") 20 | return string(data), nil 21 | } 22 | 23 | // Uses the above function and converts result to integer 24 | func CatInt(target ...string) (int, error) { 25 | wtf, _ := regexp.Compile("[^0-9]+") 26 | data, err := Cat(target...) 27 | if err != nil { 28 | return -127, err 29 | } 30 | 31 | data = wtf.ReplaceAllString(data, "") 32 | number, err := strconv.Atoi(data) 33 | if err != nil { 34 | return -127, err 35 | } 36 | 37 | return number, nil 38 | } 39 | -------------------------------------------------------------------------------- /machine/utils/grep.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "errors" 5 | "regexp" 6 | "strconv" 7 | "strings" 8 | ) 9 | 10 | // Finds multiple values for specified key 11 | // For 'key: value' line returns just value 12 | func Greps(contents string, find string) ([]string, error) { 13 | var found_values []string 14 | splits := strings.Split(contents, "\n") 15 | 16 | for _, v := range splits { 17 | if strings.Contains(v, find) { 18 | v = strings.Split(v, ":")[1] 19 | v = strings.Trim(v, " ") 20 | found_values = append(found_values, v) 21 | } 22 | } 23 | 24 | if len(found_values) == 0 { 25 | return found_values, errors.New("greps: no occurences found") 26 | } 27 | 28 | return found_values, nil 29 | } 30 | 31 | // Same as above, but converts values to integers 32 | func GrepsInt(contents string, find string) ([]int, error) { 33 | text, err := Greps(contents, find) 34 | wtf, _ := regexp.Compile("[^0-9]+") 35 | var ints []int 36 | 37 | if err != nil { 38 | return ints, err 39 | } 40 | 41 | for _, v := range text { 42 | str := wtf.ReplaceAllString(v, "") 43 | numeric, err := strconv.Atoi(str) 44 | if err == nil { 45 | ints = append(ints, numeric) 46 | } 47 | } 48 | 49 | if len(ints) == 0 { 50 | err = errors.New("greps: no ints found") 51 | } 52 | 53 | return ints, err 54 | } 55 | 56 | // Same as Greps, but returns only first occurence 57 | func Grep(contents string, find string) (string, error) { 58 | result, err := Greps(contents, find) 59 | if err != nil { 60 | return "", err 61 | } 62 | return result[0], nil 63 | } 64 | 65 | // Same as GrepsInt, but return only first occurence 66 | func GrepInt(contents string, find string) (int, error) { 67 | result, err := GrepsInt(contents, find) 68 | if err != nil { 69 | return -127, err 70 | } 71 | return result[0], nil 72 | } 73 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "statee/api/machine" 7 | ) 8 | 9 | func main() { 10 | http.HandleFunc("/api/cpu", machine.GetCpu) 11 | http.HandleFunc("/api/memory", machine.GetMemory) 12 | http.HandleFunc("/api/storage", machine.GetStorage) 13 | http.HandleFunc("/api/network", machine.GetNetwork) 14 | http.HandleFunc("/api/osinfo", machine.GetOsInfo) 15 | http.HandleFunc("/api/processes", machine.GetProcesses) 16 | 17 | listen_addr := ":9090" 18 | fmt.Println("Running on " + listen_addr) 19 | http.ListenAndServe(listen_addr, nil) 20 | } 21 | -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /web/README.md: -------------------------------------------------------------------------------- 1 | # Svelte + Vite 2 | 3 | This template should help get you started developing with Svelte in Vite. 4 | 5 | ## Recommended IDE Setup 6 | 7 | [VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). 8 | 9 | ## Need an official Svelte framework? 10 | 11 | Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. 12 | 13 | ## Technical considerations 14 | 15 | **Why use this over SvelteKit?** 16 | 17 | - It brings its own routing solution which might not be preferable for some users. 18 | - It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. 19 | 20 | This template contains as little as possible to get started with Vite + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. 21 | 22 | Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. 23 | 24 | **Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** 25 | 26 | Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. 27 | 28 | **Why include `.vscode/extensions.json`?** 29 | 30 | Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. 31 | 32 | **Why enable `checkJs` in the JS template?** 33 | 34 | It is likely that most cases of changing variable types in runtime are likely to be accidental, rather than deliberate. This provides advanced typechecking out of the box. Should you like to take advantage of the dynamically-typed nature of JavaScript, it is trivial to change the configuration. 35 | 36 | **Why is HMR not preserving my local component state?** 37 | 38 | HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/sveltejs/svelte-hmr/tree/master/packages/svelte-hmr#preservation-of-local-state). 39 | 40 | If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. 41 | 42 | ```js 43 | // store.js 44 | // An extremely simple external store 45 | import { writable } from 'svelte/store' 46 | export default writable(0) 47 | ``` 48 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /web/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "bundler", 4 | "target": "ESNext", 5 | "module": "ESNext", 6 | /** 7 | * svelte-preprocess cannot figure out whether you have 8 | * a value or a type, so tell TypeScript to enforce using 9 | * `import type` instead of `import` for Types. 10 | */ 11 | "verbatimModuleSyntax": true, 12 | "isolatedModules": true, 13 | "resolveJsonModule": true, 14 | /** 15 | * To have warnings / errors of the Svelte compiler at the 16 | * correct position, enable source maps by default. 17 | */ 18 | "sourceMap": true, 19 | "esModuleInterop": true, 20 | "skipLibCheck": true, 21 | /** 22 | * Typecheck JS in `.svelte` and `.js` files by default. 23 | * Disable this if you'd like to use dynamic types. 24 | */ 25 | "checkJs": true 26 | }, 27 | /** 28 | * Use global.d.ts instead of compilerOptions.types 29 | * to avoid limiting type declarations. 30 | */ 31 | "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"] 32 | } 33 | -------------------------------------------------------------------------------- /web/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web", 3 | "version": "0.0.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "web", 9 | "version": "0.0.0", 10 | "devDependencies": { 11 | "@sveltejs/vite-plugin-svelte": "^3.0.2", 12 | "svelte": "^4.2.12", 13 | "vite": "^5.2.0" 14 | } 15 | }, 16 | "node_modules/@ampproject/remapping": { 17 | "version": "2.3.0", 18 | "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", 19 | "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", 20 | "dev": true, 21 | "dependencies": { 22 | "@jridgewell/gen-mapping": "^0.3.5", 23 | "@jridgewell/trace-mapping": "^0.3.24" 24 | }, 25 | "engines": { 26 | "node": ">=6.0.0" 27 | } 28 | }, 29 | "node_modules/@esbuild/aix-ppc64": { 30 | "version": "0.20.2", 31 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", 32 | "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", 33 | "cpu": [ 34 | "ppc64" 35 | ], 36 | "dev": true, 37 | "optional": true, 38 | "os": [ 39 | "aix" 40 | ], 41 | "engines": { 42 | "node": ">=12" 43 | } 44 | }, 45 | "node_modules/@esbuild/android-arm": { 46 | "version": "0.20.2", 47 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", 48 | "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", 49 | "cpu": [ 50 | "arm" 51 | ], 52 | "dev": true, 53 | "optional": true, 54 | "os": [ 55 | "android" 56 | ], 57 | "engines": { 58 | "node": ">=12" 59 | } 60 | }, 61 | "node_modules/@esbuild/android-arm64": { 62 | "version": "0.20.2", 63 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", 64 | "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", 65 | "cpu": [ 66 | "arm64" 67 | ], 68 | "dev": true, 69 | "optional": true, 70 | "os": [ 71 | "android" 72 | ], 73 | "engines": { 74 | "node": ">=12" 75 | } 76 | }, 77 | "node_modules/@esbuild/android-x64": { 78 | "version": "0.20.2", 79 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", 80 | "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", 81 | "cpu": [ 82 | "x64" 83 | ], 84 | "dev": true, 85 | "optional": true, 86 | "os": [ 87 | "android" 88 | ], 89 | "engines": { 90 | "node": ">=12" 91 | } 92 | }, 93 | "node_modules/@esbuild/darwin-arm64": { 94 | "version": "0.20.2", 95 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", 96 | "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", 97 | "cpu": [ 98 | "arm64" 99 | ], 100 | "dev": true, 101 | "optional": true, 102 | "os": [ 103 | "darwin" 104 | ], 105 | "engines": { 106 | "node": ">=12" 107 | } 108 | }, 109 | "node_modules/@esbuild/darwin-x64": { 110 | "version": "0.20.2", 111 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", 112 | "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", 113 | "cpu": [ 114 | "x64" 115 | ], 116 | "dev": true, 117 | "optional": true, 118 | "os": [ 119 | "darwin" 120 | ], 121 | "engines": { 122 | "node": ">=12" 123 | } 124 | }, 125 | "node_modules/@esbuild/freebsd-arm64": { 126 | "version": "0.20.2", 127 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", 128 | "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", 129 | "cpu": [ 130 | "arm64" 131 | ], 132 | "dev": true, 133 | "optional": true, 134 | "os": [ 135 | "freebsd" 136 | ], 137 | "engines": { 138 | "node": ">=12" 139 | } 140 | }, 141 | "node_modules/@esbuild/freebsd-x64": { 142 | "version": "0.20.2", 143 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", 144 | "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", 145 | "cpu": [ 146 | "x64" 147 | ], 148 | "dev": true, 149 | "optional": true, 150 | "os": [ 151 | "freebsd" 152 | ], 153 | "engines": { 154 | "node": ">=12" 155 | } 156 | }, 157 | "node_modules/@esbuild/linux-arm": { 158 | "version": "0.20.2", 159 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", 160 | "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", 161 | "cpu": [ 162 | "arm" 163 | ], 164 | "dev": true, 165 | "optional": true, 166 | "os": [ 167 | "linux" 168 | ], 169 | "engines": { 170 | "node": ">=12" 171 | } 172 | }, 173 | "node_modules/@esbuild/linux-arm64": { 174 | "version": "0.20.2", 175 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", 176 | "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", 177 | "cpu": [ 178 | "arm64" 179 | ], 180 | "dev": true, 181 | "optional": true, 182 | "os": [ 183 | "linux" 184 | ], 185 | "engines": { 186 | "node": ">=12" 187 | } 188 | }, 189 | "node_modules/@esbuild/linux-ia32": { 190 | "version": "0.20.2", 191 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", 192 | "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", 193 | "cpu": [ 194 | "ia32" 195 | ], 196 | "dev": true, 197 | "optional": true, 198 | "os": [ 199 | "linux" 200 | ], 201 | "engines": { 202 | "node": ">=12" 203 | } 204 | }, 205 | "node_modules/@esbuild/linux-loong64": { 206 | "version": "0.20.2", 207 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", 208 | "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", 209 | "cpu": [ 210 | "loong64" 211 | ], 212 | "dev": true, 213 | "optional": true, 214 | "os": [ 215 | "linux" 216 | ], 217 | "engines": { 218 | "node": ">=12" 219 | } 220 | }, 221 | "node_modules/@esbuild/linux-mips64el": { 222 | "version": "0.20.2", 223 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", 224 | "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", 225 | "cpu": [ 226 | "mips64el" 227 | ], 228 | "dev": true, 229 | "optional": true, 230 | "os": [ 231 | "linux" 232 | ], 233 | "engines": { 234 | "node": ">=12" 235 | } 236 | }, 237 | "node_modules/@esbuild/linux-ppc64": { 238 | "version": "0.20.2", 239 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", 240 | "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", 241 | "cpu": [ 242 | "ppc64" 243 | ], 244 | "dev": true, 245 | "optional": true, 246 | "os": [ 247 | "linux" 248 | ], 249 | "engines": { 250 | "node": ">=12" 251 | } 252 | }, 253 | "node_modules/@esbuild/linux-riscv64": { 254 | "version": "0.20.2", 255 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", 256 | "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", 257 | "cpu": [ 258 | "riscv64" 259 | ], 260 | "dev": true, 261 | "optional": true, 262 | "os": [ 263 | "linux" 264 | ], 265 | "engines": { 266 | "node": ">=12" 267 | } 268 | }, 269 | "node_modules/@esbuild/linux-s390x": { 270 | "version": "0.20.2", 271 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", 272 | "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", 273 | "cpu": [ 274 | "s390x" 275 | ], 276 | "dev": true, 277 | "optional": true, 278 | "os": [ 279 | "linux" 280 | ], 281 | "engines": { 282 | "node": ">=12" 283 | } 284 | }, 285 | "node_modules/@esbuild/linux-x64": { 286 | "version": "0.20.2", 287 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", 288 | "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", 289 | "cpu": [ 290 | "x64" 291 | ], 292 | "dev": true, 293 | "optional": true, 294 | "os": [ 295 | "linux" 296 | ], 297 | "engines": { 298 | "node": ">=12" 299 | } 300 | }, 301 | "node_modules/@esbuild/netbsd-x64": { 302 | "version": "0.20.2", 303 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", 304 | "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", 305 | "cpu": [ 306 | "x64" 307 | ], 308 | "dev": true, 309 | "optional": true, 310 | "os": [ 311 | "netbsd" 312 | ], 313 | "engines": { 314 | "node": ">=12" 315 | } 316 | }, 317 | "node_modules/@esbuild/openbsd-x64": { 318 | "version": "0.20.2", 319 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", 320 | "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", 321 | "cpu": [ 322 | "x64" 323 | ], 324 | "dev": true, 325 | "optional": true, 326 | "os": [ 327 | "openbsd" 328 | ], 329 | "engines": { 330 | "node": ">=12" 331 | } 332 | }, 333 | "node_modules/@esbuild/sunos-x64": { 334 | "version": "0.20.2", 335 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", 336 | "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", 337 | "cpu": [ 338 | "x64" 339 | ], 340 | "dev": true, 341 | "optional": true, 342 | "os": [ 343 | "sunos" 344 | ], 345 | "engines": { 346 | "node": ">=12" 347 | } 348 | }, 349 | "node_modules/@esbuild/win32-arm64": { 350 | "version": "0.20.2", 351 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", 352 | "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", 353 | "cpu": [ 354 | "arm64" 355 | ], 356 | "dev": true, 357 | "optional": true, 358 | "os": [ 359 | "win32" 360 | ], 361 | "engines": { 362 | "node": ">=12" 363 | } 364 | }, 365 | "node_modules/@esbuild/win32-ia32": { 366 | "version": "0.20.2", 367 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", 368 | "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", 369 | "cpu": [ 370 | "ia32" 371 | ], 372 | "dev": true, 373 | "optional": true, 374 | "os": [ 375 | "win32" 376 | ], 377 | "engines": { 378 | "node": ">=12" 379 | } 380 | }, 381 | "node_modules/@esbuild/win32-x64": { 382 | "version": "0.20.2", 383 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", 384 | "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", 385 | "cpu": [ 386 | "x64" 387 | ], 388 | "dev": true, 389 | "optional": true, 390 | "os": [ 391 | "win32" 392 | ], 393 | "engines": { 394 | "node": ">=12" 395 | } 396 | }, 397 | "node_modules/@jridgewell/gen-mapping": { 398 | "version": "0.3.5", 399 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", 400 | "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", 401 | "dev": true, 402 | "dependencies": { 403 | "@jridgewell/set-array": "^1.2.1", 404 | "@jridgewell/sourcemap-codec": "^1.4.10", 405 | "@jridgewell/trace-mapping": "^0.3.24" 406 | }, 407 | "engines": { 408 | "node": ">=6.0.0" 409 | } 410 | }, 411 | "node_modules/@jridgewell/resolve-uri": { 412 | "version": "3.1.2", 413 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 414 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 415 | "dev": true, 416 | "engines": { 417 | "node": ">=6.0.0" 418 | } 419 | }, 420 | "node_modules/@jridgewell/set-array": { 421 | "version": "1.2.1", 422 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", 423 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 424 | "dev": true, 425 | "engines": { 426 | "node": ">=6.0.0" 427 | } 428 | }, 429 | "node_modules/@jridgewell/sourcemap-codec": { 430 | "version": "1.4.15", 431 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 432 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 433 | "dev": true 434 | }, 435 | "node_modules/@jridgewell/trace-mapping": { 436 | "version": "0.3.25", 437 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 438 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 439 | "dev": true, 440 | "dependencies": { 441 | "@jridgewell/resolve-uri": "^3.1.0", 442 | "@jridgewell/sourcemap-codec": "^1.4.14" 443 | } 444 | }, 445 | "node_modules/@rollup/rollup-android-arm-eabi": { 446 | "version": "4.17.2", 447 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", 448 | "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", 449 | "cpu": [ 450 | "arm" 451 | ], 452 | "dev": true, 453 | "optional": true, 454 | "os": [ 455 | "android" 456 | ] 457 | }, 458 | "node_modules/@rollup/rollup-android-arm64": { 459 | "version": "4.17.2", 460 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", 461 | "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", 462 | "cpu": [ 463 | "arm64" 464 | ], 465 | "dev": true, 466 | "optional": true, 467 | "os": [ 468 | "android" 469 | ] 470 | }, 471 | "node_modules/@rollup/rollup-darwin-arm64": { 472 | "version": "4.17.2", 473 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", 474 | "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", 475 | "cpu": [ 476 | "arm64" 477 | ], 478 | "dev": true, 479 | "optional": true, 480 | "os": [ 481 | "darwin" 482 | ] 483 | }, 484 | "node_modules/@rollup/rollup-darwin-x64": { 485 | "version": "4.17.2", 486 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", 487 | "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", 488 | "cpu": [ 489 | "x64" 490 | ], 491 | "dev": true, 492 | "optional": true, 493 | "os": [ 494 | "darwin" 495 | ] 496 | }, 497 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 498 | "version": "4.17.2", 499 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", 500 | "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", 501 | "cpu": [ 502 | "arm" 503 | ], 504 | "dev": true, 505 | "optional": true, 506 | "os": [ 507 | "linux" 508 | ] 509 | }, 510 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 511 | "version": "4.17.2", 512 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", 513 | "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", 514 | "cpu": [ 515 | "arm" 516 | ], 517 | "dev": true, 518 | "optional": true, 519 | "os": [ 520 | "linux" 521 | ] 522 | }, 523 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 524 | "version": "4.17.2", 525 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", 526 | "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", 527 | "cpu": [ 528 | "arm64" 529 | ], 530 | "dev": true, 531 | "optional": true, 532 | "os": [ 533 | "linux" 534 | ] 535 | }, 536 | "node_modules/@rollup/rollup-linux-arm64-musl": { 537 | "version": "4.17.2", 538 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", 539 | "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", 540 | "cpu": [ 541 | "arm64" 542 | ], 543 | "dev": true, 544 | "optional": true, 545 | "os": [ 546 | "linux" 547 | ] 548 | }, 549 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 550 | "version": "4.17.2", 551 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", 552 | "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", 553 | "cpu": [ 554 | "ppc64" 555 | ], 556 | "dev": true, 557 | "optional": true, 558 | "os": [ 559 | "linux" 560 | ] 561 | }, 562 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 563 | "version": "4.17.2", 564 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", 565 | "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", 566 | "cpu": [ 567 | "riscv64" 568 | ], 569 | "dev": true, 570 | "optional": true, 571 | "os": [ 572 | "linux" 573 | ] 574 | }, 575 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 576 | "version": "4.17.2", 577 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", 578 | "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", 579 | "cpu": [ 580 | "s390x" 581 | ], 582 | "dev": true, 583 | "optional": true, 584 | "os": [ 585 | "linux" 586 | ] 587 | }, 588 | "node_modules/@rollup/rollup-linux-x64-gnu": { 589 | "version": "4.17.2", 590 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", 591 | "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", 592 | "cpu": [ 593 | "x64" 594 | ], 595 | "dev": true, 596 | "optional": true, 597 | "os": [ 598 | "linux" 599 | ] 600 | }, 601 | "node_modules/@rollup/rollup-linux-x64-musl": { 602 | "version": "4.17.2", 603 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", 604 | "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", 605 | "cpu": [ 606 | "x64" 607 | ], 608 | "dev": true, 609 | "optional": true, 610 | "os": [ 611 | "linux" 612 | ] 613 | }, 614 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 615 | "version": "4.17.2", 616 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", 617 | "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", 618 | "cpu": [ 619 | "arm64" 620 | ], 621 | "dev": true, 622 | "optional": true, 623 | "os": [ 624 | "win32" 625 | ] 626 | }, 627 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 628 | "version": "4.17.2", 629 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", 630 | "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", 631 | "cpu": [ 632 | "ia32" 633 | ], 634 | "dev": true, 635 | "optional": true, 636 | "os": [ 637 | "win32" 638 | ] 639 | }, 640 | "node_modules/@rollup/rollup-win32-x64-msvc": { 641 | "version": "4.17.2", 642 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", 643 | "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", 644 | "cpu": [ 645 | "x64" 646 | ], 647 | "dev": true, 648 | "optional": true, 649 | "os": [ 650 | "win32" 651 | ] 652 | }, 653 | "node_modules/@sveltejs/vite-plugin-svelte": { 654 | "version": "3.1.0", 655 | "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.0.tgz", 656 | "integrity": "sha512-sY6ncCvg+O3njnzbZexcVtUqOBE3iYmQPJ9y+yXSkOwG576QI/xJrBnQSRXFLGwJNBa0T78JEKg5cIR0WOAuUw==", 657 | "dev": true, 658 | "dependencies": { 659 | "@sveltejs/vite-plugin-svelte-inspector": "^2.0.0", 660 | "debug": "^4.3.4", 661 | "deepmerge": "^4.3.1", 662 | "kleur": "^4.1.5", 663 | "magic-string": "^0.30.9", 664 | "svelte-hmr": "^0.16.0", 665 | "vitefu": "^0.2.5" 666 | }, 667 | "engines": { 668 | "node": "^18.0.0 || >=20" 669 | }, 670 | "peerDependencies": { 671 | "svelte": "^4.0.0 || ^5.0.0-next.0", 672 | "vite": "^5.0.0" 673 | } 674 | }, 675 | "node_modules/@sveltejs/vite-plugin-svelte-inspector": { 676 | "version": "2.1.0", 677 | "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", 678 | "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", 679 | "dev": true, 680 | "dependencies": { 681 | "debug": "^4.3.4" 682 | }, 683 | "engines": { 684 | "node": "^18.0.0 || >=20" 685 | }, 686 | "peerDependencies": { 687 | "@sveltejs/vite-plugin-svelte": "^3.0.0", 688 | "svelte": "^4.0.0 || ^5.0.0-next.0", 689 | "vite": "^5.0.0" 690 | } 691 | }, 692 | "node_modules/@types/estree": { 693 | "version": "1.0.5", 694 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", 695 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", 696 | "dev": true 697 | }, 698 | "node_modules/acorn": { 699 | "version": "8.11.3", 700 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 701 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 702 | "dev": true, 703 | "bin": { 704 | "acorn": "bin/acorn" 705 | }, 706 | "engines": { 707 | "node": ">=0.4.0" 708 | } 709 | }, 710 | "node_modules/aria-query": { 711 | "version": "5.3.0", 712 | "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", 713 | "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", 714 | "dev": true, 715 | "dependencies": { 716 | "dequal": "^2.0.3" 717 | } 718 | }, 719 | "node_modules/axobject-query": { 720 | "version": "4.0.0", 721 | "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", 722 | "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", 723 | "dev": true, 724 | "dependencies": { 725 | "dequal": "^2.0.3" 726 | } 727 | }, 728 | "node_modules/code-red": { 729 | "version": "1.0.4", 730 | "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", 731 | "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", 732 | "dev": true, 733 | "dependencies": { 734 | "@jridgewell/sourcemap-codec": "^1.4.15", 735 | "@types/estree": "^1.0.1", 736 | "acorn": "^8.10.0", 737 | "estree-walker": "^3.0.3", 738 | "periscopic": "^3.1.0" 739 | } 740 | }, 741 | "node_modules/css-tree": { 742 | "version": "2.3.1", 743 | "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", 744 | "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", 745 | "dev": true, 746 | "dependencies": { 747 | "mdn-data": "2.0.30", 748 | "source-map-js": "^1.0.1" 749 | }, 750 | "engines": { 751 | "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" 752 | } 753 | }, 754 | "node_modules/debug": { 755 | "version": "4.3.4", 756 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 757 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 758 | "dev": true, 759 | "dependencies": { 760 | "ms": "2.1.2" 761 | }, 762 | "engines": { 763 | "node": ">=6.0" 764 | }, 765 | "peerDependenciesMeta": { 766 | "supports-color": { 767 | "optional": true 768 | } 769 | } 770 | }, 771 | "node_modules/deepmerge": { 772 | "version": "4.3.1", 773 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", 774 | "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", 775 | "dev": true, 776 | "engines": { 777 | "node": ">=0.10.0" 778 | } 779 | }, 780 | "node_modules/dequal": { 781 | "version": "2.0.3", 782 | "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", 783 | "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", 784 | "dev": true, 785 | "engines": { 786 | "node": ">=6" 787 | } 788 | }, 789 | "node_modules/esbuild": { 790 | "version": "0.20.2", 791 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", 792 | "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", 793 | "dev": true, 794 | "hasInstallScript": true, 795 | "bin": { 796 | "esbuild": "bin/esbuild" 797 | }, 798 | "engines": { 799 | "node": ">=12" 800 | }, 801 | "optionalDependencies": { 802 | "@esbuild/aix-ppc64": "0.20.2", 803 | "@esbuild/android-arm": "0.20.2", 804 | "@esbuild/android-arm64": "0.20.2", 805 | "@esbuild/android-x64": "0.20.2", 806 | "@esbuild/darwin-arm64": "0.20.2", 807 | "@esbuild/darwin-x64": "0.20.2", 808 | "@esbuild/freebsd-arm64": "0.20.2", 809 | "@esbuild/freebsd-x64": "0.20.2", 810 | "@esbuild/linux-arm": "0.20.2", 811 | "@esbuild/linux-arm64": "0.20.2", 812 | "@esbuild/linux-ia32": "0.20.2", 813 | "@esbuild/linux-loong64": "0.20.2", 814 | "@esbuild/linux-mips64el": "0.20.2", 815 | "@esbuild/linux-ppc64": "0.20.2", 816 | "@esbuild/linux-riscv64": "0.20.2", 817 | "@esbuild/linux-s390x": "0.20.2", 818 | "@esbuild/linux-x64": "0.20.2", 819 | "@esbuild/netbsd-x64": "0.20.2", 820 | "@esbuild/openbsd-x64": "0.20.2", 821 | "@esbuild/sunos-x64": "0.20.2", 822 | "@esbuild/win32-arm64": "0.20.2", 823 | "@esbuild/win32-ia32": "0.20.2", 824 | "@esbuild/win32-x64": "0.20.2" 825 | } 826 | }, 827 | "node_modules/estree-walker": { 828 | "version": "3.0.3", 829 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", 830 | "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", 831 | "dev": true, 832 | "dependencies": { 833 | "@types/estree": "^1.0.0" 834 | } 835 | }, 836 | "node_modules/fsevents": { 837 | "version": "2.3.3", 838 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 839 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 840 | "dev": true, 841 | "hasInstallScript": true, 842 | "optional": true, 843 | "os": [ 844 | "darwin" 845 | ], 846 | "engines": { 847 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 848 | } 849 | }, 850 | "node_modules/is-reference": { 851 | "version": "3.0.2", 852 | "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", 853 | "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", 854 | "dev": true, 855 | "dependencies": { 856 | "@types/estree": "*" 857 | } 858 | }, 859 | "node_modules/kleur": { 860 | "version": "4.1.5", 861 | "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", 862 | "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", 863 | "dev": true, 864 | "engines": { 865 | "node": ">=6" 866 | } 867 | }, 868 | "node_modules/locate-character": { 869 | "version": "3.0.0", 870 | "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", 871 | "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", 872 | "dev": true 873 | }, 874 | "node_modules/magic-string": { 875 | "version": "0.30.10", 876 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", 877 | "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", 878 | "dev": true, 879 | "dependencies": { 880 | "@jridgewell/sourcemap-codec": "^1.4.15" 881 | } 882 | }, 883 | "node_modules/mdn-data": { 884 | "version": "2.0.30", 885 | "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", 886 | "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", 887 | "dev": true 888 | }, 889 | "node_modules/ms": { 890 | "version": "2.1.2", 891 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 892 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 893 | "dev": true 894 | }, 895 | "node_modules/nanoid": { 896 | "version": "3.3.7", 897 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 898 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 899 | "dev": true, 900 | "funding": [ 901 | { 902 | "type": "github", 903 | "url": "https://github.com/sponsors/ai" 904 | } 905 | ], 906 | "bin": { 907 | "nanoid": "bin/nanoid.cjs" 908 | }, 909 | "engines": { 910 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 911 | } 912 | }, 913 | "node_modules/periscopic": { 914 | "version": "3.1.0", 915 | "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", 916 | "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", 917 | "dev": true, 918 | "dependencies": { 919 | "@types/estree": "^1.0.0", 920 | "estree-walker": "^3.0.0", 921 | "is-reference": "^3.0.0" 922 | } 923 | }, 924 | "node_modules/picocolors": { 925 | "version": "1.0.1", 926 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", 927 | "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", 928 | "dev": true 929 | }, 930 | "node_modules/postcss": { 931 | "version": "8.4.38", 932 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", 933 | "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", 934 | "dev": true, 935 | "funding": [ 936 | { 937 | "type": "opencollective", 938 | "url": "https://opencollective.com/postcss/" 939 | }, 940 | { 941 | "type": "tidelift", 942 | "url": "https://tidelift.com/funding/github/npm/postcss" 943 | }, 944 | { 945 | "type": "github", 946 | "url": "https://github.com/sponsors/ai" 947 | } 948 | ], 949 | "dependencies": { 950 | "nanoid": "^3.3.7", 951 | "picocolors": "^1.0.0", 952 | "source-map-js": "^1.2.0" 953 | }, 954 | "engines": { 955 | "node": "^10 || ^12 || >=14" 956 | } 957 | }, 958 | "node_modules/rollup": { 959 | "version": "4.17.2", 960 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", 961 | "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", 962 | "dev": true, 963 | "dependencies": { 964 | "@types/estree": "1.0.5" 965 | }, 966 | "bin": { 967 | "rollup": "dist/bin/rollup" 968 | }, 969 | "engines": { 970 | "node": ">=18.0.0", 971 | "npm": ">=8.0.0" 972 | }, 973 | "optionalDependencies": { 974 | "@rollup/rollup-android-arm-eabi": "4.17.2", 975 | "@rollup/rollup-android-arm64": "4.17.2", 976 | "@rollup/rollup-darwin-arm64": "4.17.2", 977 | "@rollup/rollup-darwin-x64": "4.17.2", 978 | "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", 979 | "@rollup/rollup-linux-arm-musleabihf": "4.17.2", 980 | "@rollup/rollup-linux-arm64-gnu": "4.17.2", 981 | "@rollup/rollup-linux-arm64-musl": "4.17.2", 982 | "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", 983 | "@rollup/rollup-linux-riscv64-gnu": "4.17.2", 984 | "@rollup/rollup-linux-s390x-gnu": "4.17.2", 985 | "@rollup/rollup-linux-x64-gnu": "4.17.2", 986 | "@rollup/rollup-linux-x64-musl": "4.17.2", 987 | "@rollup/rollup-win32-arm64-msvc": "4.17.2", 988 | "@rollup/rollup-win32-ia32-msvc": "4.17.2", 989 | "@rollup/rollup-win32-x64-msvc": "4.17.2", 990 | "fsevents": "~2.3.2" 991 | } 992 | }, 993 | "node_modules/source-map-js": { 994 | "version": "1.2.0", 995 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", 996 | "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", 997 | "dev": true, 998 | "engines": { 999 | "node": ">=0.10.0" 1000 | } 1001 | }, 1002 | "node_modules/svelte": { 1003 | "version": "4.2.17", 1004 | "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.17.tgz", 1005 | "integrity": "sha512-N7m1YnoXtRf5wya5Gyx3TWuTddI4nAyayyIWFojiWV5IayDYNV5i2mRp/7qNGol4DtxEYxljmrbgp1HM6hUbmQ==", 1006 | "dev": true, 1007 | "dependencies": { 1008 | "@ampproject/remapping": "^2.2.1", 1009 | "@jridgewell/sourcemap-codec": "^1.4.15", 1010 | "@jridgewell/trace-mapping": "^0.3.18", 1011 | "@types/estree": "^1.0.1", 1012 | "acorn": "^8.9.0", 1013 | "aria-query": "^5.3.0", 1014 | "axobject-query": "^4.0.0", 1015 | "code-red": "^1.0.3", 1016 | "css-tree": "^2.3.1", 1017 | "estree-walker": "^3.0.3", 1018 | "is-reference": "^3.0.1", 1019 | "locate-character": "^3.0.0", 1020 | "magic-string": "^0.30.4", 1021 | "periscopic": "^3.1.0" 1022 | }, 1023 | "engines": { 1024 | "node": ">=16" 1025 | } 1026 | }, 1027 | "node_modules/svelte-hmr": { 1028 | "version": "0.16.0", 1029 | "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", 1030 | "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", 1031 | "dev": true, 1032 | "engines": { 1033 | "node": "^12.20 || ^14.13.1 || >= 16" 1034 | }, 1035 | "peerDependencies": { 1036 | "svelte": "^3.19.0 || ^4.0.0" 1037 | } 1038 | }, 1039 | "node_modules/vite": { 1040 | "version": "5.2.11", 1041 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", 1042 | "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", 1043 | "dev": true, 1044 | "dependencies": { 1045 | "esbuild": "^0.20.1", 1046 | "postcss": "^8.4.38", 1047 | "rollup": "^4.13.0" 1048 | }, 1049 | "bin": { 1050 | "vite": "bin/vite.js" 1051 | }, 1052 | "engines": { 1053 | "node": "^18.0.0 || >=20.0.0" 1054 | }, 1055 | "funding": { 1056 | "url": "https://github.com/vitejs/vite?sponsor=1" 1057 | }, 1058 | "optionalDependencies": { 1059 | "fsevents": "~2.3.3" 1060 | }, 1061 | "peerDependencies": { 1062 | "@types/node": "^18.0.0 || >=20.0.0", 1063 | "less": "*", 1064 | "lightningcss": "^1.21.0", 1065 | "sass": "*", 1066 | "stylus": "*", 1067 | "sugarss": "*", 1068 | "terser": "^5.4.0" 1069 | }, 1070 | "peerDependenciesMeta": { 1071 | "@types/node": { 1072 | "optional": true 1073 | }, 1074 | "less": { 1075 | "optional": true 1076 | }, 1077 | "lightningcss": { 1078 | "optional": true 1079 | }, 1080 | "sass": { 1081 | "optional": true 1082 | }, 1083 | "stylus": { 1084 | "optional": true 1085 | }, 1086 | "sugarss": { 1087 | "optional": true 1088 | }, 1089 | "terser": { 1090 | "optional": true 1091 | } 1092 | } 1093 | }, 1094 | "node_modules/vitefu": { 1095 | "version": "0.2.5", 1096 | "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", 1097 | "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", 1098 | "dev": true, 1099 | "peerDependencies": { 1100 | "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" 1101 | }, 1102 | "peerDependenciesMeta": { 1103 | "vite": { 1104 | "optional": true 1105 | } 1106 | } 1107 | } 1108 | }, 1109 | "dependencies": { 1110 | "@ampproject/remapping": { 1111 | "version": "2.3.0", 1112 | "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", 1113 | "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", 1114 | "dev": true, 1115 | "requires": { 1116 | "@jridgewell/gen-mapping": "^0.3.5", 1117 | "@jridgewell/trace-mapping": "^0.3.24" 1118 | } 1119 | }, 1120 | "@esbuild/aix-ppc64": { 1121 | "version": "0.20.2", 1122 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", 1123 | "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", 1124 | "dev": true, 1125 | "optional": true 1126 | }, 1127 | "@esbuild/android-arm": { 1128 | "version": "0.20.2", 1129 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", 1130 | "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", 1131 | "dev": true, 1132 | "optional": true 1133 | }, 1134 | "@esbuild/android-arm64": { 1135 | "version": "0.20.2", 1136 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", 1137 | "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", 1138 | "dev": true, 1139 | "optional": true 1140 | }, 1141 | "@esbuild/android-x64": { 1142 | "version": "0.20.2", 1143 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", 1144 | "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", 1145 | "dev": true, 1146 | "optional": true 1147 | }, 1148 | "@esbuild/darwin-arm64": { 1149 | "version": "0.20.2", 1150 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", 1151 | "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", 1152 | "dev": true, 1153 | "optional": true 1154 | }, 1155 | "@esbuild/darwin-x64": { 1156 | "version": "0.20.2", 1157 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", 1158 | "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", 1159 | "dev": true, 1160 | "optional": true 1161 | }, 1162 | "@esbuild/freebsd-arm64": { 1163 | "version": "0.20.2", 1164 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", 1165 | "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", 1166 | "dev": true, 1167 | "optional": true 1168 | }, 1169 | "@esbuild/freebsd-x64": { 1170 | "version": "0.20.2", 1171 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", 1172 | "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", 1173 | "dev": true, 1174 | "optional": true 1175 | }, 1176 | "@esbuild/linux-arm": { 1177 | "version": "0.20.2", 1178 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", 1179 | "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", 1180 | "dev": true, 1181 | "optional": true 1182 | }, 1183 | "@esbuild/linux-arm64": { 1184 | "version": "0.20.2", 1185 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", 1186 | "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", 1187 | "dev": true, 1188 | "optional": true 1189 | }, 1190 | "@esbuild/linux-ia32": { 1191 | "version": "0.20.2", 1192 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", 1193 | "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", 1194 | "dev": true, 1195 | "optional": true 1196 | }, 1197 | "@esbuild/linux-loong64": { 1198 | "version": "0.20.2", 1199 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", 1200 | "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", 1201 | "dev": true, 1202 | "optional": true 1203 | }, 1204 | "@esbuild/linux-mips64el": { 1205 | "version": "0.20.2", 1206 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", 1207 | "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", 1208 | "dev": true, 1209 | "optional": true 1210 | }, 1211 | "@esbuild/linux-ppc64": { 1212 | "version": "0.20.2", 1213 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", 1214 | "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", 1215 | "dev": true, 1216 | "optional": true 1217 | }, 1218 | "@esbuild/linux-riscv64": { 1219 | "version": "0.20.2", 1220 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", 1221 | "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", 1222 | "dev": true, 1223 | "optional": true 1224 | }, 1225 | "@esbuild/linux-s390x": { 1226 | "version": "0.20.2", 1227 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", 1228 | "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", 1229 | "dev": true, 1230 | "optional": true 1231 | }, 1232 | "@esbuild/linux-x64": { 1233 | "version": "0.20.2", 1234 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", 1235 | "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", 1236 | "dev": true, 1237 | "optional": true 1238 | }, 1239 | "@esbuild/netbsd-x64": { 1240 | "version": "0.20.2", 1241 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", 1242 | "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", 1243 | "dev": true, 1244 | "optional": true 1245 | }, 1246 | "@esbuild/openbsd-x64": { 1247 | "version": "0.20.2", 1248 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", 1249 | "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", 1250 | "dev": true, 1251 | "optional": true 1252 | }, 1253 | "@esbuild/sunos-x64": { 1254 | "version": "0.20.2", 1255 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", 1256 | "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", 1257 | "dev": true, 1258 | "optional": true 1259 | }, 1260 | "@esbuild/win32-arm64": { 1261 | "version": "0.20.2", 1262 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", 1263 | "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", 1264 | "dev": true, 1265 | "optional": true 1266 | }, 1267 | "@esbuild/win32-ia32": { 1268 | "version": "0.20.2", 1269 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", 1270 | "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", 1271 | "dev": true, 1272 | "optional": true 1273 | }, 1274 | "@esbuild/win32-x64": { 1275 | "version": "0.20.2", 1276 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", 1277 | "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", 1278 | "dev": true, 1279 | "optional": true 1280 | }, 1281 | "@jridgewell/gen-mapping": { 1282 | "version": "0.3.5", 1283 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", 1284 | "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", 1285 | "dev": true, 1286 | "requires": { 1287 | "@jridgewell/set-array": "^1.2.1", 1288 | "@jridgewell/sourcemap-codec": "^1.4.10", 1289 | "@jridgewell/trace-mapping": "^0.3.24" 1290 | } 1291 | }, 1292 | "@jridgewell/resolve-uri": { 1293 | "version": "3.1.2", 1294 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 1295 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 1296 | "dev": true 1297 | }, 1298 | "@jridgewell/set-array": { 1299 | "version": "1.2.1", 1300 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", 1301 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 1302 | "dev": true 1303 | }, 1304 | "@jridgewell/sourcemap-codec": { 1305 | "version": "1.4.15", 1306 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 1307 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 1308 | "dev": true 1309 | }, 1310 | "@jridgewell/trace-mapping": { 1311 | "version": "0.3.25", 1312 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 1313 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 1314 | "dev": true, 1315 | "requires": { 1316 | "@jridgewell/resolve-uri": "^3.1.0", 1317 | "@jridgewell/sourcemap-codec": "^1.4.14" 1318 | } 1319 | }, 1320 | "@rollup/rollup-android-arm-eabi": { 1321 | "version": "4.17.2", 1322 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", 1323 | "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", 1324 | "dev": true, 1325 | "optional": true 1326 | }, 1327 | "@rollup/rollup-android-arm64": { 1328 | "version": "4.17.2", 1329 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", 1330 | "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", 1331 | "dev": true, 1332 | "optional": true 1333 | }, 1334 | "@rollup/rollup-darwin-arm64": { 1335 | "version": "4.17.2", 1336 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", 1337 | "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", 1338 | "dev": true, 1339 | "optional": true 1340 | }, 1341 | "@rollup/rollup-darwin-x64": { 1342 | "version": "4.17.2", 1343 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", 1344 | "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", 1345 | "dev": true, 1346 | "optional": true 1347 | }, 1348 | "@rollup/rollup-linux-arm-gnueabihf": { 1349 | "version": "4.17.2", 1350 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", 1351 | "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", 1352 | "dev": true, 1353 | "optional": true 1354 | }, 1355 | "@rollup/rollup-linux-arm-musleabihf": { 1356 | "version": "4.17.2", 1357 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", 1358 | "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", 1359 | "dev": true, 1360 | "optional": true 1361 | }, 1362 | "@rollup/rollup-linux-arm64-gnu": { 1363 | "version": "4.17.2", 1364 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", 1365 | "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", 1366 | "dev": true, 1367 | "optional": true 1368 | }, 1369 | "@rollup/rollup-linux-arm64-musl": { 1370 | "version": "4.17.2", 1371 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", 1372 | "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", 1373 | "dev": true, 1374 | "optional": true 1375 | }, 1376 | "@rollup/rollup-linux-powerpc64le-gnu": { 1377 | "version": "4.17.2", 1378 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", 1379 | "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", 1380 | "dev": true, 1381 | "optional": true 1382 | }, 1383 | "@rollup/rollup-linux-riscv64-gnu": { 1384 | "version": "4.17.2", 1385 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", 1386 | "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", 1387 | "dev": true, 1388 | "optional": true 1389 | }, 1390 | "@rollup/rollup-linux-s390x-gnu": { 1391 | "version": "4.17.2", 1392 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", 1393 | "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", 1394 | "dev": true, 1395 | "optional": true 1396 | }, 1397 | "@rollup/rollup-linux-x64-gnu": { 1398 | "version": "4.17.2", 1399 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", 1400 | "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", 1401 | "dev": true, 1402 | "optional": true 1403 | }, 1404 | "@rollup/rollup-linux-x64-musl": { 1405 | "version": "4.17.2", 1406 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", 1407 | "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", 1408 | "dev": true, 1409 | "optional": true 1410 | }, 1411 | "@rollup/rollup-win32-arm64-msvc": { 1412 | "version": "4.17.2", 1413 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", 1414 | "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", 1415 | "dev": true, 1416 | "optional": true 1417 | }, 1418 | "@rollup/rollup-win32-ia32-msvc": { 1419 | "version": "4.17.2", 1420 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", 1421 | "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", 1422 | "dev": true, 1423 | "optional": true 1424 | }, 1425 | "@rollup/rollup-win32-x64-msvc": { 1426 | "version": "4.17.2", 1427 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", 1428 | "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", 1429 | "dev": true, 1430 | "optional": true 1431 | }, 1432 | "@sveltejs/vite-plugin-svelte": { 1433 | "version": "3.1.0", 1434 | "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.0.tgz", 1435 | "integrity": "sha512-sY6ncCvg+O3njnzbZexcVtUqOBE3iYmQPJ9y+yXSkOwG576QI/xJrBnQSRXFLGwJNBa0T78JEKg5cIR0WOAuUw==", 1436 | "dev": true, 1437 | "requires": { 1438 | "@sveltejs/vite-plugin-svelte-inspector": "^2.0.0", 1439 | "debug": "^4.3.4", 1440 | "deepmerge": "^4.3.1", 1441 | "kleur": "^4.1.5", 1442 | "magic-string": "^0.30.9", 1443 | "svelte-hmr": "^0.16.0", 1444 | "vitefu": "^0.2.5" 1445 | } 1446 | }, 1447 | "@sveltejs/vite-plugin-svelte-inspector": { 1448 | "version": "2.1.0", 1449 | "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", 1450 | "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", 1451 | "dev": true, 1452 | "requires": { 1453 | "debug": "^4.3.4" 1454 | } 1455 | }, 1456 | "@types/estree": { 1457 | "version": "1.0.5", 1458 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", 1459 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", 1460 | "dev": true 1461 | }, 1462 | "acorn": { 1463 | "version": "8.11.3", 1464 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 1465 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 1466 | "dev": true 1467 | }, 1468 | "aria-query": { 1469 | "version": "5.3.0", 1470 | "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", 1471 | "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", 1472 | "dev": true, 1473 | "requires": { 1474 | "dequal": "^2.0.3" 1475 | } 1476 | }, 1477 | "axobject-query": { 1478 | "version": "4.0.0", 1479 | "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", 1480 | "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", 1481 | "dev": true, 1482 | "requires": { 1483 | "dequal": "^2.0.3" 1484 | } 1485 | }, 1486 | "code-red": { 1487 | "version": "1.0.4", 1488 | "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", 1489 | "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", 1490 | "dev": true, 1491 | "requires": { 1492 | "@jridgewell/sourcemap-codec": "^1.4.15", 1493 | "@types/estree": "^1.0.1", 1494 | "acorn": "^8.10.0", 1495 | "estree-walker": "^3.0.3", 1496 | "periscopic": "^3.1.0" 1497 | } 1498 | }, 1499 | "css-tree": { 1500 | "version": "2.3.1", 1501 | "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", 1502 | "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", 1503 | "dev": true, 1504 | "requires": { 1505 | "mdn-data": "2.0.30", 1506 | "source-map-js": "^1.0.1" 1507 | } 1508 | }, 1509 | "debug": { 1510 | "version": "4.3.4", 1511 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 1512 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 1513 | "dev": true, 1514 | "requires": { 1515 | "ms": "2.1.2" 1516 | } 1517 | }, 1518 | "deepmerge": { 1519 | "version": "4.3.1", 1520 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", 1521 | "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", 1522 | "dev": true 1523 | }, 1524 | "dequal": { 1525 | "version": "2.0.3", 1526 | "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", 1527 | "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", 1528 | "dev": true 1529 | }, 1530 | "esbuild": { 1531 | "version": "0.20.2", 1532 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", 1533 | "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", 1534 | "dev": true, 1535 | "requires": { 1536 | "@esbuild/aix-ppc64": "0.20.2", 1537 | "@esbuild/android-arm": "0.20.2", 1538 | "@esbuild/android-arm64": "0.20.2", 1539 | "@esbuild/android-x64": "0.20.2", 1540 | "@esbuild/darwin-arm64": "0.20.2", 1541 | "@esbuild/darwin-x64": "0.20.2", 1542 | "@esbuild/freebsd-arm64": "0.20.2", 1543 | "@esbuild/freebsd-x64": "0.20.2", 1544 | "@esbuild/linux-arm": "0.20.2", 1545 | "@esbuild/linux-arm64": "0.20.2", 1546 | "@esbuild/linux-ia32": "0.20.2", 1547 | "@esbuild/linux-loong64": "0.20.2", 1548 | "@esbuild/linux-mips64el": "0.20.2", 1549 | "@esbuild/linux-ppc64": "0.20.2", 1550 | "@esbuild/linux-riscv64": "0.20.2", 1551 | "@esbuild/linux-s390x": "0.20.2", 1552 | "@esbuild/linux-x64": "0.20.2", 1553 | "@esbuild/netbsd-x64": "0.20.2", 1554 | "@esbuild/openbsd-x64": "0.20.2", 1555 | "@esbuild/sunos-x64": "0.20.2", 1556 | "@esbuild/win32-arm64": "0.20.2", 1557 | "@esbuild/win32-ia32": "0.20.2", 1558 | "@esbuild/win32-x64": "0.20.2" 1559 | } 1560 | }, 1561 | "estree-walker": { 1562 | "version": "3.0.3", 1563 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", 1564 | "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", 1565 | "dev": true, 1566 | "requires": { 1567 | "@types/estree": "^1.0.0" 1568 | } 1569 | }, 1570 | "fsevents": { 1571 | "version": "2.3.3", 1572 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1573 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1574 | "dev": true, 1575 | "optional": true 1576 | }, 1577 | "is-reference": { 1578 | "version": "3.0.2", 1579 | "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", 1580 | "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", 1581 | "dev": true, 1582 | "requires": { 1583 | "@types/estree": "*" 1584 | } 1585 | }, 1586 | "kleur": { 1587 | "version": "4.1.5", 1588 | "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", 1589 | "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", 1590 | "dev": true 1591 | }, 1592 | "locate-character": { 1593 | "version": "3.0.0", 1594 | "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", 1595 | "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", 1596 | "dev": true 1597 | }, 1598 | "magic-string": { 1599 | "version": "0.30.10", 1600 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", 1601 | "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", 1602 | "dev": true, 1603 | "requires": { 1604 | "@jridgewell/sourcemap-codec": "^1.4.15" 1605 | } 1606 | }, 1607 | "mdn-data": { 1608 | "version": "2.0.30", 1609 | "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", 1610 | "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", 1611 | "dev": true 1612 | }, 1613 | "ms": { 1614 | "version": "2.1.2", 1615 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1616 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1617 | "dev": true 1618 | }, 1619 | "nanoid": { 1620 | "version": "3.3.7", 1621 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 1622 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 1623 | "dev": true 1624 | }, 1625 | "periscopic": { 1626 | "version": "3.1.0", 1627 | "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", 1628 | "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", 1629 | "dev": true, 1630 | "requires": { 1631 | "@types/estree": "^1.0.0", 1632 | "estree-walker": "^3.0.0", 1633 | "is-reference": "^3.0.0" 1634 | } 1635 | }, 1636 | "picocolors": { 1637 | "version": "1.0.1", 1638 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", 1639 | "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", 1640 | "dev": true 1641 | }, 1642 | "postcss": { 1643 | "version": "8.4.38", 1644 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", 1645 | "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", 1646 | "dev": true, 1647 | "requires": { 1648 | "nanoid": "^3.3.7", 1649 | "picocolors": "^1.0.0", 1650 | "source-map-js": "^1.2.0" 1651 | } 1652 | }, 1653 | "rollup": { 1654 | "version": "4.17.2", 1655 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", 1656 | "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", 1657 | "dev": true, 1658 | "requires": { 1659 | "@rollup/rollup-android-arm-eabi": "4.17.2", 1660 | "@rollup/rollup-android-arm64": "4.17.2", 1661 | "@rollup/rollup-darwin-arm64": "4.17.2", 1662 | "@rollup/rollup-darwin-x64": "4.17.2", 1663 | "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", 1664 | "@rollup/rollup-linux-arm-musleabihf": "4.17.2", 1665 | "@rollup/rollup-linux-arm64-gnu": "4.17.2", 1666 | "@rollup/rollup-linux-arm64-musl": "4.17.2", 1667 | "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", 1668 | "@rollup/rollup-linux-riscv64-gnu": "4.17.2", 1669 | "@rollup/rollup-linux-s390x-gnu": "4.17.2", 1670 | "@rollup/rollup-linux-x64-gnu": "4.17.2", 1671 | "@rollup/rollup-linux-x64-musl": "4.17.2", 1672 | "@rollup/rollup-win32-arm64-msvc": "4.17.2", 1673 | "@rollup/rollup-win32-ia32-msvc": "4.17.2", 1674 | "@rollup/rollup-win32-x64-msvc": "4.17.2", 1675 | "@types/estree": "1.0.5", 1676 | "fsevents": "~2.3.2" 1677 | } 1678 | }, 1679 | "source-map-js": { 1680 | "version": "1.2.0", 1681 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", 1682 | "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", 1683 | "dev": true 1684 | }, 1685 | "svelte": { 1686 | "version": "4.2.17", 1687 | "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.17.tgz", 1688 | "integrity": "sha512-N7m1YnoXtRf5wya5Gyx3TWuTddI4nAyayyIWFojiWV5IayDYNV5i2mRp/7qNGol4DtxEYxljmrbgp1HM6hUbmQ==", 1689 | "dev": true, 1690 | "requires": { 1691 | "@ampproject/remapping": "^2.2.1", 1692 | "@jridgewell/sourcemap-codec": "^1.4.15", 1693 | "@jridgewell/trace-mapping": "^0.3.18", 1694 | "@types/estree": "^1.0.1", 1695 | "acorn": "^8.9.0", 1696 | "aria-query": "^5.3.0", 1697 | "axobject-query": "^4.0.0", 1698 | "code-red": "^1.0.3", 1699 | "css-tree": "^2.3.1", 1700 | "estree-walker": "^3.0.3", 1701 | "is-reference": "^3.0.1", 1702 | "locate-character": "^3.0.0", 1703 | "magic-string": "^0.30.4", 1704 | "periscopic": "^3.1.0" 1705 | } 1706 | }, 1707 | "svelte-hmr": { 1708 | "version": "0.16.0", 1709 | "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", 1710 | "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", 1711 | "dev": true, 1712 | "requires": {} 1713 | }, 1714 | "vite": { 1715 | "version": "5.2.11", 1716 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", 1717 | "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", 1718 | "dev": true, 1719 | "requires": { 1720 | "esbuild": "^0.20.1", 1721 | "fsevents": "~2.3.3", 1722 | "postcss": "^8.4.38", 1723 | "rollup": "^4.13.0" 1724 | } 1725 | }, 1726 | "vitefu": { 1727 | "version": "0.2.5", 1728 | "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", 1729 | "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", 1730 | "dev": true, 1731 | "requires": {} 1732 | } 1733 | } 1734 | } 1735 | -------------------------------------------------------------------------------- /web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "@sveltejs/vite-plugin-svelte": "^3.0.2", 13 | "svelte": "^4.2.12", 14 | "vite": "^5.2.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /web/src/App.svelte: -------------------------------------------------------------------------------- 1 |
2 |

Statee

3 |

Yeah, it works

4 |
5 | -------------------------------------------------------------------------------- /web/src/main.js: -------------------------------------------------------------------------------- 1 | import App from './App.svelte' 2 | 3 | const app = new App({ 4 | target: document.getElementById('app'), 5 | }) 6 | 7 | export default app 8 | -------------------------------------------------------------------------------- /web/svelte.config.js: -------------------------------------------------------------------------------- 1 | import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' 2 | 3 | export default { 4 | // Consult https://svelte.dev/docs#compile-time-svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: vitePreprocess(), 7 | } 8 | -------------------------------------------------------------------------------- /web/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import { svelte } from '@sveltejs/vite-plugin-svelte' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [svelte()], 7 | }) 8 | --------------------------------------------------------------------------------