diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index bf3d8de390b..d73efffa8a1 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,9 +1,19 @@ # Description @@ -14,7 +24,7 @@ Fixes # (issue) ## Type of change -Please delete options that are not relevant. +Please select the option that is relevant. - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) @@ -28,6 +38,8 @@ Please describe the tests that you ran to verify your changes. Provide instructi - [ ] Windows - [ ] macOS - [ ] Linux + +If you checked Linux, please specify the distro and version. ## Test Configuration diff --git a/mkdocs-website/Dockerfile b/mkdocs-website/Dockerfile new file mode 100644 index 00000000000..875bc2f0df0 --- /dev/null +++ b/mkdocs-website/Dockerfile @@ -0,0 +1,2 @@ +FROM squidfunk/mkdocs-material +RUN python3 -m pip install mkdocs-table-reader-plugin mkdocs-git-committers-plugin-2 mkdocs-static-i18n diff --git a/mkdocs-website/Taskfile.yml b/mkdocs-website/Taskfile.yml index 712a1fb2a16..a6db379a0e8 100644 --- a/mkdocs-website/Taskfile.yml +++ b/mkdocs-website/Taskfile.yml @@ -20,6 +20,10 @@ tasks: cmds: - python3 -m pip install -r requirements.insiders.txt --user + build:docker: + cmds: + - docker build -t wailsapp/mkdocs . + upgrade:insiders: summary: Upgrade the project (insiders) preconditions: @@ -38,11 +42,8 @@ tasks: serve: summary: Builds the documentation and serves it locally - preconditions: - - sh: mkdocs --version - msg: "Looks like mkdocs isn't installed. Run `wails3 task setup` or `task setup` in the documentation directory to install it." cmds: - - mkdocs serve + - docker run --rm -it -p 8000:8000 -v $PWD:/docs wailsapp/mkdocs serve:insiders: summary: Builds the documentation and serves it locally diff --git a/mkdocs-website/docs/en/API/application.md b/mkdocs-website/docs/en/API/application.md index caddaf104a6..a529b96b960 100644 --- a/mkdocs-website/docs/en/API/application.md +++ b/mkdocs-website/docs/en/API/application.md @@ -133,6 +133,57 @@ API: `Show()` app.Show() ``` +### Path + +API: `Path(selector Path) string` + +`Path(selector Path)` returns the full path for the given path type. It provides a cross-platform way to query common application directories. + +The `Path` type is an enum with the following values: +- `PathHome`: Returns the user's home directory +- `PathDataHome`: Returns the path to the user's data directory +- `PathConfigHome`: Returns the path to the user's configuration directory +- `PathStateHome`: Returns the path to the user's state directory +- `PathCacheHome`: Returns the path to the user's cache directory +- `PathRuntimeDir`: Returns the path to the user's runtime directory +- `PathDesktop`: Returns the path to the user's desktop directory +- `PathDownload`: Returns the path to the user's download directory +- `PathDocuments`: Returns the path to the user's documents directory +- `PathMusic`: Returns the path to the user's music directory +- `PathPictures`: Returns the path to the user's pictures directory +- `PathVideos`: Returns the path to the user's videos directory +- `PathTemplates`: Returns the path to the user's templates directory +- `PathPublicShare`: Returns the path to the user's public share directory + +```go + // Get the data home directory path + dataHomePath := app.Path(application.PathDataHome) + fmt.Println("DataHome path:", dataHomePath) + + // Output: DataHome path: /home/username/.local/share // Linux + // Output: DataHome path: /Users/username/Library/Application Support // macOS + // Output: DataHome path: C:\Users\Username\AppData\Roaming // Windows + + // Get the CacheHome directory path + cacheHomePath := app.Path(application.CacheHome) + fmt.Println("CacheHome path:", cacheHomePath) + + // Output: CacheHome path: /home/username/.cache // Linux + // Output: CacheHome path: /Users/username/Library/Caches // macOS + // Output: CacheHome path: C:\Users\Username\AppData\Local\Temp // Windows +``` + +## Paths +API: `Paths(selector Paths) []string` +`Paths(selector Path)` returns a list of paths for the given path type. It provides a cross-platform way to query common directory paths. + +The `Paths` type is an enum with the following values: +- `PathsDataDirs`: Returns the list of data directories +- `PathsConfigDirs`: Returns the list of configuration directories +- `PathsCacheDirs`: Returns the list of cache directories +- `PathsRuntimeDirs`: Returns the list of runtime directories + + --8<-- ./docs/en/API/application_window.md ./docs/en/API/application_menu.md diff --git a/mkdocs-website/docs/en/API/application_dialogs.md b/mkdocs-website/docs/en/API/application_dialogs.md index 9cd0980001d..db46e347186 100644 --- a/mkdocs-website/docs/en/API/application_dialogs.md +++ b/mkdocs-website/docs/en/API/application_dialogs.md @@ -1,4 +1,33 @@ +!!! warning "MacOS Dialogs and Application Lifecycle" + + If you show dialogs during application startup or file open events, you should set `ApplicationShouldTerminateAfterLastWindowClosed` to `false` to prevent the application from terminating when those dialogs close. Otherwise, the application may quit before your main window appears. + + ```go + app := application.New(application.Options{ + Mac: application.MacOptions{ + ApplicationShouldTerminateAfterLastWindowClosed: false, + }, + // ... rest of options + }) + ``` + + Alternatively, you can show startup dialogs after the main window has been displayed: + + ```go + var filename string + app.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(event *application.ApplicationEvent) { + filename = event.Context().Filename() + }) + + window.OnWindowEvent(events.Common.WindowShow, func(event *application.WindowEvent) { + application.InfoDialog(). + SetTitle("File Opened"). + SetMessage("Application opened with file: " + filename). + Show() + }) + ``` + ### ShowAboutDialog API: `ShowAboutDialog()` diff --git a/mkdocs-website/docs/en/API/application_events.md b/mkdocs-website/docs/en/API/application_events.md index 3b2b73d073e..fc024d4ad97 100644 --- a/mkdocs-website/docs/en/API/application_events.md +++ b/mkdocs-website/docs/en/API/application_events.md @@ -1,12 +1,42 @@ +### OnEvent -### On +API: +`OnEvent(name string, callback func(event *CustomEvent)) func()` + +`OnEvent()` registers an event listener for specific application events. The callback +function provided will be triggered when the corresponding event occurs. + +### OffEvent +API: +`OffEvent(name string)` + +`OffEvent()` removes an event listener for a specific named event specified. + +### OnMultipleEvent +API: +`OnMultipleEvent(name string, callback func(event *CustomEvent), counter int) func()` + +`OnMultipleEvent()` registers an event listener for X number of Events. The callback +function provided will be triggered `counter` times when the corresponding event occurs. + +### ResetEvents +API: +`ResetEvents()` + +`ResetEvents()` removes all event listeners for all application events. + +### OnApplicationEvent +API: +`OnApplicationEvent(eventType events.ApplicationEventType, callback func(event *ApplicationEvent)) func()` + +`OnApplicationEvent()` registers an event listener for specific application events. +The `eventType` is based on events.ApplicationEventType. See [ApplicationEventType](/API/events/#applicationevent) +### RegisterApplicationHook API: -`On(eventType events.ApplicationEventType, callback func(event *Event)) func()` +`RegisterApplicationEventHook(eventType events.ApplicationEventType, callback func(event *ApplicationEvent)) func()` -`On()` registers an event listener for specific application events. The callback -function provided will be triggered when the corresponding event occurs. The -function returns a function that can be called to remove the listener. +`RegisterApplicationEventHook()` registers a callback to be triggered based on specific application events. ### RegisterHook diff --git a/mkdocs-website/docs/en/API/event_hooks.md b/mkdocs-website/docs/en/API/event_hooks.md new file mode 100644 index 00000000000..bfc2caf3267 --- /dev/null +++ b/mkdocs-website/docs/en/API/event_hooks.md @@ -0,0 +1,119 @@ +wails3 provides an event system that allows for hooking into application and window events + +```go +// Notification of application start +application.RegisterApplicationEventHook(events.Common.ApplicationStarted, func(event *application.ApplicationEvent) { + app.Logger.Info("Application started!") +}) +``` + +```go +// Notification of system theme change +application.OnApplicationEvent(events.Common.ThemeChanged, func(event *application.ApplicationEvent) { + app.Logger.Info("System theme changed!") + if event.Context().IsDarkMode() { + app.Logger.Info("System is now using dark mode!") + } else { + app.Logger.Info("System is now using light mode!") + } +}) +``` + +```go +// Disable window closing by canceling the event +window.RegisterHook(events.Common.WindowClosing, func(e *application.WindowEvent) { + app.Logger.Info("Window 1 Closing? Nope! Not closing!") + e.Cancel() +}) +``` + +```go +// Notification of window focus +window.OnWindowEvent(events.Common.WindowFocus, func(e *application.WindowEvent) { + app.Logger.Info("[ApplicationEvent] Window focus!") +}) +``` + +### Application Events + +Application events are hookable events that can be registered with `application.RegisterApplicationEventHook()` +and `application.OnApplicationEvent()`. These events are based on `events.ApplicationEventType`. + +`events.Common.ApplicationStarted` +: Triggered when the application starts + +`events.Common.ThemeChanged` +: Triggered when the application theme changes + + +### Window Events + +`events.Common.WindowMaximised` +: Triggered when the window is maximised + +`events.Common.WindowUnmaximised` +: Triggered when the window is unmaximised + +`events.Common.WindowMinimised` +: Triggered when the window is minimised + +`events.Common.WindowUnminimised` +: Triggered when the window is unminimised + +`events.Common.WindowFullscreen` +: Triggered when the window is set to fullscreen + +`events.Common.WindowUnfullscreen` +: Triggered when the window is unfullscreened + +`events.Common.WindowRestored` +: Triggered when the window is restored + +`events.Common.WindowClosing` +: Triggered before the window closes + +`events.Common.WindowZoom` +: Triggered when the window is zoomed + +`events.Common.WindowZoomOut` +: Triggered when the window is zoomed out + +`events.Common.WindowZoomIn` +: Triggered when the window is zoomed in + +`events.Common.WindowZoomReset` +: Triggered when the window zoom is reset + +`events.Common.WindowFocus` +: Triggered when the window gains focus + +`events.Common.WindowLostFocus` +: Triggered when the window loses focus + +`events.Common.WindowShow` +: Triggered when the window is shown + +`events.Common.WindowHide` +: Triggered when the window is hidden + +`events.Common.WindowDPIChanged` +: Triggered when the window DPI changes + +`events.Common.WindowFilesDropped` +: Triggered when files are dropped on the window + +`events.Common.WindowRuntimeReady` +: Triggered when the window runtime is ready + +`events.Common.WindowDidMove` +: Triggered when the window is moved + +`events.Common.WindowDidResize` +: Triggered when the window is resized + +### OS-Specific Events +--8<-- +./docs/en/API/events_linux.md +./docs/en/API/events_windows.md +./docs/en/API/events_mac.md +--8<-- diff --git a/mkdocs-website/docs/en/API/events.md b/mkdocs-website/docs/en/API/events.md new file mode 100644 index 00000000000..3b58a55b67e --- /dev/null +++ b/mkdocs-website/docs/en/API/events.md @@ -0,0 +1,131 @@ +# Events + +## Event Hooks + +--8<-- +./docs/en/API/event_hooks.md +--8<-- + +## Custom Events +You can create your own custom events that can be emitted and received on both the frontend and backend. +Events are able to emitted at both the application and the window level. The receiver of the event gets data of where the +event was emitted from along with the data that was sent with the event. Events can be cancelled by the receiver. + +=== "Go" + ```go + app.OnEvent("event1", func(e *application.CustomEvent) { + app.Logger.Info("[Go] CustomEvent received", "name", e.Name, "data", e.Data, "sender", e.Sender, "cancelled", e.Cancelled) + app.Logger.Info("[Go]", e.Data[0].(string)) // Logs "Hello from JS" to the terminal + }) + + window.EmitEvent("event2", "Hello from Go") + ``` +=== "JS" + ```javascript + wails.Events.Emit("event1", "Hello from JS") + + wails.Events.On("event2", function(event) { + console.log("[JS] CustomEvent received", event) + console.log(event.data) // prints "Hello from Go" to the webview console + }) + + ``` + +### Emitting Events + +`application.EmitEvent(name string, data ...any)` +: Emits an event from the application instance + +`window.EmitEvent(name string, data ...any)` +: Emits an event from the window instance + +`wails.Events.Emit(event:wails.Events.EventData)` +: Emits an event from the frontend sending an object with `name` and `data` properties or the typescript type WailsEvent + +### Receiving Events +Events can be received on the application instance and the frontend with a couple options of how +you chose to receive them. You can register a single event listener that will trigger every time the event is emitted +or you can register an event listener that will only trigger a specific number of times. + +Golang + +`application.OnEvent(name string, handler func(data ...any))` +: Registers an event on the application instance this will trigger every time the event is emitted + +`application.OnMultipleEvent(name string, handler func(data ...any), count int)` +: Registers an event on the application instance this will trigger every time the event is emitted up to the count specified + +Frontend + +`wails.Events.On(name: string, callback: ()=>void)`, +: Registers an event on the frontend, this function returns a function that can be called to remove the event listener + +`wails.Events.Once(name: string, callback: ()=>void)`, +: Registers an event on the frontend that will only be called once, this function returns a function that can be called to remove the event listener + +`wails.Events.OnMultiple(name: string, callback: ()=>void, count: number)`, +: Registers an event on the frontend that will only be called `count` times, this function returns a function that can be called to remove the event listener + +### Removing Events +There are a few ways to remove events that are registered. All of the registration functions return a function that can be called to remove the event listeneer +in the frontend. There are additional functions provided to help remove events as well. + +Golang + +`application.OffEvent(name string, ...additionalNames string)` +: Removes an event listener with the specificed name + +`application.ResetEvents()` +: Removes all registered events and hooks + +Frontend + +`wails.Events.OffAll()` +: Removes all registered events + +`wails.Events.Off(name: string)` +: Removes an event listener with the specified name + + +## Event Types + +### ApplicationEvent +Returned when an application hook event is triggered. The event can be cancelled by calling the `Cancel()` method on the event. +```go +type ApplicationEvent struct { + Id uint + ctx *ApplicationEventContext + Cancelled bool +} + +// Cancel the event +func (a *ApplicationEvent) Cancel() {} +``` + +### WindowEvent +Returned when a window hook event is triggered. The event can be cancelled by calling the `Cancel()` method on the event. +```go +type WindowEvent struct { + ctx *WindowEventContext + Cancelled bool +} + +// Cancel the event +func (w *WindowEvent) Cancel() {} +``` + +### CustomEvent + +CustomEvent is returned when an event is being recieved it includes the name of the event, the data that was sent with the event, +the sender of the event, application or a specific window. The event can be cancelled by calling the `Cancel()` method on the event. +```go +type CustomEvent struct { + Name string `json:"name"` + Data any `json:"data"` + Sender string `json:"sender"` + Cancelled bool +} + +// Cancel the event +func (c *CustomEvent) Cancel() {} +``` diff --git a/mkdocs-website/docs/en/API/events_linux.md b/mkdocs-website/docs/en/API/events_linux.md new file mode 100644 index 00000000000..ec19fb143ae --- /dev/null +++ b/mkdocs-website/docs/en/API/events_linux.md @@ -0,0 +1,30 @@ +#### Linux Events + +##### Application Events + +`events.Linux.ApplicationStartup` +: Triggered when the application starts + +`events.Linux.SystemThemeChanged` +: Triggered when the system theme changes + +##### Window Events + +`events.Linux.WindowLoadChanged` +: Triggered when the window load changes + +`events.Linux.WindowDeleteEvent` +: Triggered when the window is deleted + +`events.Linux.WindowDidMove` +: Triggered when the window is moved + +`events.Linux.WindowDidResize` +: Triggered when the window is resized + +`events.Linux.WindowFocusIn` +: Triggered when the window gains focus + +`events.Linux.WindowFocusOut` +: Triggered when the window loses focus + diff --git a/mkdocs-website/docs/en/API/events_mac.md b/mkdocs-website/docs/en/API/events_mac.md new file mode 100644 index 00000000000..6373a5ca5aa --- /dev/null +++ b/mkdocs-website/docs/en/API/events_mac.md @@ -0,0 +1,371 @@ +#### macOS Events + +##### Application Events + +`events.Mac.ApplicationDidBecomeActive` +: Triggered when the application becomes active + +`events.Mac.ApplicationDidChangeBackingProperties` +: Triggered when the application changes backing properties + +`events.Mac.ApplicationDidChangeEffectiveAppearance` +: Triggered when the application changes effective appearance + +`events.Mac.ApplicationDidChangeIcon` +: Triggered when the application changes icon + +`events.Mac.ApplicationDidChangeOcclusionState` +: Triggered when the application changes occlusion state + +`events.Mac.ApplicationDidChangeScreenParameters` +: Triggered when the application changes screen parameters + +`events.Mac.ApplicationDidChangeStatusBarFrame` +: Triggered when the application changes status bar frame + +`events.Mac.ApplicationDidChangeStatusBarOrientation` +: Triggered when the application changes status bar orientation + +`events.Mac.ApplicationDidFinishLaunching` +: Triggered when the application finishes launching + +`events.Mac.ApplicationDidResignActiveNotification` +: Triggered when the application is no longer active + +`events.Mac.ApplicationDidHide` +: Triggered when the application is hidden + +`events.Mac.ApplicationDidUpdate` +: Triggered when the application updates + +`events.Mac.ApplicationWillBecomeActive` +: Triggered when the application is about to become active + +`events.Mac.ApplicationWillFinishLaunching` +: Triggered when the application is about to finish launching + +`events.Mac.ApplicationWillHide` +: Triggered when the application is about to hide + +`events.Mac.ApplicationWillResignActive` +: Triggered when the application is about to lose focus + +`events.Mac.ApplicationWillTerminate` +: Triggered when the application is about to terminate + +`events.Mac.ApplicationWillUnhide` +: Triggered when the application is about to unhide + +`events.Mac.ApplicationWillUpdate` +: Triggered when the application is about to update + +`events.Mac.ApplicationDidChangeTheme` +: Triggered when the application changes theme + +`events.Mac.MenuWillOpen` +: Triggered when the menu is about to open + +`events.Mac.MenuDidOpen` +: Triggered when the menu opens + +`events.Mac.MenuDidClose` +: Triggered when the menu closes + +`events.Mac.MenuWillSendAction` +: Triggered when the menu is about to send an action + +`events.Mac.MenuDidSendAction` +: Triggered when the menu sends an action + +`events.Mac.MenuWillHighlightItem` +: Triggered when the menu is about to highlight an item + +`events.Mac.MenuDidHighlightItem` +: Triggered when the menu highlights an item + +`events.Mac.MenuWillDisplayItem` +: Triggered when the menu is about to display an item + +`events.Mac.MenuDidDisplayItem` +: Triggered when the menu displays an item + +`events.Mac.MenuWillAddItem` +: Triggered when the menu is about to add an item + +`events.Mac.MenuDidAddItem` +: Triggered when the menu adds an item + +`events.Mac.MenuWillRemoveItem` +: Triggered when the menu is about to remove an item + +`events.Mac.MenuDidRemoveItem` +: Triggered when the menu removes an item + +`events.Mac.MenuWillBeginTracking` +: Triggered when the menu is about to begin tracking + +`events.Mac.MenuDidBeginTracking` +: Triggered when the menu begins tracking + +`events.Mac.MenuWillEndTracking` +: Triggered when the menu is about to end tracking + +`events.Mac.MenuDidEndTracking` +: Triggered when the menu ends tracking + +`events.Mac.MenuWillUpdate` +: Triggered when the menu is about to update + +`events.Mac.MenuDidUpdate` +: Triggered when the menu updates + +`events.Mac.MenuWillPopUp` +: Triggered when the menu is about to pop up + +`events.Mac.MenuDidPopUp` +: Triggered when the menu pops up + +`events.Mac.MenuWillSendActionToItem` +: Triggered when the menu is about to send an action to an item + +`events.Mac.MenuDidSendActionToItem` +: Triggered when the menu sends an action to an item + +##### Window Events + +`events.Mac.WindowDidBecomeKey` +: Triggered when the window becomes key + +`events.Mac.WindowDidBecomeMain` +: Triggered when the window becomes main + +`events.Mac.WindowDidBeginSheet` +: Triggered when the window begins a sheet + +`events.Mac.WindowDidChangeAlpha` +: Triggered when the window alpha changes + +`events.Mac.WindowDidChangeBackingLocation` +: Triggered when the window backing location changes + +`events.Mac.WindowDidChangeBackingProperties` +: Triggered when the window backing properties change + +`events.Mac.WindowDidChangeCollectionBehavior` +: Triggered when the window collection behavior changes + +`events.Mac.WindowDidChangeEffectiveAppearance` +: Triggered when the window effective appearance changes + +`events.Mac.WindowDidChangeOcclusionState` +: Triggered when the window occlusion state changes + +`events.Mac.WindowDidChangeOrderingMode` +: Triggered when the window ordering mode changes + +`events.Mac.WindowDidChangeScreen` +: Triggered when the window screen changes + +`events.Mac.WindowDidChangeScreenParameters` +: Triggered when the window screen parameters change + +`events.Mac.WindowDidChangeScreenProfile` +: Triggered when the window screen profile changes + +`events.Mac.WindowDidChangeScreenSpace` +: Triggered when the window screen space changes + +`events.Mac.WindowDidChangeScreenSpaceProperties` +: Triggered when the window screen space properties change + +`events.Mac.WindowDidChangeSharingType` +: Triggered when the window sharing type changes + +`events.Mac.WindowDidChangeSpace` +: Triggered when the window space changes + +`events.Mac.WindowDidChangeSpaceOrderingMode` +: Triggered when the window space ordering mode changes + +`events.Mac.WindowDidChangeTitle` +: Triggered when the window title changes + +`events.Mac.WindowDidChangeToolbar` +: Triggered when the window toolbar changes + +`events.Mac.WindowDidChangeVisibility` +: Triggered when the window visibility changes + +`events.Mac.WindowDidDeminiaturize` +: Triggered when the window is deminiaturized + +`events.Mac.WindowDidEndSheet` +: Triggered when the window ends a sheet + +`events.Mac.WindowDidEnterFullScreen` +: Triggered when the window enters fullscreen + +`events.Mac.WindowDidEnterVersionBrowser` +: Triggered when the window enters version browser + +`events.Mac.WindowDidExitFullScreen` +: Triggered when the window exits fullscreen + +`events.Mac.WindowDidExitVersionBrowser` +: Triggered when the window exits version browser + +`events.Mac.WindowDidExpose` +: Triggered when the window is exposed + +`events.Mac.WindowDidFocus` +: Triggered when the window is focused + +`events.Mac.WindowDidMiniaturize` +: Triggered when the window is miniaturized + +`events.Mac.WindowDidMove` +: Triggered when the window is moved + +`events.Mac.WindowDidOrderOffScreen` +: Triggered when the window is ordered off-screen + +`events.Mac.WindowDidOrderOnScreen` +: Triggered when the window is ordered on screen + +`events.Mac.WindowDidResignKey` +: Triggered when the window resigns key + +`events.Mac.WindowDidResignMain` +: Triggered when the window resigns main + +`events.Mac.WindowDidResize` +: Triggered when the window is resized + +`events.Mac.WindowDidUpdate` +: Triggered when the window updates + +`events.Mac.WindowDidUpdateAlpha` +: Triggered when the window alpha updates + +`events.Mac.WindowDidUpdateCollectionBehavior` +: Triggered when the window collection behavior updates + +`events.Mac.WindowDidUpdateCollectionProperties` +: Triggered when the window collection properties update + +`events.Mac.WindowDidUpdateShadow` +: Triggered when the window shadow updates + +`events.Mac.WindowDidUpdateTitle` +: Triggered when the window title updates + +`events.Mac.WindowDidUpdateToolbar` +: Triggered when the window toolbar updates + +`events.Mac.WindowDidUpdateVisibility` +: Triggered when the window visibility updates + +`events.Mac.WindowShouldClose` +: Triggered when the window should close + +`events.Mac.WindowWillBecomeKey` +: Triggered when the window will become key + +`events.Mac.WindowWillBecomeMain` +: Triggered when the window will become main + +`events.Mac.WindowWillBeginSheet` +: Triggered when the window will begin a sheet + +`events.Mac.WindowWillChangeOrderingMode` +: Triggered when the window will change ordering mode + +`events.Mac.WindowWillClose` +: Triggered when the window will close + +`events.Mac.WindowWillDeminiaturize` +: Triggered when the window will deminiaturize + +`events.Mac.WindowWillEnterFullScreen` +: Triggered when the window will enter fullscreen + +`events.Mac.WindowWillEnterVersionBrowser` +: Triggered when the window will enter version browser + +`events.Mac.WindowWillExitFullScreen` +: Triggered when the window will exit fullscreen + +`events.Mac.WindowWillExitVersionBrowser` +: Triggered when the window will exit version browser + +`events.Mac.WindowWillFocus` +: Triggered when the window will focus + +`events.Mac.WindowWillMiniaturize` +: Triggered when the window will miniaturize + +`events.Mac.WindowWillMove` +: Triggered when the window will move + +`events.Mac.WindowWillOrderOffScreen` +: Triggered when the window will order off-screen + +`events.Mac.WindowWillOrderOnScreen` +: Triggered when the window will order on screen` + +`events.Mac.WindowWillResignMain` +: Triggered when the window will resign main + +`events.Mac.WindowWillResize` +: Triggered when the window will resize + +`events.Mac.WindowWillUnfocus` +: Triggered when the window will unfocus` + +`events.Mac.WindowWillUpdate` +: Triggered when the window will update + +`events.Mac.WindowWillUpdateAlpha` +: Triggered when the window will update alpha + +`events.Mac.WindowWillUpdateCollectionBehavior` +: Triggered when the window will update collection behavior + +`events.Mac.WindowWillUpdateCollectionProperties` +: Triggered when the window will update collection properties + +`events.Mac.WindowWillUpdateShadow` +: Triggered when the window will update shadow + +`events.Mac.WindowWillUpdateTitle` +: Triggered when the window will update title + +`events.Mac.WindowWillUpdateToolbar` +: Triggered when the window will update toolbar + +`events.Mac.WindowWillUpdateVisibility` +: Triggered when the window will update visibility + +`events.Mac.WindowWillUseStandardFrame` +: Triggered when the window will use standard frame + +`events.Mac.WebviewDidStartProvisionalNavigation` +: Triggered when the webview starts a provisional navigation + +`events.Mac.WebviewDidReceiveServerRedirectForProvisionalNavigation` +: Triggered when the webview receives a server redirect for a provisional navigation + +`events.Mac.WebviewDidFinishNavigation` +: Triggered when the webview finishes navigation + +`events.Mac.WebviewDidCommitNavigation` +: Triggered when the webview commits navigation + +`events.Mac.WindowFileDraggingEntered` +: Triggered when files are dragged into the window` + +`events.Mac.WindowFileDraggingPerformed` +: Triggered when files are dragged in the window + +`events.Mac.WindowFileDraggingExited` +: Triggered when files are dragged out of the window diff --git a/mkdocs-website/docs/en/API/events_windows.md b/mkdocs-website/docs/en/API/events_windows.md new file mode 100644 index 00000000000..de81299bea0 --- /dev/null +++ b/mkdocs-website/docs/en/API/events_windows.md @@ -0,0 +1,79 @@ +#### Windows Events + +##### Application Events + +`events.Windows.ApplicationStarted` +: Triggered when the application starts + +`events.Windows.SystemThemeChanged` +: Triggered when the system theme changes + +`events.Windows.APMPowerStatusChange` +: Triggered when the system power status changes + +`events.Windows.APMSuspend` +: Triggered when the system suspends + +`events.Windows.APMResumeAutomatic` +: Triggered when the system resumes after a sleep + +`events.Windows.APMResumeSuspend` +: Triggered when the system resumes after a suspend and resume was triggered by the user + +##### Window Events + +`events.Windows.WebviewNavigationCompleted` +: Triggered when the webview navigation is completed + +`events.Windows.WindowInactive` +: Triggered when the window is inactive + +`events.Windows.WindowActive` +: Triggered when the window is active + +`events.Windows.ClickActive` +: Triggered when the window is activated via a click + +`events.Windows.MaximiseActive` +: Triggered when the window is maximised + +`events.Windows.UnMaximise` +: Triggered when the window is unmaximised + +`events.Windows.Fullscreen` +: Triggered when the window is set to fullscreen + +`events.Windows.UnFullscreen` +: Triggered when the window is exited from fullscreene + +`events.Windows.WindowRestore` +: Triggered when the window is restored + +`events.Windows.WindowMinimise` +: Triggered when the window is minimised + +`events.Windows.WindowUnminimise` +: Triggered when the window is unminimised + +`events.Windows.WindowClose` +: Triggered before the window closes +`events.Windows.WindowSetFocus` +: Triggered when the window gains keyboard focus + +`events.Windows.WindowKillFocus` +: Triggered when the window loses keyboard focus + +`events.Windows.WindowDragDrop` +: Triggered when files are dropped on the window + +`events.Windows.WindowDragEnter` +: Triggered when a drag enters the window + +`events.Windows.WindowDragLeave` +: Triggered when a drag leaves the window + +`events.Windows.WindowDragOver` +: Triggered when a drag is over the window + +`events.Windows.WindowDidMove` +: Triggered after a window has moved diff --git a/mkdocs-website/docs/en/changelog.md b/mkdocs-website/docs/en/changelog.md index 99231f19c98..f40a1f4f81f 100644 --- a/mkdocs-website/docs/en/changelog.md +++ b/mkdocs-website/docs/en/changelog.md @@ -17,15 +17,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- Events documentation to the mkdocs webite by [atterpac](https://github.com/atterpac) in [#3867](https://github.com/wailsapp/wails/pull/3867) +- Templates for sveltekit and sveltekit-ts that are set for non-SSR development by [atterpac](https://github.com/atterpac) in [#3829](https://github.com/wailsapp/wails/pull/3829) +- Update build assets using new `wails3 update build-assets` command by [leaanthony](https://github.com/leaanthony) +- Example to test the HTML Drag and Drop API by [FerroO2000](https://github.com/FerroO2000) in [#3856](https://github.com/wailsapp/wails/pull/3856) +- File Association support by [leaanthony](https://github.com/leaanthony) in [#3873](https://github.com/wailsapp/wails/pull/3873) +- New `wails3 generate runtime` command by [leaanthony](https://github.com/leaanthony) +- New `InitialPosition` option to specify if the window should be centered or positioned at the given X/Y location by [leaanthony](https://github.com/leaanthony) in [#3885](https://github.com/wailsapp/wails/pull/3885) +- Add `Path` & `Paths` methods to `application` package by [ansxuman](https://github.com/ansxuman) and [leaanthony](https://github.com/leaanthony) in [#3823](https://github.com/wailsapp/wails/pull/3823) + ### Changed - Taskfile refactor by [leaanthony](https://github.com/leaanthony) in [#3748](https://github.com/wailsapp/wails/pull/3748) - Upgrade to `go-webview2` v1.0.16 by [leaanthony](https://github.com/leaanthony) +- Fixed `Screen` type to include `ID` not `Id` by [etesam913](https://github.com/etesam913) in [#3778](https://github.com/wailsapp/wails/pull/3778) +- Update `go.mod.tmpl` wails version to support `application.ServiceOptions` by [northes](https://github.com/northes) in [#3836](https://github.com/wailsapp/wails/pull/3836) +- Fixed service name determination by [windom](https://github.com/windom/) in [#3827](https://github.com/wailsapp/wails/pull/3827) +- mkdocs serve now uses docker by [leaanthony](https://github.com/leaanthony) +- Consolidated dev config into `config.yml` by [leaanthony](https://github.com/leaanthony) + +### Fixed +- Fixed `AlwaysOnTop` not working on Mac by [leaanthony](https://github.com/leaanthony) in [#3841](https://github.com/wailsapp/wails/pull/3841) +- [darwin] Fixed `application.NewEditMenu` including a duplicate `PasteAndMatchStyle` role in the edit menu on Darwin by [johnmccabe](https://github.com/johnmccabe) in [#3839](https://github.com/wailsapp/wails/pull/3839) +- [linux] Fixed aarch64 compilation [#3840](https://github.com/wailsapp/wails/issues/3840) in [#3854](https://github.com/wailsapp/wails/pull/3854) by [kodflow](https://github.com/kodflow) ## v3.0.0-alpha.7 - 2024-09-18 ### Added - [windows] New DIP system for Enhanced High DPI Monitor Support by [mmghv](https://github.com/mmghv) in [#3665](https://github.com/wailsapp/wails/pull/3665) -- [windows] Window class name option by [windom](https://github.com/windom/) in [#3682](https://github.com/wailsapp/wails/pull/3682) +- [windows] Window class name option by [windom](https://github.com/windom/) in [#3682](https://github.com/wailsapp/wails/pull/3682) - Services have been expanded to provide plugin functionality. By [atterpac](https://github.com/atterpac) and [leaanthony](https://github.com/leaanthony) in [#3570](https://github.com/wailsapp/wails/pull/3570) ### Changed diff --git a/mkdocs-website/docs/en/learn/build.md b/mkdocs-website/docs/en/learn/build.md index 3df52962d30..7d2209a315e 100644 --- a/mkdocs-website/docs/en/learn/build.md +++ b/mkdocs-website/docs/en/learn/build.md @@ -213,3 +213,14 @@ You can also specify a custom configuration file and port: ```shell wails3 dev -config ./path/to/custom/config.yaml -port 8080 ``` + +### Using a browser for development + +Whilst v2 fully supported the use of a browser for development, it caused a lot of confusion. Applications that would +work in the browser would not necessarily work in the desktop application, as not all browser APIs are available in +webviews. + +For UI-focused development work, you still have the flexibility to use a browser in v3, by accessing the Vite URL at +http://localhost:9245 in dev mode. This gives you access to powerful browser dev tools while working on styling and +layout. When you're ready to test functionality like bindings and events, simply switch to the desktop view to ensure +everything works perfectly in the production environment. \ No newline at end of file diff --git a/mkdocs-website/docs/en/learn/guides/file-associations.md b/mkdocs-website/docs/en/learn/guides/file-associations.md new file mode 100644 index 00000000000..4aae0cc125d --- /dev/null +++ b/mkdocs-website/docs/en/learn/guides/file-associations.md @@ -0,0 +1,139 @@ +# File Associations + +File associations allow your application to handle specific file types when users open them. This is particularly useful for text editors, image viewers, or any application that works with specific file formats. This guide explains how to implement file associations in your Wails v3 application. + +## Overview + +File association support in Wails v3 is currently available for: + +- Windows (NSIS installer packages) +- macOS (application bundles) + +## Configuration + +File associations are configured in the `config.yml` file located in your project's `build` directory. + +### Basic Configuration + +To set up file associations: + +1. Open `build/config.yml` +2. Add your file associations under the `fileAssociations` section +3. Run `wails3 update build-assets` to update the build assets +4. Set the `FileAssociations` field in the application options +5. Package your application using `wails3 package` + +Here's an example configuration: + +```yaml +fileAssociations: + - ext: myapp + name: MyApp Document + description: MyApp Document File + iconName: myappFileIcon + role: Editor + - ext: custom + name: Custom Format + description: Custom File Format + iconName: customFileIcon + role: Editor +``` + +### Configuration Properties + +| Property | Description | Platform | +|-------------|------------------------------------------------------------------|----------| +| ext | File extension without the leading period (e.g., `txt`) | All | +| name | Display name for the file type | All | +| description | Description shown in file properties | Windows | +| iconName | Name of the icon file (without extension) in the build folder | All | +| role | Application's role for this file type (e.g., `Editor`, `Viewer`) | macOS | + +## Listening for File Open Events + +To handle file open events in your application, you can listen for the `events.Common.ApplicationOpenedWithFile` event: + +```go +func main() { + app := application.New(application.Options{ + Name: "MyApp", + FileAssociations: []string{".txt", ".md"}, // Specify supported extensions + }) + + // Listen for files being used to open the application + app.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(event *application.ApplicationEvent) { + associatedFile := event.Context().Filename() + application.InfoDialog().SetMessage("Application opened with file: " + associatedFile).Show() + }) + + // Create your window and run the app... +} + +``` +## Step-by-Step Tutorial + +Let's walk through setting up file associations for a simple text editor: + +### 1. Create Icons + + - Create icons for your file type (recommended sizes: 16x16, 32x32, 48x48, 256x256) + - Save the icons in your project's `build` folder + - Name them according to your `iconName` configuration (e.g., `textFileIcon.png`) + +!!! tip + You can use `wails3 generate icons` to generate the required icons for you. Run `wails3 generate icons --help` for more information. + +### 2. Configure File Associations + +Edit the `build/config.yml` file to add your file associations: + + ```yaml + # build/config.yml + fileAssociations: + - ext: txt + name: Text Document + description: Plain Text Document + iconName: textFileIcon + role: Editor + ``` + +### 3. Update Build Assets + +Run the following command to update the build assets: + + ```bash + wails3 update build-assets + ``` + +### 4. Set File Associations in the Application Options + +In your `main.go` file, set the `FileAssociations` field in the application options: + +```go + app := application.New(application.Options{ + Name: "MyApp", + FileAssociations: []string{".txt", ".md"}, // Specify supported extensions + }) +``` + +??? question "Why do the file extensions need to be set in the application config when it's set in `config.yml`?" + + On Windows, when a file is opened with a file association, the application is launched with the filename as the first argument to the application. + The application has no way of knowing if the first argument is a file or a command line argument, so it uses the `FileAssociations` field in the application options to determine if the first argument is an associated file or not. + +### 5. Package Your Application + +Package your application using the following command: + + ```bash + wails3 package + ``` + +The packaged application will be created in the `bin` directory. You can then install and test the application. + +## Additional Notes + +- Icons should be provided in PNG format in the build folder +- Testing file associations requires installing the packaged application + + diff --git a/mkdocs-website/docs/en/status.md b/mkdocs-website/docs/en/status.md index e4f9b389468..35cbf4cfa86 100644 --- a/mkdocs-website/docs/en/status.md +++ b/mkdocs-website/docs/en/status.md @@ -1,6 +1,6 @@ # Roadmap -## Current Status: Alpha 6 +## Current Status: Alpha 7 Our goal is to reach Beta status. This roadmap outlines the key features and improvements we need to implement before transitioning to Beta. Please note that this is a living document and may be updated as priorities shift or new insights emerge. @@ -20,5 +20,8 @@ The roadmap is a living document and is subject to change. If you have any suggestions, please open an issue. Each milestone will have a set of goals that we are aiming to achieve. These are subject to change. -## Known Issues +## Alpha 8 Status + +- In Progress: Add support for File Associations +- In Progress: Drag and Drop support for Linux diff --git a/mkdocs-website/mkdocs.yml b/mkdocs-website/mkdocs.yml index a6b0c586838..2d6c1008e17 100644 --- a/mkdocs-website/mkdocs.yml +++ b/mkdocs-website/mkdocs.yml @@ -66,6 +66,7 @@ markdown_extensions: - admonition - footnotes - md_in_html + - def_list - toc: permalink: '#' - pymdownx.emoji: @@ -150,12 +151,14 @@ nav: - Build System: learn/build.md - Guides: - Customising Windows: learn/guides/customising-windows.md + - File Associations: learn/guides/file-associations.md - Feedback: getting-started/feedback.md - Feedback: getting-started/feedback.md - What's New in v3?: whats-new.md - API: - Application: API/application.md - Window: API/window.md + - Events: API/events.md - System Tray: API/systray.md - Menu: API/menu.md - Main Thread: API/mainthread.md diff --git a/v3/cmd/wails3/main.go b/v3/cmd/wails3/main.go index cd9f520a601..0d229117ab4 100644 --- a/v3/cmd/wails3/main.go +++ b/v3/cmd/wails3/main.go @@ -35,6 +35,7 @@ func main() { app.NewSubCommandFunction("dev", "Run in Dev mode", commands.Dev) app.NewSubCommandFunction("package", "Package application", commands.Package) app.NewSubCommandFunction("doctor", "System status report", commands.Doctor) + task := app.NewSubCommand("task", "Run and list tasks") var taskFlags commands.RunTaskOptions task.AddFlags(&taskFlags) @@ -42,10 +43,16 @@ func main() { return commands.RunTask(&taskFlags, task.OtherArgs()) }) task.LongDescription("\nUsage: wails3 task [taskname] [flags]\n\nTasks are defined in the `Taskfile.yaml` file. See https://taskfile.dev for more information.") + generate := app.NewSubCommand("generate", "Generation tools") generate.NewSubCommandFunction("build-assets", "Generate build assets", commands.GenerateBuildAssets) generate.NewSubCommandFunction("icons", "Generate icons", commands.GenerateIcons) generate.NewSubCommandFunction("syso", "Generate Windows .syso file", commands.GenerateSyso) + generate.NewSubCommandFunction("runtime", "Generate the pre-built version of the runtime", commands.GenerateRuntime) + + update := app.NewSubCommand("update", "Update tools") + update.NewSubCommandFunction("build-assets", "Updates the build assets using the given config file", commands.UpdateBuildAssets) + bindgen := generate.NewSubCommand("bindings", "Generate bindings + models") var bindgenFlags flags.GenerateBindingsOptions bindgen.AddFlags(&bindgenFlags) @@ -59,6 +66,7 @@ func main() { plugin := app.NewSubCommand("service", "Service tools") plugin.NewSubCommandFunction("init", "Initialise a new service", commands.ServiceInit) + tool := app.NewSubCommand("tool", "Various tools") tool.NewSubCommandFunction("checkport", "Checks if a port is open. Useful for testing if vite is running.", commands.ToolCheckPort) tool.NewSubCommandFunction("watcher", "Watches files and runs a command when they change", commands.Watcher) @@ -67,6 +75,7 @@ func main() { app.NewSubCommandFunction("version", "Print the version", commands.Version) app.NewSubCommand("sponsor", "Sponsor the project").Action(openSponsor) + defer printFooter() err := app.Run() diff --git a/v3/examples/file-association/.gitignore b/v3/examples/file-association/.gitignore new file mode 100644 index 00000000000..4b51c175cca --- /dev/null +++ b/v3/examples/file-association/.gitignore @@ -0,0 +1,3 @@ +.task +bin +wails.syso \ No newline at end of file diff --git a/v3/examples/file-association/Inter Font License.txt b/v3/examples/file-association/Inter Font License.txt new file mode 100644 index 00000000000..b525cbf3ac4 --- /dev/null +++ b/v3/examples/file-association/Inter Font License.txt @@ -0,0 +1,93 @@ +Copyright 2020 The Inter Project Authors (https://github.com/rsms/inter) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/v3/examples/file-association/README.md b/v3/examples/file-association/README.md new file mode 100644 index 00000000000..64c18f8ae6a --- /dev/null +++ b/v3/examples/file-association/README.md @@ -0,0 +1,11 @@ +# File Association Sample Project + +This sample project demonstrates how to associate a file type with an application. +More info at: https://v3alpha.wails.io/learn/guides/file-associations/ + +To run the sample, follow these steps: + +1. Run `wails3 package` to generate the package. +2. On Windows, run the installer that was built in the `bin` directory. +3. Double-click on the `test.wails` file to open it with the application. +4. On macOS, double-click on the `test.wails` file and select the built application. \ No newline at end of file diff --git a/v3/examples/file-association/Taskfile.yml b/v3/examples/file-association/Taskfile.yml new file mode 100644 index 00000000000..f0dcbdbf099 --- /dev/null +++ b/v3/examples/file-association/Taskfile.yml @@ -0,0 +1,33 @@ +version: '3' + +includes: + common: ./build/Taskfile.common.yml + windows: ./build/Taskfile.windows.yml + darwin: ./build/Taskfile.darwin.yml + linux: ./build/Taskfile.linux.yml + +vars: + APP_NAME: "fileassoc" + BIN_DIR: "bin" + VITE_PORT: '{{.WAILS_VITE_PORT | default 9245}}' + +tasks: + build: + summary: Builds the application + cmds: + - task: "{{OS}}:build" + + package: + summary: Packages a production build of the application + cmds: + - task: "{{OS}}:package" + + run: + summary: Runs the application + cmds: + - task: "{{OS}}:run" + + dev: + summary: Runs the application in development mode + cmds: + - wails3 dev -config ./build/config.yml -port {{.VITE_PORT}} diff --git a/v3/examples/file-association/build/Info.dev.plist b/v3/examples/file-association/build/Info.dev.plist new file mode 100644 index 00000000000..327c94603e3 --- /dev/null +++ b/v3/examples/file-association/build/Info.dev.plist @@ -0,0 +1,32 @@ + + + + CFBundlePackageType + APPL + CFBundleName + My Product + CFBundleExecutable + fileassoc + CFBundleIdentifier + + CFBundleVersion + 0.1.0 + CFBundleGetInfoString + This is a comment + CFBundleShortVersionString + 0.1.0 + CFBundleIconFile + icons + LSMinimumSystemVersion + 10.13.0 + NSHighResolutionCapable + true + NSHumanReadableCopyright + © now, My Company + NSAppTransportSecurity + + NSAllowsLocalNetworking + + + + \ No newline at end of file diff --git a/v3/examples/file-association/build/Info.plist b/v3/examples/file-association/build/Info.plist new file mode 100644 index 00000000000..1b3520754af --- /dev/null +++ b/v3/examples/file-association/build/Info.plist @@ -0,0 +1,27 @@ + + + + CFBundlePackageType + APPL + CFBundleName + My Product + CFBundleExecutable + fileassoc + CFBundleIdentifier + + CFBundleVersion + 0.1.0 + CFBundleGetInfoString + This is a comment + CFBundleShortVersionString + 0.1.0 + CFBundleIconFile + icons + LSMinimumSystemVersion + 10.13.0 + NSHighResolutionCapable + true + NSHumanReadableCopyright + © now, My Company + + \ No newline at end of file diff --git a/v3/examples/file-association/build/Taskfile.common.yml b/v3/examples/file-association/build/Taskfile.common.yml new file mode 100644 index 00000000000..6aed2a68f56 --- /dev/null +++ b/v3/examples/file-association/build/Taskfile.common.yml @@ -0,0 +1,75 @@ +version: '3' + +tasks: + go:mod:tidy: + summary: Runs `go mod tidy` + internal: true + generates: + - go.sum + sources: + - go.mod + cmds: + - go mod tidy + + install:frontend:deps: + summary: Install frontend dependencies + dir: frontend + sources: + - package.json + - package-lock.json + generates: + - node_modules/* + preconditions: + - sh: npm version + msg: "Looks like npm isn't installed. Npm is part of the Node installer: https://nodejs.org/en/download/" + cmds: + - npm install + + build:frontend: + summary: Build the frontend project + dir: frontend + sources: + - "**/*" + generates: + - dist/* + deps: + - task: install:frontend:deps + - task: generate:bindings + cmds: + - npm run build -q + + generate:bindings: + summary: Generates bindings for the frontend + sources: + - "**/*.go" + - go.mod + - go.sum + generates: + - "frontend/bindings/**/*" + cmds: + - wails3 generate bindings -f '{{.BUILD_FLAGS}}'{{if .UseTypescript}} -ts{{end}} + + generate:icons: + summary: Generates Windows `.ico` and Mac `.icns` files from an image + dir: build + sources: + - "appicon.png" + generates: + - "icons.icns" + - "icons.ico" + cmds: + - wails3 generate icons -input appicon.png + + dev:frontend: + summary: Runs the frontend in development mode + dir: frontend + deps: + - task: install:frontend:deps + cmds: + - npm run dev -- --port {{.VITE_PORT}} --strictPort + + update:build-assets: + summary: Updates the build assets + dir: build + cmds: + - wails3 update build-assets -name "{{.APP_NAME}}" -binaryname "{{.APP_NAME}}" -config config.yml -dir . \ No newline at end of file diff --git a/v3/examples/file-association/build/Taskfile.darwin.yml b/v3/examples/file-association/build/Taskfile.darwin.yml new file mode 100644 index 00000000000..45db6d06731 --- /dev/null +++ b/v3/examples/file-association/build/Taskfile.darwin.yml @@ -0,0 +1,45 @@ +version: '3' + +includes: + common: Taskfile.common.yml + +tasks: + build: + summary: Creates a production build of the application + deps: + - task: common:go:mod:tidy + - task: common:build:frontend + - task: common:generate:icons + cmds: + - go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}} + vars: + BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l"{{end}}' + env: + GOOS: darwin + CGO_ENABLED: 1 + GOARCH: '{{.ARCH | default ARCH}}' + CGO_CFLAGS: "-mmacosx-version-min=10.15" + CGO_LDFLAGS: "-mmacosx-version-min=10.15" + MACOSX_DEPLOYMENT_TARGET: "10.15" + PRODUCTION: '{{.PRODUCTION | default "false"}}' + + package: + summary: Packages a production build of the application into a `.app` bundle + deps: + - task: build + vars: + PRODUCTION: "true" + cmds: + - task: create:app:bundle + + create:app:bundle: + summary: Creates an `.app` bundle + cmds: + - mkdir -p {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/{MacOS,Resources} + - cp build/icons.icns {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/Resources + - cp {{.BIN_DIR}}/{{.APP_NAME}} {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents/MacOS + - cp build/Info.plist {{.BIN_DIR}}/{{.APP_NAME}}.app/Contents + + run: + cmds: + - '{{.BIN_DIR}}/{{.APP_NAME}}' diff --git a/v3/examples/file-association/build/Taskfile.linux.yml b/v3/examples/file-association/build/Taskfile.linux.yml new file mode 100644 index 00000000000..814ee0ae130 --- /dev/null +++ b/v3/examples/file-association/build/Taskfile.linux.yml @@ -0,0 +1,66 @@ +version: '3' + +includes: + common: Taskfile.common.yml + +tasks: + build: + summary: Builds the application for Linux + deps: + - task: common:go:mod:tidy + - task: common:build:frontend + - task: common:generate:icons + cmds: + - go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}} + vars: + BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s"{{else}}-gcflags=all="-l"{{end}}' + env: + GOOS: linux + CGO_ENABLED: 1 + GOARCH: '{{.ARCH | default ARCH}}' + PRODUCTION: '{{.PRODUCTION | default "false"}}' + + package: + summary: Packages a production build of the application for Linux + deps: + - task: build + vars: + PRODUCTION: "true" + cmds: + - task: create:appimage + + create:appimage: + summary: Creates an AppImage + dir: build/appimage + deps: + - task: build + vars: + PRODUCTION: "true" + - task: generate:dotdesktop + cmds: + - cp {{.APP_BINARY}} {{.APP_NAME}} + - cp ../appicon.png appicon.png + - wails3 generate appimage -binary {{.APP_NAME}} -icon {{.ICON}} -desktopfile {{.DESKTOP_FILE}} -outputdir {{.OUTPUT_DIR}} -builddir {{.ROOT_DIR}}/build/appimage + vars: + APP_NAME: '{{.APP_NAME}}' + APP_BINARY: '../../bin/{{.APP_NAME}}' + ICON: '../appicon.png' + DESKTOP_FILE: '{{.APP_NAME}}.desktop' + OUTPUT_DIR: '../../bin' + + generate:dotdesktop: + summary: Generates a `.desktop` file + dir: build + cmds: + - mkdir -p {{.ROOT_DIR}}/build/appimage + - wails3 generate .desktop -name "{{.APP_NAME}}" -exec "{{.EXEC}}" -icon "{{.ICON}}" -outputfile {{.ROOT_DIR}}/build/appimage/{{.APP_NAME}}.desktop -categories "{{.CATEGORIES}}" + vars: + APP_NAME: '{{.APP_NAME}}' + EXEC: '{{.APP_NAME}}' + ICON: 'appicon' + CATEGORIES: 'Development;' + OUTPUTFILE: '{{.ROOT_DIR}}/build/appimage/{{.APP_NAME}}.desktop' + + run: + cmds: + - '{{.BIN_DIR}}/{{.APP_NAME}}' diff --git a/v3/examples/file-association/build/Taskfile.windows.yml b/v3/examples/file-association/build/Taskfile.windows.yml new file mode 100644 index 00000000000..f815bd0ae5c --- /dev/null +++ b/v3/examples/file-association/build/Taskfile.windows.yml @@ -0,0 +1,52 @@ +version: '3' + +includes: + common: Taskfile.common.yml + +tasks: + build: + summary: Builds the application for Windows + deps: + - task: common:go:mod:tidy + - task: common:build:frontend + - task: common:generate:icons + - task: generate:syso + cmds: + - go build {{.BUILD_FLAGS}} -o {{.BIN_DIR}}/{{.APP_NAME}}.exe + vars: + BUILD_FLAGS: '{{if eq .PRODUCTION "true"}}-tags production -trimpath -ldflags="-w -s -H windowsgui"{{else}}-gcflags=all="-l"{{end}}' + env: + GOOS: windows + CGO_ENABLED: 0 + GOARCH: '{{.ARCH | default ARCH}}' + PRODUCTION: '{{.PRODUCTION | default "false"}}' + + package: + summary: Packages a production build of the application into a `.exe` bundle + cmds: + - task: create:nsis:installer + + generate:syso: + summary: Generates Windows `.syso` file + dir: build + cmds: + - wails3 generate syso -arch {{.ARCH}} -icon icon.ico -manifest wails.exe.manifest -info info.json -out ../wails.syso + vars: + ARCH: '{{.ARCH | default ARCH}}' + + create:nsis:installer: + summary: Creates an NSIS installer + dir: build/nsis + deps: + - task: build + vars: + PRODUCTION: "true" + cmds: + - makensis -DARG_WAILS_{{.ARG_FLAG}}_BINARY="{{.ROOT_DIR}}\{{.BIN_DIR}}\{{.APP_NAME}}.exe" project.nsi + vars: + ARCH: '{{.ARCH | default ARCH}}' + ARG_FLAG: '{{if eq .ARCH "amd64"}}AMD64{{else}}ARM64{{end}}' + + run: + cmds: + - '{{.BIN_DIR}}\\{{.APP_NAME}}.exe' \ No newline at end of file diff --git a/v3/examples/file-association/build/appicon.png b/v3/examples/file-association/build/appicon.png new file mode 100644 index 00000000000..63617fe4f74 Binary files /dev/null and b/v3/examples/file-association/build/appicon.png differ diff --git a/v3/examples/file-association/build/appimage/build.sh b/v3/examples/file-association/build/appimage/build.sh new file mode 100644 index 00000000000..fcba535e54e --- /dev/null +++ b/v3/examples/file-association/build/appimage/build.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +# Copyright (c) 2018-Present Lea Anthony +# SPDX-License-Identifier: MIT + +# Fail script on any error +set -euxo pipefail + +# Define variables +APP_DIR="${APP_NAME}.AppDir" + +# Create AppDir structure +mkdir -p "${APP_DIR}/usr/bin" +cp -r "${APP_BINARY}" "${APP_DIR}/usr/bin/" +cp "${ICON_PATH}" "${APP_DIR}/" +cp "${DESKTOP_FILE}" "${APP_DIR}/" + +# Download linuxdeploy and make it executable +wget -q -4 -N https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage +chmod +x linuxdeploy-x86_64.AppImage + +# Run linuxdeploy to bundle the application +./linuxdeploy-x86_64.AppImage --appdir "${APP_DIR}" --output appimage + +# Rename the generated AppImage +mv "${APP_NAME}*.AppImage" "${APP_NAME}.AppImage" + diff --git a/v3/examples/file-association/build/config.yml b/v3/examples/file-association/build/config.yml new file mode 100644 index 00000000000..dd6d2070550 --- /dev/null +++ b/v3/examples/file-association/build/config.yml @@ -0,0 +1,32 @@ +# This file contains the configuration for this project. +# When you update `info` or `fileAssociations`, run `wails3 task common:update:build-assets` to update the assets. +# Note that this will overwrite any changes you have made to the assets. +version: '3' + +# This information is used to generate the build assets. +info: + companyName: "My Company" # The name of the company + productName: "My Product" # The name of the application + productIdentifier: "com.mycompany.myproduct" # The unique product identifier + description: "A program that does X" # The application description + copyright: "(c) 2024, My Company" # Copyright text + comments: "Some Product Comments" # Comments + version: "v0.0.1" # The application version + +# File Associations +# More information at: https://v3alpha.wails.io/noit/done/yet +fileAssociations: + - ext: wails + name: Wails + description: Wails Application File + iconName: icon + role: Editor +# - ext: jpg +# name: JPEG +# description: Image File +# iconName: jpegFileIcon +# role: Editor + +# Other data +other: + - name: My Other Data \ No newline at end of file diff --git a/v3/internal/commands/build_assets/devmode.config.tmpl.yaml b/v3/examples/file-association/build/devmode.config.yaml similarity index 100% rename from v3/internal/commands/build_assets/devmode.config.tmpl.yaml rename to v3/examples/file-association/build/devmode.config.yaml diff --git a/v3/examples/file-association/build/icon.ico b/v3/examples/file-association/build/icon.ico new file mode 100644 index 00000000000..bfa0690b7f8 Binary files /dev/null and b/v3/examples/file-association/build/icon.ico differ diff --git a/v3/examples/file-association/build/icons.icns b/v3/examples/file-association/build/icons.icns new file mode 100644 index 00000000000..1b5bd4c86c4 Binary files /dev/null and b/v3/examples/file-association/build/icons.icns differ diff --git a/v3/examples/file-association/build/info.json b/v3/examples/file-association/build/info.json new file mode 100644 index 00000000000..850b2b5b0c4 --- /dev/null +++ b/v3/examples/file-association/build/info.json @@ -0,0 +1,15 @@ +{ + "fixed": { + "file_version": "0.1.0" + }, + "info": { + "0000": { + "ProductVersion": "0.1.0", + "CompanyName": "My Company", + "FileDescription": "My Product Description", + "LegalCopyright": "© now, My Company", + "ProductName": "My Product", + "Comments": "This is a comment" + } + } +} \ No newline at end of file diff --git a/v3/examples/file-association/build/nsis/project.nsi b/v3/examples/file-association/build/nsis/project.nsi new file mode 100644 index 00000000000..11ebc1ec76f --- /dev/null +++ b/v3/examples/file-association/build/nsis/project.nsi @@ -0,0 +1,112 @@ +Unicode true + +#### +## Please note: Template replacements don't work in this file. They are provided with default defines like +## mentioned underneath. +## If the keyword is not defined, "wails_tools.nsh" will populate them. +## If they are defined here, "wails_tools.nsh" will not touch them. This allows you to use this project.nsi manually +## from outside of Wails for debugging and development of the installer. +## +## For development first make a wails nsis build to populate the "wails_tools.nsh": +## > wails build --target windows/amd64 --nsis +## Then you can call makensis on this file with specifying the path to your binary: +## For a AMD64 only installer: +## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app.exe +## For a ARM64 only installer: +## > makensis -DARG_WAILS_ARM64_BINARY=..\..\bin\app.exe +## For a installer with both architectures: +## > makensis -DARG_WAILS_AMD64_BINARY=..\..\bin\app-amd64.exe -DARG_WAILS_ARM64_BINARY=..\..\bin\app-arm64.exe +#### +## The following information is taken from the wails_tools.nsh file, but they can be overwritten here. +#### +## !define INFO_PROJECTNAME "my-project" # Default "fileassoc" +## !define INFO_COMPANYNAME "My Company" # Default "My Company" +## !define INFO_PRODUCTNAME "My Product Name" # Default "My Product" +## !define INFO_PRODUCTVERSION "1.0.0" # Default "0.1.0" +## !define INFO_COPYRIGHT "(c) Now, My Company" # Default "© now, My Company" +### +## !define PRODUCT_EXECUTABLE "Application.exe" # Default "${INFO_PROJECTNAME}.exe" +## !define UNINST_KEY_NAME "UninstKeyInRegistry" # Default "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}" +#### +## !define REQUEST_EXECUTION_LEVEL "admin" # Default "admin" see also https://nsis.sourceforge.io/Docs/Chapter4.html +#### +## Include the wails tools +#### +!include "wails_tools.nsh" + +# The version information for this two must consist of 4 parts +VIProductVersion "${INFO_PRODUCTVERSION}.0" +VIFileVersion "${INFO_PRODUCTVERSION}.0" + +VIAddVersionKey "CompanyName" "${INFO_COMPANYNAME}" +VIAddVersionKey "FileDescription" "${INFO_PRODUCTNAME} Installer" +VIAddVersionKey "ProductVersion" "${INFO_PRODUCTVERSION}" +VIAddVersionKey "FileVersion" "${INFO_PRODUCTVERSION}" +VIAddVersionKey "LegalCopyright" "${INFO_COPYRIGHT}" +VIAddVersionKey "ProductName" "${INFO_PRODUCTNAME}" + +# Enable HiDPI support. https://nsis.sourceforge.io/Reference/ManifestDPIAware +ManifestDPIAware true + +!include "MUI.nsh" + +!define MUI_ICON "..\icon.ico" +!define MUI_UNICON "..\icon.ico" +# !define MUI_WELCOMEFINISHPAGE_BITMAP "resources\leftimage.bmp" #Include this to add a bitmap on the left side of the Welcome Page. Must be a size of 164x314 +!define MUI_FINISHPAGE_NOAUTOCLOSE # Wait on the INSTFILES page so the user can take a look into the details of the installation steps +!define MUI_ABORTWARNING # This will warn the user if they exit from the installer. + +!insertmacro MUI_PAGE_WELCOME # Welcome to the installer page. +# !insertmacro MUI_PAGE_LICENSE "resources\eula.txt" # Adds a EULA page to the installer +!insertmacro MUI_PAGE_DIRECTORY # In which folder install page. +!insertmacro MUI_PAGE_INSTFILES # Installing page. +!insertmacro MUI_PAGE_FINISH # Finished installation page. + +!insertmacro MUI_UNPAGE_INSTFILES # Uninstalling page + +!insertmacro MUI_LANGUAGE "English" # Set the Language of the installer + +## The following two statements can be used to sign the installer and the uninstaller. The path to the binaries are provided in %1 +#!uninstfinalize 'signtool --file "%1"' +#!finalize 'signtool --file "%1"' + +Name "${INFO_PRODUCTNAME}" +OutFile "..\..\bin\${INFO_PROJECTNAME}-${ARCH}-installer.exe" # Name of the installer's file. +InstallDir "$PROGRAMFILES64\${INFO_COMPANYNAME}\${INFO_PRODUCTNAME}" # Default installing folder ($PROGRAMFILES is Program Files folder). +ShowInstDetails show # This will always show the installation details. + +Function .onInit + !insertmacro wails.checkArchitecture +FunctionEnd + +Section + !insertmacro wails.setShellContext + + !insertmacro wails.webview2runtime + + SetOutPath $INSTDIR + + !insertmacro wails.files + + CreateShortcut "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}" + CreateShortCut "$DESKTOP\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}" + + !insertmacro wails.associateFiles + + !insertmacro wails.writeUninstaller +SectionEnd + +Section "uninstall" + !insertmacro wails.setShellContext + + RMDir /r "$AppData\${PRODUCT_EXECUTABLE}" # Remove the WebView2 DataPath + + RMDir /r $INSTDIR + + Delete "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" + Delete "$DESKTOP\${INFO_PRODUCTNAME}.lnk" + + !insertmacro wails.unassociateFiles + + !insertmacro wails.deleteUninstaller +SectionEnd diff --git a/v3/examples/file-association/build/nsis/wails_tools.nsh b/v3/examples/file-association/build/nsis/wails_tools.nsh new file mode 100644 index 00000000000..d49f6c803f4 --- /dev/null +++ b/v3/examples/file-association/build/nsis/wails_tools.nsh @@ -0,0 +1,218 @@ +# DO NOT EDIT - Generated automatically by `wails build` + +!include "x64.nsh" +!include "WinVer.nsh" +!include "FileFunc.nsh" + +!ifndef INFO_PROJECTNAME + !define INFO_PROJECTNAME "fileassoc" +!endif +!ifndef INFO_COMPANYNAME + !define INFO_COMPANYNAME "My Company" +!endif +!ifndef INFO_PRODUCTNAME + !define INFO_PRODUCTNAME "My Product" +!endif +!ifndef INFO_PRODUCTVERSION + !define INFO_PRODUCTVERSION "0.1.0" +!endif +!ifndef INFO_COPYRIGHT + !define INFO_COPYRIGHT "© now, My Company" +!endif +!ifndef PRODUCT_EXECUTABLE + !define PRODUCT_EXECUTABLE "${INFO_PROJECTNAME}.exe" +!endif +!ifndef UNINST_KEY_NAME + !define UNINST_KEY_NAME "${INFO_COMPANYNAME}${INFO_PRODUCTNAME}" +!endif +!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINST_KEY_NAME}" + +!ifndef REQUEST_EXECUTION_LEVEL + !define REQUEST_EXECUTION_LEVEL "admin" +!endif + +RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}" + +!ifdef ARG_WAILS_AMD64_BINARY + !define SUPPORTS_AMD64 +!endif + +!ifdef ARG_WAILS_ARM64_BINARY + !define SUPPORTS_ARM64 +!endif + +!ifdef SUPPORTS_AMD64 + !ifdef SUPPORTS_ARM64 + !define ARCH "amd64_arm64" + !else + !define ARCH "amd64" + !endif +!else + !ifdef SUPPORTS_ARM64 + !define ARCH "arm64" + !else + !error "Wails: Undefined ARCH, please provide at least one of ARG_WAILS_AMD64_BINARY or ARG_WAILS_ARM64_BINARY" + !endif +!endif + +!macro wails.checkArchitecture + !ifndef WAILS_WIN10_REQUIRED + !define WAILS_WIN10_REQUIRED "This product is only supported on Windows 10 (Server 2016) and later." + !endif + + !ifndef WAILS_ARCHITECTURE_NOT_SUPPORTED + !define WAILS_ARCHITECTURE_NOT_SUPPORTED "This product can't be installed on the current Windows architecture. Supports: ${ARCH}" + !endif + + ${If} ${AtLeastWin10} + !ifdef SUPPORTS_AMD64 + ${if} ${IsNativeAMD64} + Goto ok + ${EndIf} + !endif + + !ifdef SUPPORTS_ARM64 + ${if} ${IsNativeARM64} + Goto ok + ${EndIf} + !endif + + IfSilent silentArch notSilentArch + silentArch: + SetErrorLevel 65 + Abort + notSilentArch: + MessageBox MB_OK "${WAILS_ARCHITECTURE_NOT_SUPPORTED}" + Quit + ${else} + IfSilent silentWin notSilentWin + silentWin: + SetErrorLevel 64 + Abort + notSilentWin: + MessageBox MB_OK "${WAILS_WIN10_REQUIRED}" + Quit + ${EndIf} + + ok: +!macroend + +!macro wails.files + !ifdef SUPPORTS_AMD64 + ${if} ${IsNativeAMD64} + File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_AMD64_BINARY}" + ${EndIf} + !endif + + !ifdef SUPPORTS_ARM64 + ${if} ${IsNativeARM64} + File "/oname=${PRODUCT_EXECUTABLE}" "${ARG_WAILS_ARM64_BINARY}" + ${EndIf} + !endif +!macroend + +!macro wails.writeUninstaller + WriteUninstaller "$INSTDIR\uninstall.exe" + + SetRegView 64 + WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "${INFO_COMPANYNAME}" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayName" "${INFO_PRODUCTNAME}" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayVersion" "${INFO_PRODUCTVERSION}" + WriteRegStr HKLM "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\${PRODUCT_EXECUTABLE}" + WriteRegStr HKLM "${UNINST_KEY}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" + WriteRegStr HKLM "${UNINST_KEY}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" + + ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 + IntFmt $0 "0x%08X" $0 + WriteRegDWORD HKLM "${UNINST_KEY}" "EstimatedSize" "$0" +!macroend + +!macro wails.deleteUninstaller + Delete "$INSTDIR\uninstall.exe" + + SetRegView 64 + DeleteRegKey HKLM "${UNINST_KEY}" +!macroend + +!macro wails.setShellContext + ${If} ${REQUEST_EXECUTION_LEVEL} == "admin" + SetShellVarContext all + ${else} + SetShellVarContext current + ${EndIf} +!macroend + +# Install webview2 by launching the bootstrapper +# See https://docs.microsoft.com/en-us/microsoft-edge/webview2/concepts/distribution#online-only-deployment +!macro wails.webview2runtime + !ifndef WAILS_INSTALL_WEBVIEW_DETAILPRINT + !define WAILS_INSTALL_WEBVIEW_DETAILPRINT "Installing: WebView2 Runtime" + !endif + + SetRegView 64 + # If the admin key exists and is not empty then webview2 is already installed + ReadRegStr $0 HKLM "SOFTWARE\WOW6432Node\Microsoft\EdgeUpdate\Clients\{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" + ${If} $0 != "" + Goto ok + ${EndIf} + + ${If} ${REQUEST_EXECUTION_LEVEL} == "user" + # If the installer is run in user level, check the user specific key exists and is not empty then webview2 is already installed + ReadRegStr $0 HKCU "Software\Microsoft\EdgeUpdate\Clients{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}" "pv" + ${If} $0 != "" + Goto ok + ${EndIf} + ${EndIf} + + SetDetailsPrint both + DetailPrint "${WAILS_INSTALL_WEBVIEW_DETAILPRINT}" + SetDetailsPrint listonly + + InitPluginsDir + CreateDirectory "$pluginsdir\webview2bootstrapper" + SetOutPath "$pluginsdir\webview2bootstrapper" + File "MicrosoftEdgeWebview2Setup.exe" + ExecWait '"$pluginsdir\webview2bootstrapper\MicrosoftEdgeWebview2Setup.exe" /silent /install' + + SetDetailsPrint both + ok: +!macroend + +# Copy of APP_ASSOCIATE and APP_UNASSOCIATE macros from here https://gist.github.com/nikku/281d0ef126dbc215dd58bfd5b3a5cd5b +!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND + ; Backup the previously associated file class + ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" "" + WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0" + + WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}" + + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}` + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}` + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" "open" + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open" "" `${COMMANDTEXT}` + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open\command" "" `${COMMAND}` +!macroend + +!macro APP_UNASSOCIATE EXT FILECLASS + ; Backup the previously associated file class + ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" `${FILECLASS}_backup` + WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "$R0" + + DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}` +!macroend + +!macro wails.associateFiles + ; Create file associations + + !insertmacro APP_ASSOCIATE "wails" "Wails" "Wails Application File" "$INSTDIR\icon.ico" "Open with ${INFO_PRODUCTNAME}" "$INSTDIR\${PRODUCT_EXECUTABLE} $\"%1$\"" + File "..\icon.ico" + +!macroend + +!macro wails.unassociateFiles + ; Delete app associations + + !insertmacro APP_UNASSOCIATE "wails" "Wails" + Delete "$INSTDIR\icon.ico" + +!macroend \ No newline at end of file diff --git a/v3/examples/file-association/build/wails.exe.manifest b/v3/examples/file-association/build/wails.exe.manifest new file mode 100644 index 00000000000..03a121e4075 --- /dev/null +++ b/v3/examples/file-association/build/wails.exe.manifest @@ -0,0 +1,15 @@ + + + + + + + + + + + true/pm + permonitorv2,permonitor + + + \ No newline at end of file diff --git a/v3/examples/file-association/frontend/bindings/changeme/greetservice.js b/v3/examples/file-association/frontend/bindings/changeme/greetservice.js new file mode 100644 index 00000000000..860020abd39 --- /dev/null +++ b/v3/examples/file-association/frontend/bindings/changeme/greetservice.js @@ -0,0 +1,16 @@ +// @ts-check +// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL +// This file is automatically generated. DO NOT EDIT + +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore: Unused imports +import {Call as $Call, Create as $Create} from "@wailsio/runtime"; + +/** + * @param {string} name + * @returns {Promise & { cancel(): void }} + */ +export function Greet(name) { + let $resultPromise = /** @type {any} */($Call.ByID(1411160069, name)); + return $resultPromise; +} diff --git a/v3/examples/file-association/frontend/bindings/changeme/index.js b/v3/examples/file-association/frontend/bindings/changeme/index.js new file mode 100644 index 00000000000..fdf1ff435a9 --- /dev/null +++ b/v3/examples/file-association/frontend/bindings/changeme/index.js @@ -0,0 +1,8 @@ +// @ts-check +// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL +// This file is automatically generated. DO NOT EDIT + +import * as GreetService from "./greetservice.js"; +export { + GreetService +}; diff --git a/v3/examples/file-association/frontend/index.html b/v3/examples/file-association/frontend/index.html new file mode 100644 index 00000000000..78ae28f3abf --- /dev/null +++ b/v3/examples/file-association/frontend/index.html @@ -0,0 +1,35 @@ + + + + + + + + Wails App + + + + + + + + + + + + Wails + Javascript + + Please enter your name below 👇 + + + Greet + + + + + + + diff --git a/v3/examples/file-association/frontend/main.js b/v3/examples/file-association/frontend/main.js new file mode 100644 index 00000000000..c24b3b1ef3a --- /dev/null +++ b/v3/examples/file-association/frontend/main.js @@ -0,0 +1,21 @@ +import {GreetService} from "./bindings/changeme"; +import {Events} from "@wailsio/runtime"; + +const resultElement = document.getElementById('result'); +const timeElement = document.getElementById('time'); + +window.doGreet = () => { + let name = document.getElementById('name').value; + if (!name) { + name = 'anonymous'; + } + GreetService.Greet(name).then((result) => { + resultElement.innerText = result; + }).catch((err) => { + console.log(err); + }); +} + +Events.On('time', (time) => { + timeElement.innerText = time.data; +}); diff --git a/v3/examples/file-association/frontend/package-lock.json b/v3/examples/file-association/frontend/package-lock.json new file mode 100644 index 00000000000..9ba47fffa8e --- /dev/null +++ b/v3/examples/file-association/frontend/package-lock.json @@ -0,0 +1,860 @@ +{ + "name": "frontend", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "0.0.0", + "devDependencies": { + "@wailsio/runtime": "latest", + "vite": "^5.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz", + "integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz", + "integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz", + "integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz", + "integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz", + "integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz", + "integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz", + "integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz", + "integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz", + "integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz", + "integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz", + "integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz", + "integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz", + "integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz", + "integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz", + "integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz", + "integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz", + "integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz", + "integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true + }, + "node_modules/@wailsio/runtime": { + "version": "3.0.0-alpha.28", + "resolved": "https://registry.npmjs.org/@wailsio/runtime/-/runtime-3.0.0-alpha.28.tgz", + "integrity": "sha512-caMnAcKxxDrIWYgCZAMY2kdL++X4ehO2+JvH5na21xfDqz3VnHkEjxsH3jfhgd34M8LY80QEH8iqoMYytDFE/g==", + "dev": true, + "dependencies": { + "nanoid": "^5.0.7" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/nanoid": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.8.tgz", + "integrity": "sha512-TcJPw+9RV9dibz1hHUzlLVy8N4X9TnwirAjrU08Juo6BNKggzVfP2ZJ/3ZUSq15Xl5i85i+Z89XBO90pB2PghQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/rollup": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz", + "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.3", + "@rollup/rollup-android-arm64": "4.24.3", + "@rollup/rollup-darwin-arm64": "4.24.3", + "@rollup/rollup-darwin-x64": "4.24.3", + "@rollup/rollup-freebsd-arm64": "4.24.3", + "@rollup/rollup-freebsd-x64": "4.24.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.3", + "@rollup/rollup-linux-arm-musleabihf": "4.24.3", + "@rollup/rollup-linux-arm64-gnu": "4.24.3", + "@rollup/rollup-linux-arm64-musl": "4.24.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3", + "@rollup/rollup-linux-riscv64-gnu": "4.24.3", + "@rollup/rollup-linux-s390x-gnu": "4.24.3", + "@rollup/rollup-linux-x64-gnu": "4.24.3", + "@rollup/rollup-linux-x64-musl": "4.24.3", + "@rollup/rollup-win32-arm64-msvc": "4.24.3", + "@rollup/rollup-win32-ia32-msvc": "4.24.3", + "@rollup/rollup-win32-x64-msvc": "4.24.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vite": { + "version": "5.4.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", + "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + } + } +} diff --git a/v3/examples/file-association/frontend/package.json b/v3/examples/file-association/frontend/package.json new file mode 100644 index 00000000000..2642d7a4157 --- /dev/null +++ b/v3/examples/file-association/frontend/package.json @@ -0,0 +1,16 @@ +{ + "name": "frontend", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build --minify false --mode development", + "build:prod": "vite build --mode production", + "preview": "vite preview" + }, + "devDependencies": { + "vite": "^5.0.0", + "@wailsio/runtime": "latest" + } +} \ No newline at end of file diff --git a/v3/examples/file-association/frontend/public/Inter-Medium.ttf b/v3/examples/file-association/frontend/public/Inter-Medium.ttf new file mode 100644 index 00000000000..a01f3777a6f Binary files /dev/null and b/v3/examples/file-association/frontend/public/Inter-Medium.ttf differ diff --git a/v3/examples/file-association/frontend/public/javascript.svg b/v3/examples/file-association/frontend/public/javascript.svg new file mode 100644 index 00000000000..f9abb2b728d --- /dev/null +++ b/v3/examples/file-association/frontend/public/javascript.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v3/examples/file-association/frontend/public/style.css b/v3/examples/file-association/frontend/public/style.css new file mode 100644 index 00000000000..865f7f38ae5 --- /dev/null +++ b/v3/examples/file-association/frontend/public/style.css @@ -0,0 +1,161 @@ +:root { + font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", + "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: rgba(27, 38, 54, 1); + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +* { + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + src: local(""), + url("./Inter-Medium.ttf") format("truetype"); +} + +h3 { + font-size: 3em; + line-height: 1.1; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} + +a:hover { + color: #535bf2; +} + +button { + width: 60px; + height: 30px; + line-height: 30px; + border-radius: 3px; + border: none; + margin: 0 0 0 20px; + padding: 0 8px; + cursor: pointer; +} + +.result { + height: 20px; + line-height: 20px; +} + +body { + margin: 0; + display: flex; + place-items: center; + place-content: center; + min-width: 320px; + min-height: 100vh; +} + +.container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; +} + +.logo:hover { + filter: drop-shadow(0 0 2em #e80000aa); +} + +.logo.vanilla:hover { + filter: drop-shadow(0 0 2em #f7df1eaa); +} + +.result { + height: 20px; + line-height: 20px; + margin: 1.5rem auto; + text-align: center; +} + +.footer { + margin-top: 1rem; + align-content: center; + text-align: center; + color: rgba(255, 255, 255, 0.67); +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + + a:hover { + color: #747bff; + } + + button { + background-color: #f9f9f9; + } +} + + +.input-box .btn:hover { + background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%); + color: #333333; +} + +.input-box .input { + border: none; + border-radius: 3px; + outline: none; + height: 30px; + line-height: 30px; + padding: 0 10px; + color: black; + background-color: rgba(240, 240, 240, 1); + -webkit-font-smoothing: antialiased; +} + +.input-box .input:hover { + border: none; + background-color: rgba(255, 255, 255, 1); +} + +.input-box .input:focus { + border: none; + background-color: rgba(255, 255, 255, 1); +} \ No newline at end of file diff --git a/v3/examples/file-association/frontend/public/wails.png b/v3/examples/file-association/frontend/public/wails.png new file mode 100644 index 00000000000..8bdf424833b Binary files /dev/null and b/v3/examples/file-association/frontend/public/wails.png differ diff --git a/v3/examples/file-association/go.mod b/v3/examples/file-association/go.mod new file mode 100644 index 00000000000..9e5f81689ba --- /dev/null +++ b/v3/examples/file-association/go.mod @@ -0,0 +1,52 @@ +module changeme + +go 1.22.4 + +toolchain go1.23.0 + +require github.com/wailsapp/wails/v3 v3.0.0-alpha.7 + +require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect + github.com/bep/debounce v1.2.1 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/ebitengine/purego v0.4.0-alpha.4 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect + github.com/go-git/go-git/v5 v5.11.0 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/godbus/dbus/v5 v5.1.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/leaanthony/go-ansi-parser v1.6.1 // indirect + github.com/leaanthony/u v1.1.0 // indirect + github.com/lmittmann/tint v1.0.4 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + github.com/samber/lo v1.38.1 // indirect + github.com/sergi/go-diff v1.2.0 // indirect + github.com/skeema/knownhosts v1.2.1 // indirect + github.com/wailsapp/go-webview2 v1.0.16 // indirect + github.com/wailsapp/mimetype v1.4.1 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect +) + +replace github.com/wailsapp/wails/v3 => ../.. diff --git a/v3/examples/file-association/go.sum b/v3/examples/file-association/go.sum new file mode 100644 index 00000000000..bf1920d7e50 --- /dev/null +++ b/v3/examples/file-association/go.sum @@ -0,0 +1,188 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= +github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ebitengine/purego v0.4.0-alpha.4 h1:Y7yIV06Yo5M2BAdD7EVPhfp6LZ0tEcQo5770OhYUVes= +github.com/ebitengine/purego v0.4.0-alpha.4/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= +github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck= +github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leaanthony/go-ansi-parser v1.6.1 h1:xd8bzARK3dErqkPFtoF9F3/HgN8UQk0ed1YDKpEz01A= +github.com/leaanthony/go-ansi-parser v1.6.1/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU= +github.com/leaanthony/u v1.1.0 h1:2n0d2BwPVXSUq5yhe8lJPHdxevE2qK5G99PMStMZMaI= +github.com/leaanthony/u v1.1.0/go.mod h1:9+o6hejoRljvZ3BzdYlVL0JYCwtnAsVuN9pVTQcaRfI= +github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= +github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= +github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= +github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/wailsapp/go-webview2 v1.0.16 h1:wffnvnkkLvhRex/aOrA3R7FP7rkvOqL/bir1br7BekU= +github.com/wailsapp/go-webview2 v1.0.16/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo= +github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= +github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200810151505-1b9f1253b3ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/v3/examples/file-association/greetservice.go b/v3/examples/file-association/greetservice.go new file mode 100644 index 00000000000..8972c39cdf1 --- /dev/null +++ b/v3/examples/file-association/greetservice.go @@ -0,0 +1,7 @@ +package main + +type GreetService struct{} + +func (g *GreetService) Greet(name string) string { + return "Hello " + name + "!" +} diff --git a/v3/examples/file-association/main.go b/v3/examples/file-association/main.go new file mode 100644 index 00000000000..b6f51e2c88b --- /dev/null +++ b/v3/examples/file-association/main.go @@ -0,0 +1,91 @@ +package main + +import ( + "embed" + _ "embed" + "github.com/wailsapp/wails/v3/pkg/events" + "log" + "time" + + "github.com/wailsapp/wails/v3/pkg/application" +) + +// Wails uses Go's `embed` package to embed the frontend files into the binary. +// Any files in the frontend/dist folder will be embedded into the binary and +// made available to the frontend. +// See https://pkg.go.dev/embed for more information. + +//go:embed frontend/dist +var assets embed.FS + +// main function serves as the application's entry point. It initializes the application, creates a window, +// and starts a goroutine that emits a time-based event every second. It subsequently runs the application and +// logs any error that might occur. +func main() { + + // Create a new Wails application by providing the necessary options. + // Variables 'Name' and 'Description' are for application metadata. + // 'Assets' configures the asset server with the 'FS' variable pointing to the frontend files. + // 'Bind' is a list of Go struct instances. The frontend has access to the methods of these instances. + // 'Mac' options tailor the application when running an macOS. + app := application.New(application.Options{ + Name: "fileassoc", + Description: "A demo of using raw HTML & CSS", + Services: []application.Service{ + application.NewService(&GreetService{}), + }, + Assets: application.AssetOptions{ + Handler: application.AssetFileServerFS(assets), + }, + Mac: application.MacOptions{ + ApplicationShouldTerminateAfterLastWindowClosed: true, + }, + FileAssociations: []string{".wails"}, + }) + + // Create a new window with the necessary options. + // 'Title' is the title of the window. + // 'Mac' options tailor the window when running on macOS. + // 'BackgroundColour' is the background colour of the window. + // 'URL' is the URL that will be loaded into the webview. + window := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + Title: "Window 1", + Mac: application.MacWindow{ + InvisibleTitleBarHeight: 50, + Backdrop: application.MacBackdropTranslucent, + TitleBar: application.MacTitleBarHiddenInset, + }, + BackgroundColour: application.NewRGB(27, 38, 54), + URL: "/", + }) + + var filename string + app.OnApplicationEvent(events.Common.ApplicationOpenedWithFile, func(event *application.ApplicationEvent) { + filename = event.Context().Filename() + }) + + window.OnWindowEvent(events.Common.WindowShow, func(event *application.WindowEvent) { + application.InfoDialog(). + SetTitle("File Opened"). + SetMessage("Application opened with file: " + filename). + Show() + }) + + // Create a goroutine that emits an event containing the current time every second. + // The frontend can listen to this event and update the UI accordingly. + go func() { + for { + now := time.Now().Format(time.RFC1123) + app.EmitEvent("time", now) + time.Sleep(time.Second) + } + }() + + // Run the application. This blocks until the application has been exited. + err := app.Run() + + // If an error occurred while running the application, log it and exit. + if err != nil { + log.Fatal(err) + } +} diff --git a/v3/examples/file-association/test.wails b/v3/examples/file-association/test.wails new file mode 100644 index 00000000000..dde58d5e844 --- /dev/null +++ b/v3/examples/file-association/test.wails @@ -0,0 +1 @@ +Once the application is built and installed, double click on this file to open the application. \ No newline at end of file diff --git a/v3/examples/html-dnd-api/README.md b/v3/examples/html-dnd-api/README.md new file mode 100644 index 00000000000..1b06f388210 --- /dev/null +++ b/v3/examples/html-dnd-api/README.md @@ -0,0 +1,43 @@ +# HTML Drag and Drop API Example + +This example should demonstrate whether the [HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API") works correctly. + +## Expected Behaviour + +When dragging the "draggable", in the console should be printed: +1. "dragstart" once +2. "drag" many times +3. "dragend" once + +When dragging the "draggable" on the drop target, the inner text of the latter shoud change and in the console should be printed: +1. "dragstart" once +2. "drag" many times +3. "dragenter" once +4. "dragover" many times (alternating with "drag") +5. - "drop" once (in case of a drop inside the drop target) + - "dragleave" once (in case the draggable div leaves the drop target) +6. "dragend" once + +## Running the example + +To run the example, simply run the following command: + +```bash +go run main.go +``` + +## Building the example + +To build the example in debug mode, simply run the following command: + +```bash +wails3 task build +``` + +# Status + +| Platform | Status | +|----------|-------------| +| Mac | Working | +| Windows | Not Working | +| Linux | | diff --git a/v3/examples/html-dnd-api/assets/index.html b/v3/examples/html-dnd-api/assets/index.html new file mode 100644 index 00000000000..a64b9378a51 --- /dev/null +++ b/v3/examples/html-dnd-api/assets/index.html @@ -0,0 +1,75 @@ + + + + + Title + + + +HTML Drag and Drop API Demo + + +draggable + +drop target + + + + + + diff --git a/v3/examples/html-dnd-api/main.go b/v3/examples/html-dnd-api/main.go new file mode 100644 index 00000000000..9d3d37ffa3d --- /dev/null +++ b/v3/examples/html-dnd-api/main.go @@ -0,0 +1,40 @@ +package main + +import ( + "embed" + "log" + + "github.com/wailsapp/wails/v3/pkg/application" +) + +//go:embed assets +var assets embed.FS + +func main() { + + app := application.New(application.Options{ + Name: "HTML Drag and Drop API Demo", + Description: "A demo of the HTML Drag and drop API", + Assets: application.AssetOptions{ + Handler: application.BundledAssetFileServer(assets), + }, + Mac: application.MacOptions{ + ApplicationShouldTerminateAfterLastWindowClosed: true, + }, + }) + + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + Title: "Drag-n-drop Demo", + Mac: application.MacWindow{ + Backdrop: application.MacBackdropTranslucent, + TitleBar: application.MacTitleBarHiddenInsetUnified, + InvisibleTitleBarHeight: 50, + }, + }) + + err := app.Run() + + if err != nil { + log.Fatal(err.Error()) + } +} diff --git a/v3/examples/window/main.go b/v3/examples/window/main.go index f062f9a0f8e..a0c3ceda9bb 100644 --- a/v3/examples/window/main.go +++ b/v3/examples/window/main.go @@ -154,6 +154,17 @@ func main() { Show() windowCounter++ }) + myMenu.Add("New WebviewWindow (Always on top)"). + OnClick(func(ctx *application.Context) { + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + AlwaysOnTop: true, + }). + SetTitle("WebviewWindow "+strconv.Itoa(windowCounter)). + SetRelativePosition(rand.Intn(1000), rand.Intn(800)). + SetURL("https://wails.io"). + Show() + windowCounter++ + }) myMenu.Add("New WebviewWindow (Hide Maximise)"). OnClick(func(ctx *application.Context) { app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ @@ -165,6 +176,32 @@ func main() { Show() windowCounter++ }) + + myMenu.Add("New WebviewWindow (Centered)"). + OnClick(func(ctx *application.Context) { + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + MaximiseButtonState: application.ButtonHidden, + InitialPosition: application.WindowCentered, + }). + SetTitle("WebviewWindow " + strconv.Itoa(windowCounter)). + SetURL("https://wails.io"). + Show() + windowCounter++ + }) + + myMenu.Add("New WebviewWindow (Position 100,100)"). + OnClick(func(ctx *application.Context) { + app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{ + MaximiseButtonState: application.ButtonHidden, + X: 100, + Y: 100, + InitialPosition: application.WindowXY, + }). + SetTitle("WebviewWindow " + strconv.Itoa(windowCounter)). + SetURL("https://wails.io"). + Show() + windowCounter++ + }) } if runtime.GOOS == "darwin" || runtime.GOOS == "windows" { myMenu.Add("New WebviewWindow (Disable Close)"). diff --git a/v3/go.mod b/v3/go.mod index 18787cf5110..d1d3646d774 100644 --- a/v3/go.mod +++ b/v3/go.mod @@ -3,6 +3,7 @@ module github.com/wailsapp/wails/v3 go 1.22.4 require ( + github.com/adrg/xdg v0.5.0 github.com/atterpac/refresh v0.8.3 github.com/bep/debounce v1.2.1 github.com/ebitengine/purego v0.4.0-alpha.4 @@ -31,9 +32,10 @@ require ( github.com/tc-hib/winres v0.3.1 github.com/wailsapp/go-webview2 v1.0.17-0.20240921232412-df499f5de7dc github.com/wailsapp/mimetype v1.4.1 - golang.org/x/sys v0.20.0 + golang.org/x/sys v0.22.0 golang.org/x/term v0.20.0 - golang.org/x/tools v0.21.0 + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d + gopkg.in/yaml.v3 v3.0.1 modernc.org/sqlite v1.21.0 ) @@ -84,14 +86,13 @@ require ( github.com/zeebo/xxh3 v1.0.2 // indirect golang.org/x/crypto v0.23.0 // indirect golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect - golang.org/x/image v0.15.0 // indirect + golang.org/x/image v0.21.0 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.25.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/text v0.19.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect howett.net/plist v1.0.0 // indirect lukechampine.com/uint128 v1.2.0 // indirect modernc.org/cc/v3 v3.40.0 // indirect diff --git a/v3/go.sum b/v3/go.sum index 614eeb2e06e..c0dce034be1 100644 --- a/v3/go.sum +++ b/v3/go.sum @@ -26,6 +26,8 @@ github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCv github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/adrg/xdg v0.5.0 h1:dDaZvhMXatArP1NPHhnfaQUqWBLBsmx1h1HXQdMoFCY= +github.com/adrg/xdg v0.5.0/go.mod h1:dDdY4M4DF9Rjy4kHPeNL+ilVF+p2lK8IdM9/rTSGcI4= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -213,8 +215,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tc-hib/winres v0.3.1 h1:CwRjEGrKdbi5CvZ4ID+iyVhgyfatxFoizjPhzez9Io4= github.com/tc-hib/winres v0.3.1/go.mod h1:C/JaNhH3KBvhNKVbvdlDWkbMDO9H4fKKDaN7/07SSuk= github.com/wailsapp/go-webview2 v1.0.16 h1:wffnvnkkLvhRex/aOrA3R7FP7rkvOqL/bir1br7BekU= @@ -240,8 +242,8 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= -golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= +golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s= +golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= @@ -259,8 +261,8 @@ golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -284,8 +286,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -302,14 +304,14 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= -golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/v3/internal/commands/appimage.go b/v3/internal/commands/appimage.go index 62bc59acbad..a018fb74535 100644 --- a/v3/internal/commands/appimage.go +++ b/v3/internal/commands/appimage.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "path/filepath" + "runtime" "strings" "sync" @@ -72,7 +73,18 @@ func generateAppImage(options *GenerateAppImageOptions) error { // Get the last path of the binary and normalise the name name := normaliseName(filepath.Base(options.Binary)) - appDir := filepath.Join(options.BuildDir, name+"-x86_64.AppDir") + // Architecture-specific variables using a map + archDetails := map[string]string{ + "arm64": "aarch64", + "x86_64": "x86_64", + } + + arch, exists := archDetails[runtime.GOARCH] + if !exists { + return fmt.Errorf("unsupported architecture: %s", runtime.GOARCH) + } + + appDir := filepath.Join(options.BuildDir, fmt.Sprintf("%s-%s.AppDir", name, arch)) s.RMDIR(appDir) log(p, "Preparing AppImage Directory: "+appDir) @@ -92,27 +104,38 @@ func generateAppImage(options *GenerateAppImageOptions) error { // Download linuxdeploy and make it executable s.CD(options.BuildDir) - // Download necessary files + // Download URLs using a map based on architecture + urls := map[string]string{ + "linuxdeploy": fmt.Sprintf("https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-%s.AppImage", arch), + "AppRun": fmt.Sprintf("https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-%s", arch), + } + + // Download necessary files concurrently log(p, "Downloading AppImage tooling") var wg sync.WaitGroup wg.Add(2) + go func() { - if !s.EXISTS(filepath.Join(options.BuildDir, "linuxdeploy-x86_64.AppImage")) { - s.DOWNLOAD("https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage", filepath.Join(options.BuildDir, "linuxdeploy-x86_64.AppImage")) + linuxdeployPath := filepath.Join(options.BuildDir, filepath.Base(urls["linuxdeploy"])) + if !s.EXISTS(linuxdeployPath) { + s.DOWNLOAD(urls["linuxdeploy"], linuxdeployPath) } - s.CHMOD(filepath.Join(options.BuildDir, "linuxdeploy-x86_64.AppImage"), 0755) + s.CHMOD(linuxdeployPath, 0755) wg.Done() }() + go func() { target := filepath.Join(appDir, "AppRun") if !s.EXISTS(target) { - s.DOWNLOAD("https://github.com/AppImage/AppImageKit/releases/download/continuous/AppRun-x86_64", target) + s.DOWNLOAD(urls["AppRun"], target) } s.CHMOD(target, 0755) wg.Done() }() + wg.Wait() + // Processing GTK files log(p, "Processing GTK files.") filesNeeded := []string{"WebKitWebProcess", "WebKitNetworkProcess", "libwebkit2gtkinjectedbundle.so"} files, err := findGTKFiles(filesNeeded) @@ -122,11 +145,9 @@ func generateAppImage(options *GenerateAppImageOptions) error { s.CD(appDir) for _, file := range files { targetDir := filepath.Dir(file) - // Strip leading forward slash if targetDir[0] == '/' { targetDir = targetDir[1:] } - var err error targetDir, err = filepath.Abs(targetDir) if err != nil { return err @@ -134,6 +155,7 @@ func generateAppImage(options *GenerateAppImageOptions) error { s.MKDIR(targetDir) s.COPY(file, targetDir) } + // Copy GTK Plugin err = os.WriteFile(filepath.Join(options.BuildDir, "linuxdeploy-plugin-gtk.sh"), gtkPlugin, 0755) if err != nil { @@ -141,7 +163,6 @@ func generateAppImage(options *GenerateAppImageOptions) error { } // Determine GTK Version - // Run ldd on the binary and capture the output targetBinary := filepath.Join(appDir, "usr", "bin", options.Binary) lddOutput, err := s.EXEC(fmt.Sprintf("ldd %s", targetBinary)) if err != nil { @@ -149,21 +170,23 @@ func generateAppImage(options *GenerateAppImageOptions) error { return err } lddString := string(lddOutput) - // Check if GTK3 is present var DeployGtkVersion string - if s.CONTAINS(lddString, "libgtk-x11-2.0.so") { + switch { + case s.CONTAINS(lddString, "libgtk-x11-2.0.so"): DeployGtkVersion = "2" - } else if s.CONTAINS(lddString, "libgtk-3.so") { + case s.CONTAINS(lddString, "libgtk-3.so"): DeployGtkVersion = "3" - } else if s.CONTAINS(lddString, "libgtk-4.so") { + case s.CONTAINS(lddString, "libgtk-4.so"): DeployGtkVersion = "4" - } else { + default: return fmt.Errorf("unable to determine GTK version") } + // Run linuxdeploy to bundle the application s.CD(options.BuildDir) - //log(p, "Generating AppImage (This may take a while...)") - cmd := fmt.Sprintf("./linuxdeploy-x86_64.AppImage --appimage-extract-and-run --appdir %s --output appimage --plugin gtk", appDir) + linuxdeployAppImage := filepath.Join(options.BuildDir, fmt.Sprintf("linuxdeploy-%s.AppImage", arch)) + + cmd := fmt.Sprintf("%s --appimage-extract-and-run --appdir %s --output appimage --plugin gtk", linuxdeployAppImage, appDir) s.SETENV("DEPLOY_GTK_VERSION", DeployGtkVersion) output, err := s.EXEC(cmd) if err != nil { @@ -172,7 +195,7 @@ func generateAppImage(options *GenerateAppImageOptions) error { } // Move file to output directory - targetFile := filepath.Join(options.BuildDir, name+"-x86_64.AppImage") + targetFile := filepath.Join(options.BuildDir, fmt.Sprintf("%s-%s.AppImage", name, arch)) s.MOVE(targetFile, options.OutputDir) log(p, "AppImage created: "+targetFile) diff --git a/v3/internal/commands/build-assets.go b/v3/internal/commands/build-assets.go index 9b422595d44..c5e0946fecf 100644 --- a/v3/internal/commands/build-assets.go +++ b/v3/internal/commands/build-assets.go @@ -5,6 +5,7 @@ import ( _ "embed" "fmt" "github.com/leaanthony/gosod" + "gopkg.in/yaml.v3" "io/fs" "os" "path/filepath" @@ -16,10 +17,32 @@ import ( //go:embed build_assets var buildAssets embed.FS +//go:embed updatable_build_assets +var updatableBuildAssets embed.FS + type BuildAssetsOptions struct { + Dir string `description:"The directory to generate the files into" default:"."` + Name string `description:"The name of the project"` + BinaryName string `description:"The name of the binary"` + ProductName string `description:"The name of the product" default:"My Product"` + ProductDescription string `description:"The description of the product" default:"My Product Description"` + ProductVersion string `description:"The version of the product" default:"0.1.0"` + ProductCompany string `description:"The company of the product" default:"My Company"` + ProductCopyright string `description:"The copyright notice" default:"\u00a9 now, My Company"` + ProductComments string `description:"Comments to add to the generated files" default:"This is a comment"` + ProductIdentifier string `description:"The product identifier, e.g com.mycompany.myproduct"` + Silent bool `description:"Suppress output to console"` +} + +type BuildConfig struct { + BuildAssetsOptions + FileAssociations []FileAssociation `yaml:"fileAssociations"` +} + +type UpdateBuildAssetsOptions struct { Dir string `description:"The directory to generate the files into" default:"build"` Name string `description:"The name of the project"` - Binary string `description:"The name of the binary"` + BinaryName string `description:"The name of the binary"` ProductName string `description:"The name of the product" default:"My Product"` ProductDescription string `description:"The description of the product" default:"My Product Description"` ProductVersion string `description:"The version of the product" default:"0.1.0"` @@ -27,6 +50,7 @@ type BuildAssetsOptions struct { ProductCopyright string `description:"The copyright notice" default:"\u00a9 now, My Company"` ProductComments string `description:"Comments to add to the generated files" default:"This is a comment"` ProductIdentifier string `description:"The product identifier, e.g com.mycompany.myproduct"` + Config string `description:"The path to the config file"` Silent bool `description:"Suppress output to console"` } @@ -47,6 +71,8 @@ func GenerateBuildAssets(options *BuildAssetsOptions) error { } } + var config BuildConfig + if options.ProductComments == "" { options.ProductComments = fmt.Sprintf("(c) %d %s", time.Now().Year(), options.ProductCompany) } @@ -55,13 +81,15 @@ func GenerateBuildAssets(options *BuildAssetsOptions) error { options.ProductIdentifier = "com.wails." + normaliseName(options.Name) } - if options.Binary == "" { - options.Binary = normaliseName(options.Name) + if options.BinaryName == "" { + options.BinaryName = normaliseName(options.Name) if runtime.GOOS == "windows" { - options.Binary += ".exe" + options.BinaryName += ".exe" } } + config.BuildAssetsOptions = *options + tfs, err := fs.Sub(buildAssets, "build_assets") if err != nil { return err @@ -70,8 +98,77 @@ func GenerateBuildAssets(options *BuildAssetsOptions) error { if !options.Silent { println("Generating build assets in " + options.Dir) } - return gosod.New(tfs).Extract(options.Dir, options) + err = gosod.New(tfs).Extract(options.Dir, config) + if err != nil { + return err + } + tfs, err = fs.Sub(updatableBuildAssets, "updatable_build_assets") + if err != nil { + return err + } + return gosod.New(tfs).Extract(options.Dir, config) +} + +type FileAssociation struct { + Ext string `yaml:"ext"` + Name string `yaml:"name"` + Description string `yaml:"description"` + IconName string `yaml:"iconName"` + Role string `yaml:"role"` +} + +type UpdateConfig struct { + UpdateBuildAssetsOptions + FileAssociations []FileAssociation `yaml:"fileAssociations"` +} + +func UpdateBuildAssets(options *UpdateBuildAssetsOptions) error { + DisableFooter = true + + var err error + options.Dir, err = filepath.Abs(options.Dir) + if err != nil { + return err + } + + var config UpdateConfig + + if options.Config != "" { + bytes, err := os.ReadFile(options.Config) + if err != nil { + return err + } + err = yaml.Unmarshal(bytes, &config) + if err != nil { + return err + } + } + + // If directory doesn't exist, create it + if _, err := os.Stat(options.Dir); os.IsNotExist(err) { + err = os.MkdirAll(options.Dir, 0755) + if err != nil { + return err + } + } + + tfs, err := fs.Sub(updatableBuildAssets, "updatable_build_assets") + if err != nil { + return err + } + + config.UpdateBuildAssetsOptions = *options + + err = gosod.New(tfs).Extract(options.Dir, config) + if err != nil { + return err + } + + if !options.Silent { + println("Successfully updated build assets in " + options.Dir) + } + return nil } func normaliseName(name string) string { diff --git a/v3/internal/commands/build_assets/Taskfile.common.yml b/v3/internal/commands/build_assets/Taskfile.common.yml index 129f1b11410..6aed2a68f56 100644 --- a/v3/internal/commands/build_assets/Taskfile.common.yml +++ b/v3/internal/commands/build_assets/Taskfile.common.yml @@ -66,4 +66,10 @@ tasks: deps: - task: install:frontend:deps cmds: - - npm run dev -- --port {{.VITE_PORT}} --strictPort \ No newline at end of file + - npm run dev -- --port {{.VITE_PORT}} --strictPort + + update:build-assets: + summary: Updates the build assets + dir: build + cmds: + - wails3 update build-assets -name "{{.APP_NAME}}" -binaryname "{{.APP_NAME}}" -config config.yml -dir . \ No newline at end of file diff --git a/v3/internal/commands/build_assets/config.yml b/v3/internal/commands/build_assets/config.yml new file mode 100644 index 00000000000..37da251193d --- /dev/null +++ b/v3/internal/commands/build_assets/config.yml @@ -0,0 +1,62 @@ +# This file contains the configuration for this project. +# When you update `info` or `fileAssociations`, run `wails3 task common:update:build-assets` to update the assets. +# Note that this will overwrite any changes you have made to the assets. +version: '3' + +# This information is used to generate the build assets. +info: + companyName: "My Company" # The name of the company + productName: "My Product" # The name of the application + productIdentifier: "com.mycompany.myproduct" # The unique product identifier + description: "A program that does X" # The application description + copyright: "(c) 2024, My Company" # Copyright text + comments: "Some Product Comments" # Comments + version: "v0.0.1" # The application version + +# Dev mode configuration +dev_mode: + root_path: . + log_level: warn + debounce: 1000 + ignore: + dir: + - .git + - node_modules + - frontend + - bin + file: + - .DS_Store + - .gitignore + - .gitkeep + watched_extension: + - "*.go" + git_ignore: true + executes: + - cmd: wails3 task common:install:frontend:deps + type: once + - cmd: wails3 task common:dev:frontend + type: background + - cmd: go mod tidy + type: blocking + - cmd: wails3 task build + type: blocking + - cmd: wails3 task run + type: primary + +# File Associations +# More information at: https://v3alpha.wails.io/noit/done/yet +fileAssociations: +# - ext: wails +# name: Wails +# description: Wails Application File +# iconName: wailsFileIcon +# role: Editor +# - ext: jpg +# name: JPEG +# description: Image File +# iconName: jpegFileIcon +# role: Editor + +# Other data +other: + - name: My Other Data \ No newline at end of file diff --git a/v3/internal/commands/build_assets/nsis/project.nsi.tmpl b/v3/internal/commands/build_assets/nsis/project.nsi.tmpl index 4d18a34eeff..917bda4868b 100644 --- a/v3/internal/commands/build_assets/nsis/project.nsi.tmpl +++ b/v3/internal/commands/build_assets/nsis/project.nsi.tmpl @@ -91,6 +91,8 @@ Section CreateShortcut "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}" CreateShortCut "$DESKTOP\${INFO_PRODUCTNAME}.lnk" "$INSTDIR\${PRODUCT_EXECUTABLE}" + !insertmacro wails.associateFiles + !insertmacro wails.writeUninstaller SectionEnd @@ -104,5 +106,7 @@ Section "uninstall" Delete "$SMPROGRAMS\${INFO_PRODUCTNAME}.lnk" Delete "$DESKTOP\${INFO_PRODUCTNAME}.lnk" + !insertmacro wails.unassociateFiles + !insertmacro wails.deleteUninstaller SectionEnd diff --git a/v3/internal/commands/dev.go b/v3/internal/commands/dev.go index c76d483ad14..f7053e3779c 100644 --- a/v3/internal/commands/dev.go +++ b/v3/internal/commands/dev.go @@ -15,7 +15,7 @@ const wailsVitePort = "WAILS_VITE_PORT" type DevOptions struct { flags.Common - Config string `description:"The config file including path" default:"./build/devmode.config.yaml"` + Config string `description:"The config file including path" default:"./build/config.yml"` VitePort int `name:"port" description:"Specify the vite dev server port"` Secure bool `name:"s" description:"Enable HTTPS"` } diff --git a/v3/internal/commands/init.go b/v3/internal/commands/init.go index 41a38b2f311..9a5f0ae438c 100644 --- a/v3/internal/commands/init.go +++ b/v3/internal/commands/init.go @@ -43,13 +43,13 @@ func Init(options *flags.Init) error { Name: options.ProjectName, Dir: filepath.Join(options.ProjectDir, "build"), Silent: true, - ProductComments: options.ProductComments, ProductCompany: options.ProductCompany, - ProductDescription: options.ProductDescription, ProductName: options.ProductName, + ProductDescription: options.ProductDescription, ProductVersion: options.ProductVersion, ProductIdentifier: options.ProductIdentifier, ProductCopyright: options.ProductCopyright, + ProductComments: options.ProductComments, } return GenerateBuildAssets(buildAssetsOptions) } diff --git a/v3/internal/commands/runtime.go b/v3/internal/commands/runtime.go new file mode 100644 index 00000000000..7414c8b325a --- /dev/null +++ b/v3/internal/commands/runtime.go @@ -0,0 +1,47 @@ +package commands + +import ( + "io" + "os" + "path/filepath" + "runtime" +) + +type RuntimeOptions struct { + Directory string `name:"d" description:"Directory to generate runtime file in" default:"."` +} + +func GenerateRuntime(options *RuntimeOptions) error { + DisableFooter = true + _, thisFile, _, _ := runtime.Caller(0) + localDir := filepath.Dir(thisFile) + bundledAssetsDir := filepath.Join(localDir, "..", "assetserver", "bundledassets") + runtimeJS := filepath.Join(bundledAssetsDir, "runtime.js") + err := CopyFile(runtimeJS, filepath.Join(options.Directory, "runtime.js")) + if err != nil { + return err + } + runtimeDebugJS := filepath.Join(bundledAssetsDir, "runtime.debug.js") + err = CopyFile(runtimeDebugJS, filepath.Join(options.Directory, "runtime-debug.js")) + if err != nil { + return err + } + return nil +} + +func CopyFile(source string, target string) error { + s, err := os.Open(source) + if err != nil { + return err + } + defer s.Close() + d, err := os.Create(target) + if err != nil { + return err + } + if _, err := io.Copy(d, s); err != nil { + d.Close() + return err + } + return d.Close() +} diff --git a/v3/internal/commands/build_assets/Info.dev.plist.tmpl b/v3/internal/commands/updatable_build_assets/Info.dev.plist.tmpl similarity index 96% rename from v3/internal/commands/build_assets/Info.dev.plist.tmpl rename to v3/internal/commands/updatable_build_assets/Info.dev.plist.tmpl index eead3308a21..0bd24ec4cc5 100644 --- a/v3/internal/commands/build_assets/Info.dev.plist.tmpl +++ b/v3/internal/commands/updatable_build_assets/Info.dev.plist.tmpl @@ -6,7 +6,7 @@ CFBundleName {{.ProductName}} CFBundleExecutable - {{.Name}} + {{.BinaryName}} CFBundleIdentifier {{.ProductIdentifier}} CFBundleVersion diff --git a/v3/internal/commands/build_assets/Info.plist.tmpl b/v3/internal/commands/updatable_build_assets/Info.plist.tmpl similarity index 96% rename from v3/internal/commands/build_assets/Info.plist.tmpl rename to v3/internal/commands/updatable_build_assets/Info.plist.tmpl index 243d47bdc8f..f40771b307c 100644 --- a/v3/internal/commands/build_assets/Info.plist.tmpl +++ b/v3/internal/commands/updatable_build_assets/Info.plist.tmpl @@ -6,7 +6,7 @@ CFBundleName {{.ProductName}} CFBundleExecutable - {{.Name}} + {{.BinaryName}} CFBundleIdentifier {{.ProductIdentifier}} CFBundleVersion diff --git a/v3/internal/commands/build_assets/info.json.tmpl b/v3/internal/commands/updatable_build_assets/info.json.tmpl similarity index 100% rename from v3/internal/commands/build_assets/info.json.tmpl rename to v3/internal/commands/updatable_build_assets/info.json.tmpl diff --git a/v3/internal/commands/build_assets/nsis/wails_tools.nsh.tmpl b/v3/internal/commands/updatable_build_assets/nsis/wails_tools.nsh.tmpl similarity index 75% rename from v3/internal/commands/build_assets/nsis/wails_tools.nsh.tmpl rename to v3/internal/commands/updatable_build_assets/nsis/wails_tools.nsh.tmpl index 127d0eec366..ca5c11cccbd 100644 --- a/v3/internal/commands/build_assets/nsis/wails_tools.nsh.tmpl +++ b/v3/internal/commands/updatable_build_assets/nsis/wails_tools.nsh.tmpl @@ -176,4 +176,43 @@ RequestExecutionLevel "${REQUEST_EXECUTION_LEVEL}" SetDetailsPrint both ok: +!macroend + +# Copy of APP_ASSOCIATE and APP_UNASSOCIATE macros from here https://gist.github.com/nikku/281d0ef126dbc215dd58bfd5b3a5cd5b +!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND + ; Backup the previously associated file class + ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" "" + WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "${FILECLASS}_backup" "$R0" + + WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "${FILECLASS}" + + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}" "" `${DESCRIPTION}` + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\DefaultIcon" "" `${ICON}` + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell" "" "open" + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open" "" `${COMMANDTEXT}` + WriteRegStr SHELL_CONTEXT "Software\Classes\${FILECLASS}\shell\open\command" "" `${COMMAND}` +!macroend + +!macro APP_UNASSOCIATE EXT FILECLASS + ; Backup the previously associated file class + ReadRegStr $R0 SHELL_CONTEXT "Software\Classes\.${EXT}" `${FILECLASS}_backup` + WriteRegStr SHELL_CONTEXT "Software\Classes\.${EXT}" "" "$R0" + + DeleteRegKey SHELL_CONTEXT `Software\Classes\${FILECLASS}` +!macroend + +!macro wails.associateFiles + ; Create file associations + {{range .FileAssociations}} + !insertmacro APP_ASSOCIATE "{{.Ext}}" "{{.Name}}" "{{.Description}}" "$INSTDIR\{{.IconName}}.ico" "Open with ${INFO_PRODUCTNAME}" "$INSTDIR\${PRODUCT_EXECUTABLE} $\"%1$\"" + File "..\{{.IconName}}.ico" + {{end}} +!macroend + +!macro wails.unassociateFiles + ; Delete app associations + {{range .FileAssociations}} + !insertmacro APP_UNASSOCIATE "{{.Ext}}" "{{.Name}}" + Delete "$INSTDIR\{{.IconName}}.ico" + {{end}} !macroend \ No newline at end of file diff --git a/v3/internal/commands/build_assets/wails.exe.manifest.tmpl b/v3/internal/commands/updatable_build_assets/wails.exe.manifest.tmpl similarity index 100% rename from v3/internal/commands/build_assets/wails.exe.manifest.tmpl rename to v3/internal/commands/updatable_build_assets/wails.exe.manifest.tmpl diff --git a/v3/internal/commands/watcher.go b/v3/internal/commands/watcher.go index 25a67a6e2c0..6cdd6dc3afa 100644 --- a/v3/internal/commands/watcher.go +++ b/v3/internal/commands/watcher.go @@ -3,6 +3,7 @@ package commands import ( "github.com/atterpac/refresh/engine" "github.com/wailsapp/wails/v3/internal/signal" + "gopkg.in/yaml.v3" "os" ) @@ -12,7 +13,25 @@ type WatcherOptions struct { func Watcher(options *WatcherOptions) error { stopChan := make(chan struct{}) - watcherEngine, err := engine.NewEngineFromYAML(options.Config) + + // Parse the config file + type devConfig struct { + Config engine.Config `yaml:"dev_mode"` + } + + var devconfig devConfig + + // Parse the config file + c, err := os.ReadFile(options.Config) + if err != nil { + return err + } + err = yaml.Unmarshal(c, &devconfig) + if err != nil { + return err + } + + watcherEngine, err := engine.NewEngineFromConfig(devconfig.Config) if err != nil { return err } diff --git a/v3/internal/flags/service.go b/v3/internal/flags/service.go index c52accd87be..f7fd8ec2e03 100644 --- a/v3/internal/flags/service.go +++ b/v3/internal/flags/service.go @@ -1,14 +1,14 @@ package flags type ServiceInit struct { - Name string `name:"n" description:"Name of plugin" default:"example_plugin"` - Description string `name:"d" description:"Description of plugin" default:"Example plugin"` - PackageName string `name:"p" description:"Package name for plugin" default:""` + Name string `name:"n" description:"Name of service" default:"example_service"` + Description string `name:"d" description:"Description of service" default:"Example service"` + PackageName string `name:"p" description:"Package name for service" default:""` OutputDir string `name:"o" description:"Output directory" default:"."` Quiet bool `name:"q" description:"Suppress output to console"` - Author string `name:"a" description:"Author of plugin" default:""` - Version string `name:"v" description:"Version of plugin" default:""` - Website string `name:"w" description:"Website of plugin" default:""` - Repository string `name:"r" description:"Repository of plugin" default:""` - License string `name:"l" description:"License of plugin" default:""` + Author string `name:"a" description:"Author of service" default:""` + Version string `name:"v" description:"Version of service" default:""` + Website string `name:"w" description:"Website of service" default:""` + Repository string `name:"r" description:"Repository of service" default:""` + License string `name:"l" description:"License of service" default:""` } diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/package.json b/v3/internal/runtime/desktop/@wailsio/runtime/package.json index a1602cc3480..dea509f7de7 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/package.json +++ b/v3/internal/runtime/desktop/@wailsio/runtime/package.json @@ -1,12 +1,18 @@ { "name": "@wailsio/runtime", - "version": "3.0.0-alpha.27", + "type": "module", + "version": "3.0.0-alpha.29", "description": "Wails Runtime", - "main": "src/index.js", - "types": "types/index.d.ts", + "exports": { + ".": { + "types": "./types/index.d.ts", + "require": "./src/index.js", + "import": "./src/index.js" + } + }, "repository": { "type": "git", - "url": "https://github.com/wailsapp/wails.git" + "url": "git+https://github.com/wailsapp/wails.git" }, "scripts": { "prebuild:types": "rimraf ./types", diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js b/v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js index 3314a9065fa..9be464ca5a1 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/src/event_types.js @@ -189,5 +189,6 @@ export const EventTypes = { ThemeChanged: "common:ThemeChanged", WindowDidMove: "common:WindowDidMove", WindowDidResize: "common:WindowDidResize", + ApplicationOpenedWithFile: "common:ApplicationOpenedWithFile", }, }; diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/src/screens.js b/v3/internal/runtime/desktop/@wailsio/runtime/src/screens.js index 43a5dc50b65..97fc2af02fe 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/src/screens.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/src/screens.js @@ -16,7 +16,6 @@ The electron alternative for Go * @property {number} Height - The height. */ - /** * @typedef {Object} Rect * @property {number} X - The X coordinate of the origin. @@ -25,10 +24,9 @@ The electron alternative for Go * @property {number} Height - The height of the rectangle. */ - /** * @typedef {Object} Screen - * @property {string} Id - Unique identifier for the screen. + * @property {string} ID - Unique identifier for the screen. * @property {string} Name - Human readable name of the screen. * @property {number} ScaleFactor - The scale factor of the screen (DPI/96). 1 = standard DPI, 2 = HiDPI (Retina), etc. * @property {number} X - The X coordinate of the screen. @@ -42,9 +40,8 @@ The electron alternative for Go * @property {number} Rotation - The rotation of the screen. */ - -import {newRuntimeCallerWithID, objectNames} from "./runtime"; -const call = newRuntimeCallerWithID(objectNames.Screens, ''); +import { newRuntimeCallerWithID, objectNames } from "./runtime"; +const call = newRuntimeCallerWithID(objectNames.Screens, ""); const getAll = 0; const getPrimary = 1; diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/src/system.js b/v3/internal/runtime/desktop/@wailsio/runtime/src/system.js index 8341ac842a5..66d636c82fe 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/src/system.js +++ b/v3/internal/runtime/desktop/@wailsio/runtime/src/system.js @@ -15,11 +15,26 @@ let call = newRuntimeCallerWithID(objectNames.System, ''); const systemIsDarkMode = 0; const environment = 1; -export function invoke(msg) { - if(window.chrome) { - return window.chrome.webview.postMessage(msg); +const _invoke = (() => { + try { + if(window?.chrome?.webview) { + return (msg) => window.chrome.webview.postMessage(msg); + } + if(window?.webkit?.messageHandlers?.external) { + return (msg) => window.webkit.messageHandlers.external.postMessage(msg); + } + } catch(e) { + console.warn('\n%c⚠️ Browser Environment Detected %c\n\n%cOnly UI previews are available in the browser. For full functionality, please run the application in desktop mode.\nMore information at: https://v3alpha.wails.io/learn/build/#using-a-browser-for-development\n', + 'background: #ffffff; color: #000000; font-weight: bold; padding: 4px 8px; border-radius: 4px; border: 2px solid #000000;', + 'background: transparent;', + 'color: #ffffff; font-style: italic; font-weight: bold;'); } - return window.webkit.messageHandlers.external.postMessage(msg); + return null; +})(); + +export function invoke(msg) { + if (!_invoke) return; + return _invoke(msg); } /** diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts b/v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts index 88636d16546..3f2fa60e881 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts +++ b/v3/internal/runtime/desktop/@wailsio/runtime/types/event_types.d.ts @@ -189,5 +189,6 @@ export declare const EventTypes: { ThemeChanged: string, WindowDidMove: string, WindowDidResize: string, + ApplicationOpenedWithFile: string, }, }; diff --git a/v3/internal/runtime/desktop/@wailsio/runtime/types/screens.d.ts b/v3/internal/runtime/desktop/@wailsio/runtime/types/screens.d.ts index 2dcba940f94..7409875db13 100644 --- a/v3/internal/runtime/desktop/@wailsio/runtime/types/screens.d.ts +++ b/v3/internal/runtime/desktop/@wailsio/runtime/types/screens.d.ts @@ -46,7 +46,7 @@ export type Screen = { /** * - Unique identifier for the screen. */ - Id: string; + ID: string; /** * - Human readable name of the screen. */ diff --git a/v3/internal/service/template/go.mod.tmpl b/v3/internal/service/template/go.mod.tmpl index 1b99c5892e1..dc8719753d4 100644 --- a/v3/internal/service/template/go.mod.tmpl +++ b/v3/internal/service/template/go.mod.tmpl @@ -2,7 +2,7 @@ module {{.Name}} go 1.23 -require github.com/wailsapp/wails/v3 v3.0.0-alpha.4 +require github.com/wailsapp/wails/v3 v3.0.0-alpha.7 require ( github.com/imdario/mergo v0.3.12 // indirect diff --git a/v3/internal/service/template/go.sum b/v3/internal/service/template/go.sum index 2e233793693..991eadf041f 100644 --- a/v3/internal/service/template/go.sum +++ b/v3/internal/service/template/go.sum @@ -5,8 +5,8 @@ github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5Az github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= -github.com/wailsapp/wails/v3 v3.0.0-alpha.0 h1:T5gqG98Xr8LBf69oxlPkhpsFD59w2SnqUZk6XHj8Zoc= -github.com/wailsapp/wails/v3 v3.0.0-alpha.0/go.mod h1:OAfO5bP0TSUvCIHZYc6Dqfow/9RqxzHvYtmhWPpo1c0= +github.com/wailsapp/wails/v3 v3.0.0-alpha.7 h1:LNX2EnbxTEYJYICJT8UkuzoGVNalRizTNGBY47endmk= +github.com/wailsapp/wails/v3 v3.0.0-alpha.7/go.mod h1:lBz4zedFxreJBoVpMe9u89oo4IE3IlyHJg5rOWnGNR0= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= diff --git a/v3/internal/templates/_common/Taskfile.tmpl.yml b/v3/internal/templates/_common/Taskfile.tmpl.yml index 491d4553ac7..c5f99d93115 100644 --- a/v3/internal/templates/_common/Taskfile.tmpl.yml +++ b/v3/internal/templates/_common/Taskfile.tmpl.yml @@ -30,4 +30,4 @@ tasks: dev: summary: Runs the application in development mode cmds: - - wails3 dev -config ./build/devmode.config.yaml -port {{ "{{.VITE_PORT}}" }} + - wails3 dev -config ./build/config.yml -port {{ "{{.VITE_PORT}}" }} diff --git a/v3/internal/templates/preact-ts/template.json b/v3/internal/templates/preact-ts/template.json index bd4ccc20bd5..8ec971b085b 100644 --- a/v3/internal/templates/preact-ts/template.json +++ b/v3/internal/templates/preact-ts/template.json @@ -2,7 +2,7 @@ "name": "Preact + Vite (Typescript)", "shortname": "preact-ts", "author": "Lea Anthony", - "description": "Preact + Vite development server", + "description": "Preact + TS + Vite development server", "helpurl": "https://wails.io", "version": 3 } \ No newline at end of file diff --git a/v3/internal/templates/react-swc-ts/template.json b/v3/internal/templates/react-swc-ts/template.json index f708a5b5d83..d79c59cd500 100644 --- a/v3/internal/templates/react-swc-ts/template.json +++ b/v3/internal/templates/react-swc-ts/template.json @@ -2,7 +2,7 @@ "name": "React + SWC + Vite (Typescript)", "shortname": "react-swc-ts", "author": "Lea Anthony", - "description": "React + SWC + Vite development server", + "description": "React + TS + SWC + Vite development server", "helpurl": "https://wails.io", "version": 3 } \ No newline at end of file diff --git a/v3/internal/templates/solid-ts/template.json b/v3/internal/templates/solid-ts/template.json index 529ec4c0c18..b21088d3f38 100644 --- a/v3/internal/templates/solid-ts/template.json +++ b/v3/internal/templates/solid-ts/template.json @@ -2,7 +2,7 @@ "name": "Solid + Vite (Typescript)", "shortname": "solid-ts", "author": "Lea Anthony", - "description": "Solid (Typescript) + Vite development server", + "description": "Solid + TS + Vite development server", "helpurl": "https://wails.io", "version": 3 } \ No newline at end of file diff --git a/v3/internal/templates/sveltekit-ts/frontend/.gitignore b/v3/internal/templates/sveltekit-ts/frontend/.gitignore new file mode 100644 index 00000000000..79518f71645 --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/.gitignore @@ -0,0 +1,21 @@ +node_modules + +# Output +.output +.vercel +/.svelte-kit +/build + +# OS +.DS_Store +Thumbs.db + +# Env +.env +.env.* +!.env.example +!.env.test + +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/v3/internal/templates/sveltekit-ts/frontend/.npmrc b/v3/internal/templates/sveltekit-ts/frontend/.npmrc new file mode 100644 index 00000000000..b6f27f13595 --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/v3/internal/templates/sveltekit-ts/frontend/README.md b/v3/internal/templates/sveltekit-ts/frontend/README.md new file mode 100644 index 00000000000..5ce676612eb --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/README.md @@ -0,0 +1,38 @@ +# create-svelte + +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npm create svelte@latest + +# create a new project in my-app +npm create svelte@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```bash +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. diff --git a/v3/internal/templates/sveltekit-ts/frontend/package-lock.json b/v3/internal/templates/sveltekit-ts/frontend/package-lock.json new file mode 100644 index 00000000000..4ba4bd3f3a2 --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/package-lock.json @@ -0,0 +1,1288 @@ +{ + "name": "frontend", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "0.0.1", + "dependencies": { + "@sveltejs/adapter-static": "^3.0.5", + "@wailsio/runtime": "^3.0.0-alpha.28" + }, + "devDependencies": { + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.2.7", + "svelte-check": "^4.0.0", + "typescript": "^5.0.0", + "vite": "^5.0.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sveltejs/adapter-static": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.5.tgz", + "integrity": "sha512-kFJR7RxeB6FBvrKZWAEzIALatgy11ISaaZbcPup8JdWUdrmmfUHHTJ738YHJTEfnCiiXi6aX8Q6ePY7tnSMD6Q==", + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.7.1.tgz", + "integrity": "sha512-TBVnkwgYQT3EafGQK6Eyh5FlLEBlRhCmqPTwcdOs+QdnyUc3eCAxRWtXlFxIWtmk6pqv11zdng8qTpThdTogew==", + "hasInstallScript": true, + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^0.6.0", + "devalue": "^5.1.0", + "esm-env": "^1.0.0", + "import-meta-resolve": "^4.1.0", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "sade": "^1.8.1", + "set-cookie-parser": "^2.6.0", + "sirv": "^3.0.0", + "tiny-glob": "^0.2.9" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.3" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.2.tgz", + "integrity": "sha512-Txsm1tJvtiYeLUVRNqxZGKR/mI+CzuIQuc2gn+YCs9rMTowpNZ2Nqt53JdL8KF9bLhAf2ruR/dr9eZCwdTriRA==", + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", + "debug": "^4.3.4", + "deepmerge": "^4.3.1", + "kleur": "^4.1.5", + "magic-string": "^0.30.10", + "svelte-hmr": "^0.16.0", + "vitefu": "^0.2.5" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", + "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, + "node_modules/@wailsio/runtime": { + "version": "3.0.0-alpha.28", + "resolved": "https://registry.npmjs.org/@wailsio/runtime/-/runtime-3.0.0-alpha.28.tgz", + "integrity": "sha512-caMnAcKxxDrIWYgCZAMY2kdL++X4ehO2+JvH5na21xfDqz3VnHkEjxsH3jfhgd34M8LY80QEH8iqoMYytDFE/g==", + "dependencies": { + "nanoid": "^5.0.7" + } + }, + "node_modules/@wailsio/runtime/node_modules/nanoid": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", + "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/chokidar": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/code-red": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", + "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@types/estree": "^1.0.1", + "acorn": "^8.10.0", + "estree-walker": "^3.0.3", + "periscopic": "^3.1.0" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/devalue": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz", + "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/esm-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", + "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==" + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/fdir": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.0.tgz", + "integrity": "sha512-3oB133prH1o4j/L5lLW7uOCF1PlD+/It2L0eL/iAqWMB91RBbqTewABqxhj0ibBd90EEmWZq7ntIWzVaWcXTGQ==", + "dev": true, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" + }, + "node_modules/magic-string": { + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/rollup": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", + "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.0", + "@rollup/rollup-android-arm64": "4.24.0", + "@rollup/rollup-darwin-arm64": "4.24.0", + "@rollup/rollup-darwin-x64": "4.24.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", + "@rollup/rollup-linux-arm-musleabihf": "4.24.0", + "@rollup/rollup-linux-arm64-gnu": "4.24.0", + "@rollup/rollup-linux-arm64-musl": "4.24.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", + "@rollup/rollup-linux-riscv64-gnu": "4.24.0", + "@rollup/rollup-linux-s390x-gnu": "4.24.0", + "@rollup/rollup-linux-x64-gnu": "4.24.0", + "@rollup/rollup-linux-x64-musl": "4.24.0", + "@rollup/rollup-win32-arm64-msvc": "4.24.0", + "@rollup/rollup-win32-ia32-msvc": "4.24.0", + "@rollup/rollup-win32-x64-msvc": "4.24.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz", + "integrity": "sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==" + }, + "node_modules/sirv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", + "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/svelte": { + "version": "4.2.19", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.19.tgz", + "integrity": "sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==", + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@jridgewell/sourcemap-codec": "^1.4.15", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/estree": "^1.0.1", + "acorn": "^8.9.0", + "aria-query": "^5.3.0", + "axobject-query": "^4.0.0", + "code-red": "^1.0.3", + "css-tree": "^2.3.1", + "estree-walker": "^3.0.3", + "is-reference": "^3.0.1", + "locate-character": "^3.0.0", + "magic-string": "^0.30.4", + "periscopic": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/svelte-check": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.0.5.tgz", + "integrity": "sha512-icBTBZ3ibBaywbXUat3cK6hB5Du+Kq9Z8CRuyLmm64XIe2/r+lQcbuBx/IQgsbrC+kT2jQ0weVpZSSRIPwB6jQ==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "chokidar": "^4.0.1", + "fdir": "^6.2.0", + "picocolors": "^1.0.0", + "sade": "^1.7.4" + }, + "bin": { + "svelte-check": "bin/svelte-check" + }, + "engines": { + "node": ">= 18.0.0" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "typescript": ">=5.0.0" + } + }, + "node_modules/svelte-hmr": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", + "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", + "engines": { + "node": "^12.20 || ^14.13.1 || >= 16" + }, + "peerDependencies": { + "svelte": "^3.19.0 || ^4.0.0" + } + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "5.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz", + "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + } + } +} diff --git a/v3/internal/templates/sveltekit-ts/frontend/package.json b/v3/internal/templates/sveltekit-ts/frontend/package.json new file mode 100644 index 00000000000..e60814c8558 --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/package.json @@ -0,0 +1,25 @@ +{ + "name": "frontend", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch" + }, + "devDependencies": { + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.2.7", + "svelte-check": "^4.0.0", + "typescript": "^5.0.0", + "vite": "^5.0.3" + }, + "type": "module", + "dependencies": { + "@sveltejs/adapter-static": "^3.0.5", + "@wailsio/runtime": "^3.0.0-alpha.28" + } +} diff --git a/v3/internal/templates/sveltekit-ts/frontend/src/app.d.ts b/v3/internal/templates/sveltekit-ts/frontend/src/app.d.ts new file mode 100644 index 00000000000..743f07b2e50 --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/src/app.d.ts @@ -0,0 +1,13 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface PageState {} + // interface Platform {} + } +} + +export {}; diff --git a/v3/internal/templates/sveltekit-ts/frontend/src/app.html b/v3/internal/templates/sveltekit-ts/frontend/src/app.html new file mode 100644 index 00000000000..e1858401ad1 --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + + %sveltekit.body% + + diff --git a/v3/internal/templates/sveltekit-ts/frontend/src/lib/index.ts b/v3/internal/templates/sveltekit-ts/frontend/src/lib/index.ts new file mode 100644 index 00000000000..856f2b6c38a --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/src/lib/index.ts @@ -0,0 +1 @@ +// place files you want to import through the `$lib` alias in this folder. diff --git a/v3/internal/templates/sveltekit-ts/frontend/src/routes/+layout.ts b/v3/internal/templates/sveltekit-ts/frontend/src/routes/+layout.ts new file mode 100644 index 00000000000..ceccaaf67a2 --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/src/routes/+layout.ts @@ -0,0 +1,2 @@ +export const prerender = true; +export const ssr = false; diff --git a/v3/internal/templates/sveltekit-ts/frontend/src/routes/+page.svelte b/v3/internal/templates/sveltekit-ts/frontend/src/routes/+page.svelte new file mode 100644 index 00000000000..8638ade9649 --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/src/routes/+page.svelte @@ -0,0 +1,50 @@ + + + + + + + + + + + + Wails + Svelte + {result} + + + + Greet + + + + + + diff --git a/v3/internal/templates/sveltekit-ts/frontend/static/Inter-Medium.ttf b/v3/internal/templates/sveltekit-ts/frontend/static/Inter-Medium.ttf new file mode 100644 index 00000000000..a01f3777a6f Binary files /dev/null and b/v3/internal/templates/sveltekit-ts/frontend/static/Inter-Medium.ttf differ diff --git a/v3/internal/templates/sveltekit-ts/frontend/static/favicon.png b/v3/internal/templates/sveltekit-ts/frontend/static/favicon.png new file mode 100644 index 00000000000..825b9e65af7 Binary files /dev/null and b/v3/internal/templates/sveltekit-ts/frontend/static/favicon.png differ diff --git a/v3/internal/templates/sveltekit-ts/frontend/static/style.css b/v3/internal/templates/sveltekit-ts/frontend/static/style.css new file mode 100644 index 00000000000..865f7f38ae5 --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/static/style.css @@ -0,0 +1,161 @@ +:root { + font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", + "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: rgba(27, 38, 54, 1); + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +* { + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + src: local(""), + url("./Inter-Medium.ttf") format("truetype"); +} + +h3 { + font-size: 3em; + line-height: 1.1; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} + +a:hover { + color: #535bf2; +} + +button { + width: 60px; + height: 30px; + line-height: 30px; + border-radius: 3px; + border: none; + margin: 0 0 0 20px; + padding: 0 8px; + cursor: pointer; +} + +.result { + height: 20px; + line-height: 20px; +} + +body { + margin: 0; + display: flex; + place-items: center; + place-content: center; + min-width: 320px; + min-height: 100vh; +} + +.container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; +} + +.logo:hover { + filter: drop-shadow(0 0 2em #e80000aa); +} + +.logo.vanilla:hover { + filter: drop-shadow(0 0 2em #f7df1eaa); +} + +.result { + height: 20px; + line-height: 20px; + margin: 1.5rem auto; + text-align: center; +} + +.footer { + margin-top: 1rem; + align-content: center; + text-align: center; + color: rgba(255, 255, 255, 0.67); +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + + a:hover { + color: #747bff; + } + + button { + background-color: #f9f9f9; + } +} + + +.input-box .btn:hover { + background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%); + color: #333333; +} + +.input-box .input { + border: none; + border-radius: 3px; + outline: none; + height: 30px; + line-height: 30px; + padding: 0 10px; + color: black; + background-color: rgba(240, 240, 240, 1); + -webkit-font-smoothing: antialiased; +} + +.input-box .input:hover { + border: none; + background-color: rgba(255, 255, 255, 1); +} + +.input-box .input:focus { + border: none; + background-color: rgba(255, 255, 255, 1); +} \ No newline at end of file diff --git a/v3/internal/templates/sveltekit-ts/frontend/static/svelte.svg b/v3/internal/templates/sveltekit-ts/frontend/static/svelte.svg new file mode 100644 index 00000000000..c5e08481f8a --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/static/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v3/internal/templates/sveltekit-ts/frontend/static/wails.png b/v3/internal/templates/sveltekit-ts/frontend/static/wails.png new file mode 100644 index 00000000000..8bdf424833b Binary files /dev/null and b/v3/internal/templates/sveltekit-ts/frontend/static/wails.png differ diff --git a/v3/internal/templates/sveltekit-ts/frontend/svelte.config.js b/v3/internal/templates/sveltekit-ts/frontend/svelte.config.js new file mode 100644 index 00000000000..7acd7538667 --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/svelte.config.js @@ -0,0 +1,21 @@ +import adapter from '@sveltejs/adapter-static'; +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + preprocess: vitePreprocess(), + kit: { + // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. + // If your environment is not supported, or you settled on a specific environment, switch out the adapter. + // See https://kit.svelte.dev/docs/adapters for more information about adapters. + adapter: adapter({ + pages: 'dist', + assets: 'dist', + fallback: undefined, + precompress: false, + strict: true + }) + } +}; + +export default config; diff --git a/v3/internal/templates/sveltekit-ts/frontend/tsconfig.json b/v3/internal/templates/sveltekit-ts/frontend/tsconfig.json new file mode 100644 index 00000000000..2de4494e1ab --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "allowUnusedLabels": true, + "noUnusedLocals": false, + "moduleResolution": "bundler" + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias + // except $lib which is handled by https://kit.svelte.dev/docs/configuration#files + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/v3/internal/templates/sveltekit-ts/frontend/vite.config.ts b/v3/internal/templates/sveltekit-ts/frontend/vite.config.ts new file mode 100644 index 00000000000..e2a531f500a --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/frontend/vite.config.ts @@ -0,0 +1,16 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig, searchForWorkspaceRoot } from 'vite'; + +export default defineConfig({ + server: { + fs: { + allow: [ + // search up for workspace root + searchForWorkspaceRoot(process.cwd()), + // your custom rules + './bindings/*', + ], + }, + }, + plugins: [sveltekit()] +}); diff --git a/v3/internal/templates/sveltekit-ts/template.json b/v3/internal/templates/sveltekit-ts/template.json new file mode 100644 index 00000000000..3183d3e55b3 --- /dev/null +++ b/v3/internal/templates/sveltekit-ts/template.json @@ -0,0 +1,8 @@ +{ + "name": "SvelteKit Typescript + Vite", + "shortname": "sveltekit-ts", + "author": "Atterpac", + "description": "SvelteKit + TS + Vite development server", + "helpurl": "https://wails.io", + "version": 3 +} diff --git a/v3/internal/templates/sveltekit/frontend/.gitignore b/v3/internal/templates/sveltekit/frontend/.gitignore new file mode 100644 index 00000000000..79518f71645 --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/.gitignore @@ -0,0 +1,21 @@ +node_modules + +# Output +.output +.vercel +/.svelte-kit +/build + +# OS +.DS_Store +Thumbs.db + +# Env +.env +.env.* +!.env.example +!.env.test + +# Vite +vite.config.js.timestamp-* +vite.config.ts.timestamp-* diff --git a/v3/internal/templates/sveltekit/frontend/.npmrc b/v3/internal/templates/sveltekit/frontend/.npmrc new file mode 100644 index 00000000000..b6f27f13595 --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/.npmrc @@ -0,0 +1 @@ +engine-strict=true diff --git a/v3/internal/templates/sveltekit/frontend/README.md b/v3/internal/templates/sveltekit/frontend/README.md new file mode 100644 index 00000000000..5ce676612eb --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/README.md @@ -0,0 +1,38 @@ +# create-svelte + +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/main/packages/create-svelte). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npm create svelte@latest + +# create a new project in my-app +npm create svelte@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```bash +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. diff --git a/v3/internal/templates/sveltekit/frontend/frontend/Inter-Medium.ttf b/v3/internal/templates/sveltekit/frontend/frontend/Inter-Medium.ttf new file mode 100644 index 00000000000..a01f3777a6f Binary files /dev/null and b/v3/internal/templates/sveltekit/frontend/frontend/Inter-Medium.ttf differ diff --git a/v3/internal/templates/sveltekit/frontend/frontend/style.css b/v3/internal/templates/sveltekit/frontend/frontend/style.css new file mode 100644 index 00000000000..865f7f38ae5 --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/frontend/style.css @@ -0,0 +1,161 @@ +:root { + font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", + "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: rgba(27, 38, 54, 1); + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +* { + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + src: local(""), + url("./Inter-Medium.ttf") format("truetype"); +} + +h3 { + font-size: 3em; + line-height: 1.1; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} + +a:hover { + color: #535bf2; +} + +button { + width: 60px; + height: 30px; + line-height: 30px; + border-radius: 3px; + border: none; + margin: 0 0 0 20px; + padding: 0 8px; + cursor: pointer; +} + +.result { + height: 20px; + line-height: 20px; +} + +body { + margin: 0; + display: flex; + place-items: center; + place-content: center; + min-width: 320px; + min-height: 100vh; +} + +.container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; +} + +.logo:hover { + filter: drop-shadow(0 0 2em #e80000aa); +} + +.logo.vanilla:hover { + filter: drop-shadow(0 0 2em #f7df1eaa); +} + +.result { + height: 20px; + line-height: 20px; + margin: 1.5rem auto; + text-align: center; +} + +.footer { + margin-top: 1rem; + align-content: center; + text-align: center; + color: rgba(255, 255, 255, 0.67); +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + + a:hover { + color: #747bff; + } + + button { + background-color: #f9f9f9; + } +} + + +.input-box .btn:hover { + background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%); + color: #333333; +} + +.input-box .input { + border: none; + border-radius: 3px; + outline: none; + height: 30px; + line-height: 30px; + padding: 0 10px; + color: black; + background-color: rgba(240, 240, 240, 1); + -webkit-font-smoothing: antialiased; +} + +.input-box .input:hover { + border: none; + background-color: rgba(255, 255, 255, 1); +} + +.input-box .input:focus { + border: none; + background-color: rgba(255, 255, 255, 1); +} \ No newline at end of file diff --git a/v3/internal/templates/sveltekit/frontend/frontend/svelte.svg b/v3/internal/templates/sveltekit/frontend/frontend/svelte.svg new file mode 100644 index 00000000000..c5e08481f8a --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/frontend/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v3/internal/templates/sveltekit/frontend/frontend/wails.png b/v3/internal/templates/sveltekit/frontend/frontend/wails.png new file mode 100644 index 00000000000..8bdf424833b Binary files /dev/null and b/v3/internal/templates/sveltekit/frontend/frontend/wails.png differ diff --git a/v3/internal/templates/sveltekit/frontend/package-lock.json b/v3/internal/templates/sveltekit/frontend/package-lock.json new file mode 100644 index 00000000000..7e20bdb4555 --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/package-lock.json @@ -0,0 +1,1221 @@ +{ + "name": "frontend", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "frontend", + "version": "0.0.1", + "dependencies": { + "@sveltejs/adapter-static": "^3.0.5", + "@wailsio/runtime": "^3.0.0-alpha.28" + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^3.0.0", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.2.7", + "vite": "^5.0.3" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sveltejs/adapter-auto": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.2.5.tgz", + "integrity": "sha512-27LR+uKccZ62lgq4N/hvyU2G+hTP9fxWEAfnZcl70HnyfAjMSsGk1z/SjAPXNCD1mVJIE7IFu3TQ8cQ/UH3c0A==", + "dev": true, + "dependencies": { + "import-meta-resolve": "^4.1.0" + }, + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/adapter-static": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.5.tgz", + "integrity": "sha512-kFJR7RxeB6FBvrKZWAEzIALatgy11ISaaZbcPup8JdWUdrmmfUHHTJ738YHJTEfnCiiXi6aX8Q6ePY7tnSMD6Q==", + "peerDependencies": { + "@sveltejs/kit": "^2.0.0" + } + }, + "node_modules/@sveltejs/kit": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.7.1.tgz", + "integrity": "sha512-TBVnkwgYQT3EafGQK6Eyh5FlLEBlRhCmqPTwcdOs+QdnyUc3eCAxRWtXlFxIWtmk6pqv11zdng8qTpThdTogew==", + "hasInstallScript": true, + "dependencies": { + "@types/cookie": "^0.6.0", + "cookie": "^0.6.0", + "devalue": "^5.1.0", + "esm-env": "^1.0.0", + "import-meta-resolve": "^4.1.0", + "kleur": "^4.1.5", + "magic-string": "^0.30.5", + "mrmime": "^2.0.0", + "sade": "^1.8.1", + "set-cookie-parser": "^2.6.0", + "sirv": "^3.0.0", + "tiny-glob": "^0.2.9" + }, + "bin": { + "svelte-kit": "svelte-kit.js" + }, + "engines": { + "node": ">=18.13" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.3" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.2.tgz", + "integrity": "sha512-Txsm1tJvtiYeLUVRNqxZGKR/mI+CzuIQuc2gn+YCs9rMTowpNZ2Nqt53JdL8KF9bLhAf2ruR/dr9eZCwdTriRA==", + "dependencies": { + "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", + "debug": "^4.3.4", + "deepmerge": "^4.3.1", + "kleur": "^4.1.5", + "magic-string": "^0.30.10", + "svelte-hmr": "^0.16.0", + "vitefu": "^0.2.5" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte-inspector": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", + "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.0.0 || >=20" + }, + "peerDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.0.0 || ^5.0.0-next.0", + "vite": "^5.0.0" + } + }, + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, + "node_modules/@wailsio/runtime": { + "version": "3.0.0-alpha.28", + "resolved": "https://registry.npmjs.org/@wailsio/runtime/-/runtime-3.0.0-alpha.28.tgz", + "integrity": "sha512-caMnAcKxxDrIWYgCZAMY2kdL++X4ehO2+JvH5na21xfDqz3VnHkEjxsH3jfhgd34M8LY80QEH8iqoMYytDFE/g==", + "dependencies": { + "nanoid": "^5.0.7" + } + }, + "node_modules/@wailsio/runtime/node_modules/nanoid": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz", + "integrity": "sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/code-red": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", + "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@types/estree": "^1.0.1", + "acorn": "^8.10.0", + "estree-walker": "^3.0.3", + "periscopic": "^3.1.0" + } + }, + "node_modules/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/devalue": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz", + "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/esm-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", + "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==" + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==" + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==" + }, + "node_modules/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-reference": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", + "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/locate-character": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", + "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" + }, + "node_modules/magic-string": { + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==" + }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", + "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.0", + "@rollup/rollup-android-arm64": "4.24.0", + "@rollup/rollup-darwin-arm64": "4.24.0", + "@rollup/rollup-darwin-x64": "4.24.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", + "@rollup/rollup-linux-arm-musleabihf": "4.24.0", + "@rollup/rollup-linux-arm64-gnu": "4.24.0", + "@rollup/rollup-linux-arm64-musl": "4.24.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", + "@rollup/rollup-linux-riscv64-gnu": "4.24.0", + "@rollup/rollup-linux-s390x-gnu": "4.24.0", + "@rollup/rollup-linux-x64-gnu": "4.24.0", + "@rollup/rollup-linux-x64-musl": "4.24.0", + "@rollup/rollup-win32-arm64-msvc": "4.24.0", + "@rollup/rollup-win32-ia32-msvc": "4.24.0", + "@rollup/rollup-win32-x64-msvc": "4.24.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz", + "integrity": "sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==" + }, + "node_modules/sirv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", + "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/svelte": { + "version": "4.2.19", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.19.tgz", + "integrity": "sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==", + "dependencies": { + "@ampproject/remapping": "^2.2.1", + "@jridgewell/sourcemap-codec": "^1.4.15", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/estree": "^1.0.1", + "acorn": "^8.9.0", + "aria-query": "^5.3.0", + "axobject-query": "^4.0.0", + "code-red": "^1.0.3", + "css-tree": "^2.3.1", + "estree-walker": "^3.0.3", + "is-reference": "^3.0.1", + "locate-character": "^3.0.0", + "magic-string": "^0.30.4", + "periscopic": "^3.1.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/svelte-hmr": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", + "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", + "engines": { + "node": "^12.20 || ^14.13.1 || >= 16" + }, + "peerDependencies": { + "svelte": "^3.19.0 || ^4.0.0" + } + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/vite": { + "version": "5.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz", + "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", + "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + } + } +} diff --git a/v3/internal/templates/sveltekit/frontend/package.json b/v3/internal/templates/sveltekit/frontend/package.json new file mode 100644 index 00000000000..5c7a2d82bbc --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/package.json @@ -0,0 +1,22 @@ +{ + "name": "frontend", + "version": "0.0.1", + "private": true, + "scripts": { + "dev": "vite dev", + "build": "vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@sveltejs/adapter-auto": "^3.0.0", + "@sveltejs/kit": "^2.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.0", + "svelte": "^4.2.7", + "vite": "^5.0.3" + }, + "type": "module", + "dependencies": { + "@sveltejs/adapter-static": "^3.0.5", + "@wailsio/runtime": "^3.0.0-alpha.28" + } +} diff --git a/v3/internal/templates/sveltekit/frontend/src/app.html b/v3/internal/templates/sveltekit/frontend/src/app.html new file mode 100644 index 00000000000..2b3908e2c37 --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + + %sveltekit.body% + + diff --git a/v3/internal/templates/sveltekit/frontend/src/lib/index.js b/v3/internal/templates/sveltekit/frontend/src/lib/index.js new file mode 100644 index 00000000000..856f2b6c38a --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/src/lib/index.js @@ -0,0 +1 @@ +// place files you want to import through the `$lib` alias in this folder. diff --git a/v3/internal/templates/sveltekit/frontend/src/routes/+layout.js b/v3/internal/templates/sveltekit/frontend/src/routes/+layout.js new file mode 100644 index 00000000000..ceccaaf67a2 --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/src/routes/+layout.js @@ -0,0 +1,2 @@ +export const prerender = true; +export const ssr = false; diff --git a/v3/internal/templates/sveltekit/frontend/src/routes/+page.svelte b/v3/internal/templates/sveltekit/frontend/src/routes/+page.svelte new file mode 100644 index 00000000000..8638ade9649 --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/src/routes/+page.svelte @@ -0,0 +1,50 @@ + + + + + + + + + + + + Wails + Svelte + {result} + + + + Greet + + + + + + diff --git a/v3/internal/templates/sveltekit/frontend/static/Inter-Medium.ttf b/v3/internal/templates/sveltekit/frontend/static/Inter-Medium.ttf new file mode 100644 index 00000000000..a01f3777a6f Binary files /dev/null and b/v3/internal/templates/sveltekit/frontend/static/Inter-Medium.ttf differ diff --git a/v3/internal/templates/sveltekit/frontend/static/style.css b/v3/internal/templates/sveltekit/frontend/static/style.css new file mode 100644 index 00000000000..865f7f38ae5 --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/static/style.css @@ -0,0 +1,161 @@ +:root { + font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", + "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + font-size: 16px; + line-height: 24px; + font-weight: 400; + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: rgba(27, 38, 54, 1); + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-text-size-adjust: 100%; +} + +* { + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; +} + +@font-face { + font-family: "Inter"; + font-style: normal; + font-weight: 400; + src: local(""), + url("./Inter-Medium.ttf") format("truetype"); +} + +h3 { + font-size: 3em; + line-height: 1.1; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} + +a:hover { + color: #535bf2; +} + +button { + width: 60px; + height: 30px; + line-height: 30px; + border-radius: 3px; + border: none; + margin: 0 0 0 20px; + padding: 0 8px; + cursor: pointer; +} + +.result { + height: 20px; + line-height: 20px; +} + +body { + margin: 0; + display: flex; + place-items: center; + place-content: center; + min-width: 320px; + min-height: 100vh; +} + +.container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; +} + +.logo:hover { + filter: drop-shadow(0 0 2em #e80000aa); +} + +.logo.vanilla:hover { + filter: drop-shadow(0 0 2em #f7df1eaa); +} + +.result { + height: 20px; + line-height: 20px; + margin: 1.5rem auto; + text-align: center; +} + +.footer { + margin-top: 1rem; + align-content: center; + text-align: center; + color: rgba(255, 255, 255, 0.67); +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + + a:hover { + color: #747bff; + } + + button { + background-color: #f9f9f9; + } +} + + +.input-box .btn:hover { + background-image: linear-gradient(to top, #cfd9df 0%, #e2ebf0 100%); + color: #333333; +} + +.input-box .input { + border: none; + border-radius: 3px; + outline: none; + height: 30px; + line-height: 30px; + padding: 0 10px; + color: black; + background-color: rgba(240, 240, 240, 1); + -webkit-font-smoothing: antialiased; +} + +.input-box .input:hover { + border: none; + background-color: rgba(255, 255, 255, 1); +} + +.input-box .input:focus { + border: none; + background-color: rgba(255, 255, 255, 1); +} \ No newline at end of file diff --git a/v3/internal/templates/sveltekit/frontend/static/svelte.svg b/v3/internal/templates/sveltekit/frontend/static/svelte.svg new file mode 100644 index 00000000000..c5e08481f8a --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/static/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/v3/internal/templates/sveltekit/frontend/static/wails.png b/v3/internal/templates/sveltekit/frontend/static/wails.png new file mode 100644 index 00000000000..8bdf424833b Binary files /dev/null and b/v3/internal/templates/sveltekit/frontend/static/wails.png differ diff --git a/v3/internal/templates/sveltekit/frontend/svelte.config.js b/v3/internal/templates/sveltekit/frontend/svelte.config.js new file mode 100644 index 00000000000..7f2998d8942 --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/svelte.config.js @@ -0,0 +1,19 @@ +import adapter from '@sveltejs/adapter-static'; + +/** @type {import('@sveltejs/kit').Config} */ +const config = { + kit: { + // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. + // If your environment is not supported, or you settled on a specific environment, switch out the adapter. + // See https://kit.svelte.dev/docs/adapters for more information about adapters. + adapter: adapter({ + pages: 'dist', + assets: 'dist', + fallback: undefined, + precompress: false, + strict: true + }) + } +}; + +export default config; diff --git a/v3/internal/templates/sveltekit/frontend/vite.config.js b/v3/internal/templates/sveltekit/frontend/vite.config.js new file mode 100644 index 00000000000..e2a531f500a --- /dev/null +++ b/v3/internal/templates/sveltekit/frontend/vite.config.js @@ -0,0 +1,16 @@ +import { sveltekit } from '@sveltejs/kit/vite'; +import { defineConfig, searchForWorkspaceRoot } from 'vite'; + +export default defineConfig({ + server: { + fs: { + allow: [ + // search up for workspace root + searchForWorkspaceRoot(process.cwd()), + // your custom rules + './bindings/*', + ], + }, + }, + plugins: [sveltekit()] +}); diff --git a/v3/internal/templates/sveltekit/template.json b/v3/internal/templates/sveltekit/template.json new file mode 100644 index 00000000000..6dc741057d7 --- /dev/null +++ b/v3/internal/templates/sveltekit/template.json @@ -0,0 +1,8 @@ +{ + "name": "SvelteKit Typescript + Vite", + "shortname": "svelte-ts", + "author": "Atterpac", + "description": "SvelteKit + Vite development server", + "helpurl": "https://wails.io", + "version": 3 +} diff --git a/v3/internal/templates/vanilla-ts/template.json b/v3/internal/templates/vanilla-ts/template.json index 0fc3c7241cf..1c25d224b00 100644 --- a/v3/internal/templates/vanilla-ts/template.json +++ b/v3/internal/templates/vanilla-ts/template.json @@ -2,7 +2,7 @@ "name": "Vanilla + Vite (Typescript)", "shortname": "vanilla-ts", "author": "Lea Anthony", - "description": "Vanilla + Vite development server", + "description": "Vanilla + TS + Vite development server", "helpurl": "https://wails.io", "version": 3 } \ No newline at end of file diff --git a/v3/internal/templates/vue-ts/template.json b/v3/internal/templates/vue-ts/template.json index 720ac3db607..7e6404a59c6 100644 --- a/v3/internal/templates/vue-ts/template.json +++ b/v3/internal/templates/vue-ts/template.json @@ -2,7 +2,7 @@ "name": "Vue + Vite (Typescript)", "shortname": "vue-ts", "author": "Lea Anthony", - "description": "Vue + Vite development server", + "description": "Vue + TS + Vite development server", "helpurl": "https://wails.io", "version": 3 } \ No newline at end of file diff --git a/v3/pkg/application/application.go b/v3/pkg/application/application.go index 94a291e2bbb..9d575a14536 100644 --- a/v3/pkg/application/application.go +++ b/v3/pkg/application/application.go @@ -142,7 +142,7 @@ func New(appOptions Options) *App { if err != nil { name := service.options.Name if name == "" { - name = getServiceName(service) + name = getServiceName(service.instance) } globalApplication.Logger.Error("OnStartup() failed:", "service", name, "error", err.Error()) continue @@ -1013,3 +1013,13 @@ func (a *App) shouldQuit() bool { } return true } + +// Path returns the path for the given selector +func (a *App) Path(selector Path) string { + return paths[selector] +} + +// Paths returns the paths for the given selector +func (a *App) Paths(selector Paths) []string { + return pathdirs[selector] +} diff --git a/v3/pkg/application/application_darwin.go b/v3/pkg/application/application_darwin.go index 69de385072d..e1bd4c54d19 100644 --- a/v3/pkg/application/application_darwin.go +++ b/v3/pkg/application/application_darwin.go @@ -363,3 +363,16 @@ func (a *App) platformEnvironment() map[string]any { func fatalHandler(errFunc func(error)) { return } + +//export HandleOpenFile +func HandleOpenFile(filePath *C.char) { + goFilepath := C.GoString(filePath) + // Create new application event context + eventContext := newApplicationEventContext() + eventContext.setOpenedWithFile(goFilepath) + // EmitEvent application started event + applicationEvents <- &ApplicationEvent{ + Id: uint(events.Common.ApplicationOpenedWithFile), + ctx: eventContext, + } +} diff --git a/v3/pkg/application/application_darwin_delegate.h b/v3/pkg/application/application_darwin_delegate.h index f60dfd0bba8..1523356b27b 100644 --- a/v3/pkg/application/application_darwin_delegate.h +++ b/v3/pkg/application/application_darwin_delegate.h @@ -5,10 +5,12 @@ #import -@interface AppDelegate : NSObject +@interface AppDelegate : NSResponder @property bool shouldTerminateWhenLastWindowClosed; @property bool shuttingDown; - (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app; @end +extern void HandleOpenFile(char *); + #endif diff --git a/v3/pkg/application/application_darwin_delegate.m b/v3/pkg/application/application_darwin_delegate.m index 2b91eb4d2f1..82a91df2f29 100644 --- a/v3/pkg/application/application_darwin_delegate.m +++ b/v3/pkg/application/application_darwin_delegate.m @@ -9,6 +9,12 @@ - (void)dealloc { [super dealloc]; } +-(BOOL)application:(NSApplication *)sender openFile:(NSString *)filename + { + const char* utf8FileName = filename.UTF8String; + HandleOpenFile((char*)utf8FileName); + return YES; + } // Create the applicationShouldTerminateAfterLastWindowClosed: method - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication { diff --git a/v3/pkg/application/application_options.go b/v3/pkg/application/application_options.go index b9a41256765..3fb304badd5 100644 --- a/v3/pkg/application/application_options.go +++ b/v3/pkg/application/application_options.go @@ -109,6 +109,11 @@ type Options struct { // ErrorHandler is called when an error occurs ErrorHandler func(err error) + // File extensions associated with the application + // Example: [".txt", ".md"] + // The '.' is required + FileAssociations []string + // This blank field ensures types from other packages // are never convertible to Options. // This property, in turn, improves the accuracy of the binding generator. diff --git a/v3/pkg/application/application_windows.go b/v3/pkg/application/application_windows.go index a3015af9333..ee2d411aa54 100644 --- a/v3/pkg/application/application_windows.go +++ b/v3/pkg/application/application_windows.go @@ -4,6 +4,9 @@ package application import ( "fmt" + "os" + "path/filepath" + "slices" "sync" "syscall" "unsafe" @@ -131,6 +134,27 @@ func (m *windowsApp) run() error { Id: uint(events.Windows.ApplicationStarted), ctx: blankApplicationEventContext, } + + // Check if there is 1 parameter passed to the application + // and if the extension matches the options.FileAssociations string + println("Checking args") + if len(os.Args) == 2 { + arg := os.Args[1] + ext := filepath.Ext(arg) + println("Got extension: ", ext) + if slices.Contains(m.parent.options.FileAssociations, ext) { + println("Slices contains") + eventContext := newApplicationEventContext() + eventContext.setOpenedWithFile(arg) + // EmitEvent application started event + println("sending event") + applicationEvents <- &ApplicationEvent{ + Id: uint(events.Common.ApplicationOpenedWithFile), + ctx: eventContext, + } + } + } + _ = m.runMainLoop() return nil diff --git a/v3/pkg/application/context_application_event.go b/v3/pkg/application/context_application_event.go index 2cd1ca2c0a0..468634f2286 100644 --- a/v3/pkg/application/context_application_event.go +++ b/v3/pkg/application/context_application_event.go @@ -4,6 +4,7 @@ var blankApplicationEventContext = &ApplicationEventContext{} const ( openedFiles = "openedFiles" + filename = "filename" ) type ApplicationEventContext struct { @@ -55,6 +56,22 @@ func (c ApplicationEventContext) setData(data map[string]any) { c.data = data } +func (c ApplicationEventContext) setOpenedWithFile(filepath string) { + c.data[filename] = filepath +} + +func (c ApplicationEventContext) Filename() string { + filename, ok := c.data[filename] + if !ok { + return "" + } + result, ok := filename.(string) + if !ok { + return "" + } + return result +} + func newApplicationEventContext() *ApplicationEventContext { return &ApplicationEventContext{ data: make(map[string]any), diff --git a/v3/pkg/application/dialogs_darwin.go b/v3/pkg/application/dialogs_darwin.go index 6f83f5a852e..a4c73a852da 100644 --- a/v3/pkg/application/dialogs_darwin.go +++ b/v3/pkg/application/dialogs_darwin.go @@ -19,23 +19,21 @@ extern void dialogCallback(int id, int buttonPressed); static void showAboutBox(char* title, char *message, void *icon, int length) { // run on main thread - // dispatch_async(dispatch_get_main_queue(), ^{ - NSAlert *alert = [[NSAlert alloc] init]; - if (title != NULL) { - [alert setMessageText:[NSString stringWithUTF8String:title]]; - free(title); - } - if (message != NULL) { - [alert setInformativeText:[NSString stringWithUTF8String:message]]; - free(message); - } - if (icon != NULL) { - NSImage *image = [[NSImage alloc] initWithData:[NSData dataWithBytes:icon length:length]]; - [alert setIcon:image]; - } - [alert setAlertStyle:NSAlertStyleInformational]; - [alert runModal]; - // }); + NSAlert *alert = [[NSAlert alloc] init]; + if (title != NULL) { + [alert setMessageText:[NSString stringWithUTF8String:title]]; + free(title); + } + if (message != NULL) { + [alert setInformativeText:[NSString stringWithUTF8String:message]]; + free(message); + } + if (icon != NULL) { + NSImage *image = [[NSImage alloc] initWithData:[NSData dataWithBytes:icon length:length]]; + [alert setIcon:image]; + } + [alert setAlertStyle:NSAlertStyleInformational]; + [alert runModal]; } diff --git a/v3/pkg/application/linux_cgo.go b/v3/pkg/application/linux_cgo.go index 3541c27ccf9..ac9465b9dce 100644 --- a/v3/pkg/application/linux_cgo.go +++ b/v3/pkg/application/linux_cgo.go @@ -7,6 +7,7 @@ import ( "regexp" "strings" "sync" + "time" "unsafe" "github.com/wailsapp/wails/v3/internal/assetserver/webview" @@ -1480,8 +1481,22 @@ func onUriList(extracted **C.char, data unsafe.Pointer) { } } +var debounceTimer *time.Timer +var isDebouncing bool = false //export onKeyPressEvent -func onKeyPressEvent(widget *C.GtkWidget, event *C.GdkEventKey, userData C.uintptr_t) C.gboolean { +func onKeyPressEvent(_ *C.GtkWidget, event *C.GdkEventKey, userData C.uintptr_t) C.gboolean { + // Keypress re-emits if the key is pressed over a certain threshold so we need a debounce + if isDebouncing { + debounceTimer.Reset(50 * time.Millisecond) + return C.gboolean(0) + } + + // Start the debounce + isDebouncing = true + debounceTimer = time.AfterFunc(50*time.Millisecond, func() { + isDebouncing = false + }) + windowID := uint(C.uint(userData)) if accelerator, ok := getKeyboardState(event); ok { windowKeyEvents <- &windowKeyEvent{ diff --git a/v3/pkg/application/path.go b/v3/pkg/application/path.go new file mode 100644 index 00000000000..867e5b67814 --- /dev/null +++ b/v3/pkg/application/path.go @@ -0,0 +1,123 @@ +package application + +import "github.com/adrg/xdg" + +type Path int + +const ( + // PathHome is the user's home directory. + PathHome Path = iota + + // PathDataHome defines the base directory relative to which user-specific + // data files should be stored. This directory is defined by the + // $XDG_DATA_HOME environment variable. If the variable is not set, + // a default equal to $HOME/.local/share should be used. + PathDataHome + + // PathConfigHome defines the base directory relative to which user-specific + // configuration files should be written. This directory is defined by + // the $XDG_CONFIG_HOME environment variable. If the variable is + // not set, a default equal to $HOME/.config should be used. + PathConfigHome + + // PathStateHome defines the base directory relative to which user-specific + // state files should be stored. This directory is defined by the + // $XDG_STATE_HOME environment variable. If the variable is not set, + // a default equal to ~/.local/state should be used. + PathStateHome + + // PathCacheHome defines the base directory relative to which user-specific + // non-essential (cached) data should be written. This directory is + // defined by the $XDG_CACHE_HOME environment variable. If the variable + // is not set, a default equal to $HOME/.cache should be used. + PathCacheHome + + // PathRuntimeDir defines the base directory relative to which user-specific + // non-essential runtime files and other file objects (such as sockets, + // named pipes, etc.) should be stored. This directory is defined by the + // $XDG_RUNTIME_DIR environment variable. If the variable is not set, + // applications should fall back to a replacement directory with similar + // capabilities. Applications should use this directory for communication + // and synchronization purposes and should not place larger files in it, + // since it might reside in runtime memory and cannot necessarily be + // swapped out to disk. + PathRuntimeDir + + // PathDesktop defines the location of the user's desktop directory. + PathDesktop + + // PathDownload defines a suitable location for user downloaded files. + PathDownload + + // PathDocuments defines a suitable location for user document files. + PathDocuments + + // PathMusic defines a suitable location for user audio files. + PathMusic + + // PathPictures defines a suitable location for user image files. + PathPictures + + // PathVideos defines a suitable location for user video files. + PathVideos + + // PathTemplates defines a suitable location for user template files. + PathTemplates + + // PathPublicShare defines a suitable location for user shared files. + PathPublicShare +) + +var paths = map[Path]string{ + PathHome: xdg.Home, + PathDataHome: xdg.DataHome, + PathConfigHome: xdg.ConfigHome, + PathStateHome: xdg.StateHome, + PathCacheHome: xdg.CacheHome, + PathRuntimeDir: xdg.RuntimeDir, + PathDesktop: xdg.UserDirs.Desktop, + PathDownload: xdg.UserDirs.Download, + PathDocuments: xdg.UserDirs.Documents, + PathMusic: xdg.UserDirs.Music, + PathPictures: xdg.UserDirs.Pictures, + PathVideos: xdg.UserDirs.Videos, + PathTemplates: xdg.UserDirs.Templates, + PathPublicShare: xdg.UserDirs.PublicShare, +} + +type Paths int + +const ( + // PathsDataDirs defines the preference-ordered set of base directories to + // search for data files in addition to the DataHome base directory. + // This set of directories is defined by the $XDG_DATA_DIRS environment + // variable. If the variable is not set, the default directories + // to be used are /usr/local/share and /usr/share, in that order. The + // DataHome directory is considered more important than any of the + // directories defined by DataDirs. Therefore, user data files should be + // written relative to the DataHome directory, if possible. + PathsDataDirs = iota + + // PathsConfigDirs defines the preference-ordered set of base directories + // search for configuration files in addition to the ConfigHome base + // directory. This set of directories is defined by the $XDG_CONFIG_DIRS + // environment variable. If the variable is not set, a default equal + // to /etc/xdg should be used. The ConfigHome directory is considered + // more important than any of the directories defined by ConfigDirs. + // Therefore, user config files should be written relative to the + // ConfigHome directory, if possible. + PathsConfigDirs + + // PathsFontDirs defines the common locations where font files are stored. + PathsFontDirs + + // PathsApplicationDirs defines the common locations of applications. + PathsApplicationDirs +) + +var pathdirs = map[Paths][]string{ + PathsDataDirs: xdg.DataDirs, + PathsConfigDirs: xdg.ConfigDirs, + PathsFontDirs: xdg.FontDirs, + PathsApplicationDirs: xdg.ApplicationDirs, +} diff --git a/v3/pkg/application/roles.go b/v3/pkg/application/roles.go index 4786c986252..a6e6f177c36 100644 --- a/v3/pkg/application/roles.go +++ b/v3/pkg/application/roles.go @@ -121,7 +121,6 @@ func NewEditMenu() *MenuItem { editMenu.AddRole(Copy) editMenu.AddRole(Paste) if runtime.GOOS == "darwin" { - editMenu.AddRole(PasteAndMatchStyle) editMenu.AddRole(PasteAndMatchStyle) editMenu.AddRole(Delete) editMenu.AddRole(SelectAll) diff --git a/v3/pkg/application/screenmanager.go b/v3/pkg/application/screenmanager.go index 9756d5ee272..70e2b056510 100644 --- a/v3/pkg/application/screenmanager.go +++ b/v3/pkg/application/screenmanager.go @@ -362,18 +362,17 @@ func (s *Screen) physicalToDipRect(physicalRect Rect) Rect { // Layout screens in the virtual space with DIP calculations and cache the screens // for future coordinate transformation between the physical and logical (DIP) space func (m *ScreenManager) LayoutScreens(screens []*Screen) error { - if screens == nil || len(screens) == 0 { - return fmt.Errorf("screens parameter is nil or empty") - } - m.screens = screens + if screens == nil || len(screens) == 0 { + return fmt.Errorf("screens parameter is nil or empty") + } + m.screens = screens - err := m.calculateScreensDipCoordinates() - if err != nil { - return err - } + err := m.calculateScreensDipCoordinates() + if err != nil { + return err + } - return nil -} + return nil } func (m *ScreenManager) Screens() []*Screen { diff --git a/v3/pkg/application/webview_window.go b/v3/pkg/application/webview_window.go index 11a97ce1f6b..5aed72475a1 100644 --- a/v3/pkg/application/webview_window.go +++ b/v3/pkg/application/webview_window.go @@ -11,6 +11,7 @@ import ( "github.com/leaanthony/u" "github.com/samber/lo" + "github.com/wailsapp/wails/v3/internal/assetserver" "github.com/wailsapp/wails/v3/pkg/events" ) @@ -432,10 +433,11 @@ func (w *WebviewWindow) Hide() Window { } func (w *WebviewWindow) SetURL(s string) Window { - w.options.URL = s + url, _ := assetserver.GetStartURL(s) + w.options.URL = url if w.impl != nil { InvokeSync(func() { - w.impl.setURL(s) + w.impl.setURL(url) }) } return w @@ -724,7 +726,7 @@ func (w *WebviewWindow) startResize(border string) error { // Center centers the window on the screen func (w *WebviewWindow) Center() { if w.impl == nil && !w.isDestroyed() { - w.options.Centered = true + w.options.InitialPosition = WindowCentered return } InvokeSync(w.impl.center) diff --git a/v3/pkg/application/webview_window_darwin.go b/v3/pkg/application/webview_window_darwin.go index 1971f4354ce..27e97aecc1d 100644 --- a/v3/pkg/application/webview_window_darwin.go +++ b/v3/pkg/application/webview_window_darwin.go @@ -514,9 +514,22 @@ void windowSetAppearanceTypeByName(void* nsWindow, const char *appearanceName) { // Center window on current monitor void windowCenter(void* nsWindow) { - [(WebviewWindow*)nsWindow center]; + WebviewWindow* window = (WebviewWindow*)nsWindow; + NSScreen* screen = [window screen]; + if (screen == NULL) { + screen = [NSScreen mainScreen]; + } + + NSRect screenFrame = [screen frame]; + NSRect windowFrame = [window frame]; + + CGFloat x = screenFrame.origin.x + (screenFrame.size.width - windowFrame.size.width) / 2; + CGFloat y = screenFrame.origin.y + (screenFrame.size.height - windowFrame.size.height) / 2; + + [window setFrame:NSMakeRect(x, y, windowFrame.size.width, windowFrame.size.height) display:YES]; } + // Get the current size of the window void windowGetSize(void* nsWindow, int* width, int* height) { NSRect frame = [(WebviewWindow*)nsWindow frame]; @@ -557,12 +570,18 @@ void windowGetPosition(void* nsWindow, int* x, int* y) { } void windowSetPosition(void* nsWindow, int x, int y) { - NSRect frame = [(WebviewWindow*)nsWindow frame]; - frame.origin.x = x; - frame.origin.y = y; - [(WebviewWindow*)nsWindow setFrame:frame display:YES]; + WebviewWindow* window = (WebviewWindow*)nsWindow; + NSScreen* screen = [window screen]; + if (screen == NULL) { + screen = [NSScreen mainScreen]; + } + NSRect frame = [window frame]; + frame.origin.x = x; + frame.origin.y = (screen.frame.size.height - frame.size.height) - y; + [window setFrame:frame display:YES]; } + // Destroy window void windowDestroy(void* nsWindow) { [(WebviewWindow*)nsWindow close]; @@ -1165,7 +1184,6 @@ func (w *macosWebviewWindow) run() { w.getWebviewPreferences(), ) w.setTitle(options.Title) - w.setAlwaysOnTop(options.AlwaysOnTop) w.setResizable(!options.DisableResize) if options.MinWidth != 0 || options.MinHeight != 0 { w.setMinSize(options.MinWidth, options.MinHeight) @@ -1230,7 +1248,11 @@ func (w *macosWebviewWindow) run() { w.fullscreen() case WindowStateNormal: } - C.windowCenter(w.nsWindow) + if w.parent.options.InitialPosition == WindowCentered { + C.windowCenter(w.nsWindow) + } else { + w.setPosition(options.X, options.Y) + } startURL, err := assetserver.GetStartURL(options.URL) if err != nil { @@ -1249,13 +1271,15 @@ func (w *macosWebviewWindow) run() { C.windowInjectCSS(w.nsWindow, C.CString(options.CSS)) } if !options.Hidden { - C.windowShow(w.nsWindow) + w.parent.Show() w.setHasShadow(!options.Mac.DisableShadow) + w.setAlwaysOnTop(options.AlwaysOnTop) } else { // We have to wait until the window is shown before we can remove the shadow var cancel func() cancel = w.parent.OnWindowEvent(events.Mac.WindowDidBecomeKey, func(_ *WindowEvent) { w.setHasShadow(!options.Mac.DisableShadow) + w.setAlwaysOnTop(options.AlwaysOnTop) cancel() }) } diff --git a/v3/pkg/application/webview_window_linux.go b/v3/pkg/application/webview_window_linux.go index 828ece800d1..e77cd7bd823 100644 --- a/v3/pkg/application/webview_window_linux.go +++ b/v3/pkg/application/webview_window_linux.go @@ -295,11 +295,12 @@ func (w *linuxWebviewWindow) run() { w.setFrameless(w.parent.options.Frameless) - if w.parent.options.X != 0 || w.parent.options.Y != 0 { - w.setRelativePosition(w.parent.options.X, w.parent.options.Y) + if w.parent.options.InitialPosition == WindowCentered { + C.windowCenter(w.nsWindow) } else { - w.center() + w.setPosition(options.X, options.Y) } + switch w.parent.options.StartState { case WindowStateMaximised: w.maximise() @@ -352,10 +353,10 @@ func (w *linuxWebviewWindow) run() { } if !w.parent.options.Hidden { w.show() - if w.parent.options.X != 0 || w.parent.options.Y != 0 { - w.setRelativePosition(w.parent.options.X, w.parent.options.Y) + if w.parent.options.InitialPosition == WindowCentered { + w.center() } else { - w.center() // needs to be queued until after GTK starts up! + w.setRelativePosition(w.parent.options.X, w.parent.options.Y) } } if w.parent.options.DevToolsEnabled || globalApplication.isDebugMode { diff --git a/v3/pkg/application/webview_window_options.go b/v3/pkg/application/webview_window_options.go index beddeff3c70..0abe58ab5f4 100644 --- a/v3/pkg/application/webview_window_options.go +++ b/v3/pkg/application/webview_window_options.go @@ -22,6 +22,13 @@ const ( ButtonHidden ButtonState = 2 ) +type WindowStartPosition int + +const ( + WindowCentered WindowStartPosition = 0 + WindowXY WindowStartPosition = 1 +) + type WebviewWindowOptions struct { // Name is a unique identifier that can be given to a window. Name string @@ -63,9 +70,6 @@ type WebviewWindowOptions struct { // Default: WindowStateNormal StartState WindowState - // Centered will center the window on the screen. - Centered bool - // BackgroundType is the type of background to use for the window. // Default: BackgroundTypeSolid BackgroundType BackgroundType @@ -82,6 +86,9 @@ type WebviewWindowOptions struct { // CSS is the CSS to load in the window. CSS string + // Initial Position + InitialPosition WindowStartPosition + // X is the starting X position of the window. X int diff --git a/v3/pkg/application/webview_window_windows.go b/v3/pkg/application/webview_window_windows.go index 802b52207a2..dd823f3b554 100644 --- a/v3/pkg/application/webview_window_windows.go +++ b/v3/pkg/application/webview_window_windows.go @@ -370,8 +370,10 @@ func (w *windowsWebviewWindow) run() { w.resizeDebouncer = debounce.New(time.Duration(options.Windows.ResizeDebounceMS) * time.Millisecond) } - if options.Centered { + if options.InitialPosition == WindowCentered { w.center() + } else { + w.setPosition(options.X, options.Y) } if options.Frameless { @@ -380,7 +382,7 @@ func (w *windowsWebviewWindow) run() { } if !options.Hidden { - w.show() + w.parent.Show() w.update() } } diff --git a/v3/pkg/events/events.go b/v3/pkg/events/events.go index bfa94d46a27..3191aa975e2 100644 --- a/v3/pkg/events/events.go +++ b/v3/pkg/events/events.go @@ -6,56 +6,58 @@ type WindowEventType uint var Common = newCommonEvents() type commonEvents struct { - ApplicationStarted ApplicationEventType - WindowMaximise WindowEventType - WindowUnMaximise WindowEventType - WindowFullscreen WindowEventType - WindowUnFullscreen WindowEventType - WindowRestore WindowEventType - WindowMinimise WindowEventType - WindowUnMinimise WindowEventType - WindowClosing WindowEventType - WindowZoom WindowEventType - WindowZoomIn WindowEventType - WindowZoomOut WindowEventType - WindowZoomReset WindowEventType - WindowFocus WindowEventType - WindowLostFocus WindowEventType - WindowShow WindowEventType - WindowHide WindowEventType - WindowDPIChanged WindowEventType - WindowFilesDropped WindowEventType - WindowRuntimeReady WindowEventType - ThemeChanged ApplicationEventType - WindowDidMove WindowEventType - WindowDidResize WindowEventType + ApplicationStarted ApplicationEventType + WindowMaximise WindowEventType + WindowUnMaximise WindowEventType + WindowFullscreen WindowEventType + WindowUnFullscreen WindowEventType + WindowRestore WindowEventType + WindowMinimise WindowEventType + WindowUnMinimise WindowEventType + WindowClosing WindowEventType + WindowZoom WindowEventType + WindowZoomIn WindowEventType + WindowZoomOut WindowEventType + WindowZoomReset WindowEventType + WindowFocus WindowEventType + WindowLostFocus WindowEventType + WindowShow WindowEventType + WindowHide WindowEventType + WindowDPIChanged WindowEventType + WindowFilesDropped WindowEventType + WindowRuntimeReady WindowEventType + ThemeChanged ApplicationEventType + WindowDidMove WindowEventType + WindowDidResize WindowEventType + ApplicationOpenedWithFile ApplicationEventType } func newCommonEvents() commonEvents { return commonEvents{ - ApplicationStarted: 1183, - WindowMaximise: 1184, - WindowUnMaximise: 1185, - WindowFullscreen: 1186, - WindowUnFullscreen: 1187, - WindowRestore: 1188, - WindowMinimise: 1189, - WindowUnMinimise: 1190, - WindowClosing: 1191, - WindowZoom: 1192, - WindowZoomIn: 1193, - WindowZoomOut: 1194, - WindowZoomReset: 1195, - WindowFocus: 1196, - WindowLostFocus: 1197, - WindowShow: 1198, - WindowHide: 1199, - WindowDPIChanged: 1200, - WindowFilesDropped: 1201, - WindowRuntimeReady: 1202, - ThemeChanged: 1203, - WindowDidMove: 1204, - WindowDidResize: 1205, + ApplicationStarted: 1183, + WindowMaximise: 1184, + WindowUnMaximise: 1185, + WindowFullscreen: 1186, + WindowUnFullscreen: 1187, + WindowRestore: 1188, + WindowMinimise: 1189, + WindowUnMinimise: 1190, + WindowClosing: 1191, + WindowZoom: 1192, + WindowZoomIn: 1193, + WindowZoomOut: 1194, + WindowZoomReset: 1195, + WindowFocus: 1196, + WindowLostFocus: 1197, + WindowShow: 1198, + WindowHide: 1199, + WindowDPIChanged: 1200, + WindowFilesDropped: 1201, + WindowRuntimeReady: 1202, + ThemeChanged: 1203, + WindowDidMove: 1204, + WindowDidResize: 1205, + ApplicationOpenedWithFile: 1206, } } @@ -63,24 +65,24 @@ var Linux = newLinuxEvents() type linuxEvents struct { SystemThemeChanged ApplicationEventType - WindowLoadChanged WindowEventType - WindowDeleteEvent WindowEventType - WindowDidMove WindowEventType - WindowDidResize WindowEventType - WindowFocusIn WindowEventType - WindowFocusOut WindowEventType + WindowLoadChanged WindowEventType + WindowDeleteEvent WindowEventType + WindowDidMove WindowEventType + WindowDidResize WindowEventType + WindowFocusIn WindowEventType + WindowFocusOut WindowEventType ApplicationStartup ApplicationEventType } func newLinuxEvents() linuxEvents { return linuxEvents{ SystemThemeChanged: 1024, - WindowLoadChanged: 1025, - WindowDeleteEvent: 1026, - WindowDidMove: 1027, - WindowDidResize: 1028, - WindowFocusIn: 1029, - WindowFocusOut: 1030, + WindowLoadChanged: 1025, + WindowDeleteEvent: 1026, + WindowDidMove: 1027, + WindowDidResize: 1028, + WindowFocusIn: 1029, + WindowFocusOut: 1030, ApplicationStartup: 1031, } } @@ -216,130 +218,130 @@ type macEvents struct { func newMacEvents() macEvents { return macEvents{ - ApplicationDidBecomeActive: 1032, - ApplicationDidChangeBackingProperties: 1033, - ApplicationDidChangeEffectiveAppearance: 1034, - ApplicationDidChangeIcon: 1035, - ApplicationDidChangeOcclusionState: 1036, - ApplicationDidChangeScreenParameters: 1037, - ApplicationDidChangeStatusBarFrame: 1038, + ApplicationDidBecomeActive: 1032, + ApplicationDidChangeBackingProperties: 1033, + ApplicationDidChangeEffectiveAppearance: 1034, + ApplicationDidChangeIcon: 1035, + ApplicationDidChangeOcclusionState: 1036, + ApplicationDidChangeScreenParameters: 1037, + ApplicationDidChangeStatusBarFrame: 1038, ApplicationDidChangeStatusBarOrientation: 1039, - ApplicationDidFinishLaunching: 1040, - ApplicationDidHide: 1041, - ApplicationDidResignActiveNotification: 1042, - ApplicationDidUnhide: 1043, - ApplicationDidUpdate: 1044, - ApplicationWillBecomeActive: 1045, - ApplicationWillFinishLaunching: 1046, - ApplicationWillHide: 1047, - ApplicationWillResignActive: 1048, - ApplicationWillTerminate: 1049, - ApplicationWillUnhide: 1050, - ApplicationWillUpdate: 1051, - ApplicationDidChangeTheme: 1052, - ApplicationShouldHandleReopen: 1053, - WindowDidBecomeKey: 1054, - WindowDidBecomeMain: 1055, - WindowDidBeginSheet: 1056, - WindowDidChangeAlpha: 1057, - WindowDidChangeBackingLocation: 1058, - WindowDidChangeBackingProperties: 1059, - WindowDidChangeCollectionBehavior: 1060, - WindowDidChangeEffectiveAppearance: 1061, - WindowDidChangeOcclusionState: 1062, - WindowDidChangeOrderingMode: 1063, - WindowDidChangeScreen: 1064, - WindowDidChangeScreenParameters: 1065, - WindowDidChangeScreenProfile: 1066, - WindowDidChangeScreenSpace: 1067, - WindowDidChangeScreenSpaceProperties: 1068, - WindowDidChangeSharingType: 1069, - WindowDidChangeSpace: 1070, - WindowDidChangeSpaceOrderingMode: 1071, - WindowDidChangeTitle: 1072, - WindowDidChangeToolbar: 1073, - WindowDidChangeVisibility: 1074, - WindowDidDeminiaturize: 1075, - WindowDidEndSheet: 1076, - WindowDidEnterFullScreen: 1077, - WindowDidEnterVersionBrowser: 1078, - WindowDidExitFullScreen: 1079, - WindowDidExitVersionBrowser: 1080, - WindowDidExpose: 1081, - WindowDidFocus: 1082, - WindowDidMiniaturize: 1083, - WindowDidMove: 1084, - WindowDidOrderOffScreen: 1085, - WindowDidOrderOnScreen: 1086, - WindowDidResignKey: 1087, - WindowDidResignMain: 1088, - WindowDidResize: 1089, - WindowDidUpdate: 1090, - WindowDidUpdateAlpha: 1091, - WindowDidUpdateCollectionBehavior: 1092, - WindowDidUpdateCollectionProperties: 1093, - WindowDidUpdateShadow: 1094, - WindowDidUpdateTitle: 1095, - WindowDidUpdateToolbar: 1096, - WindowDidUpdateVisibility: 1097, - WindowShouldClose: 1098, - WindowWillBecomeKey: 1099, - WindowWillBecomeMain: 1100, - WindowWillBeginSheet: 1101, - WindowWillChangeOrderingMode: 1102, - WindowWillClose: 1103, - WindowWillDeminiaturize: 1104, - WindowWillEnterFullScreen: 1105, - WindowWillEnterVersionBrowser: 1106, - WindowWillExitFullScreen: 1107, - WindowWillExitVersionBrowser: 1108, - WindowWillFocus: 1109, - WindowWillMiniaturize: 1110, - WindowWillMove: 1111, - WindowWillOrderOffScreen: 1112, - WindowWillOrderOnScreen: 1113, - WindowWillResignMain: 1114, - WindowWillResize: 1115, - WindowWillUnfocus: 1116, - WindowWillUpdate: 1117, - WindowWillUpdateAlpha: 1118, - WindowWillUpdateCollectionBehavior: 1119, - WindowWillUpdateCollectionProperties: 1120, - WindowWillUpdateShadow: 1121, - WindowWillUpdateTitle: 1122, - WindowWillUpdateToolbar: 1123, - WindowWillUpdateVisibility: 1124, - WindowWillUseStandardFrame: 1125, - MenuWillOpen: 1126, - MenuDidOpen: 1127, - MenuDidClose: 1128, - MenuWillSendAction: 1129, - MenuDidSendAction: 1130, - MenuWillHighlightItem: 1131, - MenuDidHighlightItem: 1132, - MenuWillDisplayItem: 1133, - MenuDidDisplayItem: 1134, - MenuWillAddItem: 1135, - MenuDidAddItem: 1136, - MenuWillRemoveItem: 1137, - MenuDidRemoveItem: 1138, - MenuWillBeginTracking: 1139, - MenuDidBeginTracking: 1140, - MenuWillEndTracking: 1141, - MenuDidEndTracking: 1142, - MenuWillUpdate: 1143, - MenuDidUpdate: 1144, - MenuWillPopUp: 1145, - MenuDidPopUp: 1146, - MenuWillSendActionToItem: 1147, - MenuDidSendActionToItem: 1148, - WebViewDidStartProvisionalNavigation: 1149, + ApplicationDidFinishLaunching: 1040, + ApplicationDidHide: 1041, + ApplicationDidResignActiveNotification: 1042, + ApplicationDidUnhide: 1043, + ApplicationDidUpdate: 1044, + ApplicationWillBecomeActive: 1045, + ApplicationWillFinishLaunching: 1046, + ApplicationWillHide: 1047, + ApplicationWillResignActive: 1048, + ApplicationWillTerminate: 1049, + ApplicationWillUnhide: 1050, + ApplicationWillUpdate: 1051, + ApplicationDidChangeTheme: 1052, + ApplicationShouldHandleReopen: 1053, + WindowDidBecomeKey: 1054, + WindowDidBecomeMain: 1055, + WindowDidBeginSheet: 1056, + WindowDidChangeAlpha: 1057, + WindowDidChangeBackingLocation: 1058, + WindowDidChangeBackingProperties: 1059, + WindowDidChangeCollectionBehavior: 1060, + WindowDidChangeEffectiveAppearance: 1061, + WindowDidChangeOcclusionState: 1062, + WindowDidChangeOrderingMode: 1063, + WindowDidChangeScreen: 1064, + WindowDidChangeScreenParameters: 1065, + WindowDidChangeScreenProfile: 1066, + WindowDidChangeScreenSpace: 1067, + WindowDidChangeScreenSpaceProperties: 1068, + WindowDidChangeSharingType: 1069, + WindowDidChangeSpace: 1070, + WindowDidChangeSpaceOrderingMode: 1071, + WindowDidChangeTitle: 1072, + WindowDidChangeToolbar: 1073, + WindowDidChangeVisibility: 1074, + WindowDidDeminiaturize: 1075, + WindowDidEndSheet: 1076, + WindowDidEnterFullScreen: 1077, + WindowDidEnterVersionBrowser: 1078, + WindowDidExitFullScreen: 1079, + WindowDidExitVersionBrowser: 1080, + WindowDidExpose: 1081, + WindowDidFocus: 1082, + WindowDidMiniaturize: 1083, + WindowDidMove: 1084, + WindowDidOrderOffScreen: 1085, + WindowDidOrderOnScreen: 1086, + WindowDidResignKey: 1087, + WindowDidResignMain: 1088, + WindowDidResize: 1089, + WindowDidUpdate: 1090, + WindowDidUpdateAlpha: 1091, + WindowDidUpdateCollectionBehavior: 1092, + WindowDidUpdateCollectionProperties: 1093, + WindowDidUpdateShadow: 1094, + WindowDidUpdateTitle: 1095, + WindowDidUpdateToolbar: 1096, + WindowDidUpdateVisibility: 1097, + WindowShouldClose: 1098, + WindowWillBecomeKey: 1099, + WindowWillBecomeMain: 1100, + WindowWillBeginSheet: 1101, + WindowWillChangeOrderingMode: 1102, + WindowWillClose: 1103, + WindowWillDeminiaturize: 1104, + WindowWillEnterFullScreen: 1105, + WindowWillEnterVersionBrowser: 1106, + WindowWillExitFullScreen: 1107, + WindowWillExitVersionBrowser: 1108, + WindowWillFocus: 1109, + WindowWillMiniaturize: 1110, + WindowWillMove: 1111, + WindowWillOrderOffScreen: 1112, + WindowWillOrderOnScreen: 1113, + WindowWillResignMain: 1114, + WindowWillResize: 1115, + WindowWillUnfocus: 1116, + WindowWillUpdate: 1117, + WindowWillUpdateAlpha: 1118, + WindowWillUpdateCollectionBehavior: 1119, + WindowWillUpdateCollectionProperties: 1120, + WindowWillUpdateShadow: 1121, + WindowWillUpdateTitle: 1122, + WindowWillUpdateToolbar: 1123, + WindowWillUpdateVisibility: 1124, + WindowWillUseStandardFrame: 1125, + MenuWillOpen: 1126, + MenuDidOpen: 1127, + MenuDidClose: 1128, + MenuWillSendAction: 1129, + MenuDidSendAction: 1130, + MenuWillHighlightItem: 1131, + MenuDidHighlightItem: 1132, + MenuWillDisplayItem: 1133, + MenuDidDisplayItem: 1134, + MenuWillAddItem: 1135, + MenuDidAddItem: 1136, + MenuWillRemoveItem: 1137, + MenuDidRemoveItem: 1138, + MenuWillBeginTracking: 1139, + MenuDidBeginTracking: 1140, + MenuWillEndTracking: 1141, + MenuDidEndTracking: 1142, + MenuWillUpdate: 1143, + MenuDidUpdate: 1144, + MenuWillPopUp: 1145, + MenuDidPopUp: 1146, + MenuWillSendActionToItem: 1147, + MenuDidSendActionToItem: 1148, + WebViewDidStartProvisionalNavigation: 1149, WebViewDidReceiveServerRedirectForProvisionalNavigation: 1150, - WebViewDidFinishNavigation: 1151, - WebViewDidCommitNavigation: 1152, - WindowFileDraggingEntered: 1153, - WindowFileDraggingPerformed: 1154, - WindowFileDraggingExited: 1155, + WebViewDidFinishNavigation: 1151, + WebViewDidCommitNavigation: 1152, + WindowFileDraggingEntered: 1153, + WindowFileDraggingPerformed: 1154, + WindowFileDraggingExited: 1155, } } @@ -354,56 +356,56 @@ type windowsEvents struct { APMPowerSettingChange ApplicationEventType ApplicationStarted ApplicationEventType WebViewNavigationCompleted WindowEventType - WindowInactive WindowEventType - WindowActive WindowEventType - WindowClickActive WindowEventType - WindowMaximise WindowEventType - WindowUnMaximise WindowEventType - WindowFullscreen WindowEventType - WindowUnFullscreen WindowEventType - WindowRestore WindowEventType - WindowMinimise WindowEventType - WindowUnMinimise WindowEventType - WindowClose WindowEventType - WindowSetFocus WindowEventType - WindowKillFocus WindowEventType - WindowDragDrop WindowEventType - WindowDragEnter WindowEventType - WindowDragLeave WindowEventType - WindowDragOver WindowEventType - WindowDidMove WindowEventType - WindowDidResize WindowEventType + WindowInactive WindowEventType + WindowActive WindowEventType + WindowClickActive WindowEventType + WindowMaximise WindowEventType + WindowUnMaximise WindowEventType + WindowFullscreen WindowEventType + WindowUnFullscreen WindowEventType + WindowRestore WindowEventType + WindowMinimise WindowEventType + WindowUnMinimise WindowEventType + WindowClose WindowEventType + WindowSetFocus WindowEventType + WindowKillFocus WindowEventType + WindowDragDrop WindowEventType + WindowDragEnter WindowEventType + WindowDragLeave WindowEventType + WindowDragOver WindowEventType + WindowDidMove WindowEventType + WindowDidResize WindowEventType } func newWindowsEvents() windowsEvents { return windowsEvents{ - SystemThemeChanged: 1156, - APMPowerStatusChange: 1157, - APMSuspend: 1158, - APMResumeAutomatic: 1159, - APMResumeSuspend: 1160, - APMPowerSettingChange: 1161, - ApplicationStarted: 1162, + SystemThemeChanged: 1156, + APMPowerStatusChange: 1157, + APMSuspend: 1158, + APMResumeAutomatic: 1159, + APMResumeSuspend: 1160, + APMPowerSettingChange: 1161, + ApplicationStarted: 1162, WebViewNavigationCompleted: 1163, - WindowInactive: 1164, - WindowActive: 1165, - WindowClickActive: 1166, - WindowMaximise: 1167, - WindowUnMaximise: 1168, - WindowFullscreen: 1169, - WindowUnFullscreen: 1170, - WindowRestore: 1171, - WindowMinimise: 1172, - WindowUnMinimise: 1173, - WindowClose: 1174, - WindowSetFocus: 1175, - WindowKillFocus: 1176, - WindowDragDrop: 1177, - WindowDragEnter: 1178, - WindowDragLeave: 1179, - WindowDragOver: 1180, - WindowDidMove: 1181, - WindowDidResize: 1182, + WindowInactive: 1164, + WindowActive: 1165, + WindowClickActive: 1166, + WindowMaximise: 1167, + WindowUnMaximise: 1168, + WindowFullscreen: 1169, + WindowUnFullscreen: 1170, + WindowRestore: 1171, + WindowMinimise: 1172, + WindowUnMinimise: 1173, + WindowClose: 1174, + WindowSetFocus: 1175, + WindowKillFocus: 1176, + WindowDragDrop: 1177, + WindowDragEnter: 1178, + WindowDragLeave: 1179, + WindowDragOver: 1180, + WindowDidMove: 1181, + WindowDidResize: 1182, } } @@ -594,4 +596,5 @@ var eventToJS = map[uint]string{ 1203: "common:ThemeChanged", 1204: "common:WindowDidMove", 1205: "common:WindowDidResize", + 1206: "common:ApplicationOpenedWithFile", } diff --git a/v3/pkg/events/events.txt b/v3/pkg/events/events.txt index 5a677b214c3..e4e82ee1405 100644 --- a/v3/pkg/events/events.txt +++ b/v3/pkg/events/events.txt @@ -180,3 +180,4 @@ common:WindowRuntimeReady common:ThemeChanged common:WindowDidMove common:WindowDidResize +common:ApplicationOpenedWithFile diff --git a/v3/tasks/events/generate.go b/v3/tasks/events/generate.go index 4772a1ef8d9..5fa06f32415 100644 --- a/v3/tasks/events/generate.go +++ b/v3/tasks/events/generate.go @@ -2,6 +2,9 @@ package main import ( "bytes" + "github.com/Masterminds/semver/v3" + "github.com/tidwall/gjson" + "github.com/tidwall/sjson" "os" "strconv" "strings" @@ -396,4 +399,35 @@ func main() { panic(err) } + // Load the runtime package.json + packageJsonFilename := "../../internal/runtime/desktop/@wailsio/runtime/package.json" + packageJSON, err := os.ReadFile(packageJsonFilename) + if err != nil { + panic(err) + } + version := gjson.Get(string(packageJSON), "version").String() + // Parse and increment version + v := semver.MustParse(version) + prerelease := v.Prerelease() + // Split the prerelease by the "." and increment the last part by 1 + parts := strings.Split(prerelease, ".") + prereleaseDigits, err := strconv.Atoi(parts[len(parts)-1]) + if err != nil { + panic(err) + } + prereleaseNumber := strconv.Itoa(prereleaseDigits + 1) + parts[len(parts)-1] = prereleaseNumber + prerelease = strings.Join(parts, ".") + newVersion, err := v.SetPrerelease(prerelease) + if err != nil { + panic(err) + } + + // Set new version using sjson + newJSON, err := sjson.Set(string(packageJSON), "version", newVersion.String()) + if err != nil { + panic(err) + } + + err = os.WriteFile(packageJsonFilename, []byte(newJSON), 0644) } diff --git a/v3/tasks/events/go.mod b/v3/tasks/events/go.mod new file mode 100644 index 00000000000..8b0f46531ff --- /dev/null +++ b/v3/tasks/events/go.mod @@ -0,0 +1,14 @@ +module events + +go 1.22 + +require ( + github.com/Masterminds/semver/v3 v3.3.0 + github.com/tidwall/gjson v1.18.0 + github.com/tidwall/sjson v1.2.5 +) + +require ( + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect +)