From 19932bf3ad04625e657102ae4988ea5abd51db05 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 3 Jun 2023 07:52:41 +1000 Subject: [PATCH 01/36] Bump @antfu/utils and unconfig in /scripts/sponsors (#2696) Bumps [@antfu/utils](https://github.com/antfu/utils) and [unconfig](https://github.com/antfu/unconfig). These dependencies needed to be updated together. Updates `@antfu/utils` from 0.5.2 to 0.7.4 - [Release notes](https://github.com/antfu/utils/releases) - [Commits](https://github.com/antfu/utils/compare/v0.5.2...v0.7.4) Updates `unconfig` from 0.3.7 to 0.3.9 - [Release notes](https://github.com/antfu/unconfig/releases) - [Commits](https://github.com/antfu/unconfig/compare/v0.3.7...v0.3.9) --- updated-dependencies: - dependency-name: "@antfu/utils" dependency-type: indirect - dependency-name: unconfig dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- scripts/sponsors/package-lock.json | 36 +++++++++++++++++------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/scripts/sponsors/package-lock.json b/scripts/sponsors/package-lock.json index 30997a31..cb6cc8b9 100644 --- a/scripts/sponsors/package-lock.json +++ b/scripts/sponsors/package-lock.json @@ -13,9 +13,12 @@ } }, "node_modules/@antfu/utils": { - "version": "0.5.2", - "resolved": "https://registry.npmmirror.com/@antfu/utils/-/utils-0.5.2.tgz", - "integrity": "sha512-CQkeV+oJxUazwjlHD0/3ZD08QWKuGQkhnrKo3e6ly5pd48VUpXbb77q0xMU4+vc2CkJnDS02Eq/M9ugyX20XZA==" + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.4.tgz", + "integrity": "sha512-qe8Nmh9rYI/HIspLSTwtbMFPj6dISG6+dJnOguTlPNXtCvS2uezdxscVBb7/3DrmNbQK49TDqpkSQ1chbRGdpQ==", + "funding": { + "url": "https://github.com/sponsors/antfu" + } }, "node_modules/ajv": { "version": "6.12.6", @@ -419,9 +422,9 @@ } }, "node_modules/defu": { - "version": "6.1.1", - "resolved": "https://registry.npmmirror.com/defu/-/defu-6.1.1.tgz", - "integrity": "sha512-aA964RUCsBt0FGoNIlA3uFgo2hO+WWC0fiC6DBps/0SFzkKcYoM/3CzVLIa5xSsrFjdioMdYgAIbwo80qp2MoA==" + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.2.tgz", + "integrity": "sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==" }, "node_modules/delayed-stream": { "version": "1.0.0", @@ -951,9 +954,9 @@ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, "node_modules/jiti": { - "version": "1.16.0", - "resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.16.0.tgz", - "integrity": "sha512-L3BJStEf5NAqNuzrpfbN71dp43mYIcBUlCRea/vdyv5dW/AYa1d4bpelko4SHdY3I6eN9Wzyasxirj1/vv5kmg==", + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz", + "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==", "bin": { "jiti": "bin/jiti.js" } @@ -1765,13 +1768,16 @@ "integrity": "sha512-fk6CmUgwKCfX79EzcDQQpSCMxrHstvbLswFChHS0Vump+kFkw7nJBfTZoC1j0bOGoY9I7R3n2DGek5ajbcYnOw==" }, "node_modules/unconfig": { - "version": "0.3.7", - "resolved": "https://registry.npmmirror.com/unconfig/-/unconfig-0.3.7.tgz", - "integrity": "sha512-1589b7oGa8ILBYpta7TndM5mLHLzHUqBfhszeZxuUBrjO/RoQ52VGVWsS3w0C0GLNxO9RPmqkf6BmIvBApaRdA==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-0.3.9.tgz", + "integrity": "sha512-8yhetFd48M641mxrkWA+C/lZU4N0rCOdlo3dFsyFPnBHBjMJfjT/3eAZBRT2RxCRqeBMAKBVgikejdS6yeBjMw==", "dependencies": { - "@antfu/utils": "^0.5.2", - "defu": "^6.1.0", - "jiti": "^1.16.0" + "@antfu/utils": "^0.7.2", + "defu": "^6.1.2", + "jiti": "^1.18.2" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" } }, "node_modules/undici": { From 644dc653a99c958dfbb36483b1a37efcfdb95461 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 3 Jun 2023 17:18:59 +1000 Subject: [PATCH 02/36] chore: update sponsors.svg (#2698) Co-authored-by: leaanthony --- website/static/img/sponsors.svg | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/website/static/img/sponsors.svg b/website/static/img/sponsors.svg index 38e8760b..d4d16761 100644 --- a/website/static/img/sponsors.svg +++ b/website/static/img/sponsors.svg @@ -63,47 +63,43 @@ text { Buying Coffee - + - + - + - + - + - + - + - + - - - - - + - + Helpers From 4814e65da2a3583643fa8c253e70aaa12dbd0e5d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 3 Jun 2023 17:20:10 +1000 Subject: [PATCH 03/36] docs: sync translations (#2685) Co-authored-by: leaanthony --- .../current/reference/cli.mdx | 66 ++++++++++--------- .../changelog.mdx | 10 ++- .../current/guides/troubleshooting.mdx | 6 +- .../current/reference/cli.mdx | 66 ++++++++++--------- .../version-v2.5.0.json | 16 ++--- .../changelog.mdx | 10 ++- .../current/reference/cli.mdx | 56 ++++++++-------- .../changelog.mdx | 10 ++- .../current/reference/cli.mdx | 64 +++++++++--------- .../changelog.mdx | 10 ++- .../current/reference/cli.mdx | 56 ++++++++-------- .../changelog.mdx | 10 ++- .../current/reference/cli.mdx | 62 +++++++++-------- .../changelog.mdx | 14 +++- 14 files changed, 264 insertions(+), 192 deletions(-) diff --git a/website/i18n/fr/docusaurus-plugin-content-docs/current/reference/cli.mdx b/website/i18n/fr/docusaurus-plugin-content-docs/current/reference/cli.mdx index 9e5a18fc..ab4cb553 100644 --- a/website/i18n/fr/docusaurus-plugin-content-docs/current/reference/cli.mdx +++ b/website/i18n/fr/docusaurus-plugin-content-docs/current/reference/cli.mdx @@ -51,27 +51,32 @@ Si vous n'êtes pas sûr d'un modèle, inspectez les fichiers `package.json` et | Option | Description | Par défaut | |:-------------------- |:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| -platform | Construit pour les [plates-formes](../reference/cli.mdx#platforms) données (séparées par des virgules) par exemple. `windows/arm64`. Notez que si vous ne donnez pas l'architecture, `runtime.GOARCH` est utilisé. | platform = le contenu de la variable d'environnement `GOOS` si elle existe, autrement `runtime.GOOS`.
arch = le contenu de la variable d'environnement `GOARCH` si elle existe, autrement `runtime.GOARCH`. | | -clean | Nettoie le répertoire `build/bin` | | | -compiler "compiler" | Utiliser un autre compilateur pour compiler, par exemple go1.15beta1 | go | +| -debug | Conserve les informations de débogage dans l'application. Permet l'utilisation des outils de développement dans la fenêtre de l'application | | +| -dryrun | Prints the build command without executing it | | +| -f | Forcer la compilation de l'application | | +| -garbleargs | Arguments à passer à garble | `-literals -tiny -seed=random` | | -ldflags "flags" | Options supplémentaires à passer au compilateur | | +| -m | Skip mod tidy before compile | | | -nopackage | Ne pas empaqueter l'application | | +| -nocolour | Disable colour in output | | +| -nosyncgomod | Ne pas synchroniser go.mod avec la version Wails | | +| -nsis | Generate NSIS installer for Windows | | | -o filename | Nom du fichier de sortie | | -| -s | Ignorer la construction du frontend | false | -| -f | Forcer la compilation de l'application | false | +| -obfuscated | Cacher le code de l'application en utilisant [garble](https://github.com/burrowers/garble) | | +| -platform | Construit pour les [plates-formes](../reference/cli.mdx#platforms) données (séparées par des virgules) par exemple. `windows/arm64`. Notez que si vous ne donnez pas l'architecture, `runtime.GOARCH` est utilisé. | platform = le contenu de la variable d'environnement `GOOS` si elle existe, autrement `runtime.GOOS`.
arch = le contenu de la variable d'environnement `GOARCH` si elle existe, autrement `runtime.GOARCH`. | +| -race | Construire avec le détecteur Go race | | +| -s | Ignorer la construction du frontend | | +| -skipbindings | Skip bindings generation | | | -tags "extra tags" | Options de compilation à passer au compilateur Go. Doivent être entre guillemets. Séparés par un espace ou une virgule (pas les deux) | | +| -trimpath | Supprimer tous les chemins vers les fichiers système de l'exécutable final. | | +| -u | Met à jour le `go.mod de votre projet` pour utiliser la même version de Wails que le CLI | | | -upx | Compresser le binaire final en utilisant "upx" | | | -upxflags | Options à passer à upx | | | -v int | Niveau de verbosité (0 - silencieux, 1 - par défaut, 2 - verbeux) | 1 | | -webview2 | Stratégie d'installation WebView2 : download,embed,browser,error | download | -| -u | Met à jour le `go.mod de votre projet` pour utiliser la même version de Wails que le CLI | | -| -debug | Conserve les informations de débogage dans l'application. Permet l'utilisation des outils de développement dans la fenêtre de l'application | false | -| -trimpath | Supprimer tous les chemins vers les fichiers système de l'exécutable final. | false | -| -race | Construire avec le détecteur Go race | false | | -windowsconsole | Garder la fenêtre de la console lors de la construction d'une version pour Windows | | -| -obfuscate | Cacher le code de l'application en utilisant [garble](https://github.com/burrowers/garble) | false | -| -garbleargs | Arguments à passer à garble | `-literals -tiny -seed=random` | -| -nosyncgomod | Ne pas synchroniser go.mod avec la version Wails | false | Pour une description détaillée des options `webview2` , veuillez vous référer au Guide de [Windows](../guides/windows.mdx). @@ -159,37 +164,36 @@ Your system is ready for Wails development! - Un observateur est démarré et déclenchera une reconstruction de votre application de développement s'il détecte des changements dans vos fichiers go - Un serveur web est lancé sur `http://localhost:34115` qui sert votre application (et pas seulement le frontend) sur http. Cela vous permet d'utiliser les extensions de développement de votre navigateur favori - Tous les assets de l'application sont chargés à partir du disque. Si elles sont modifiées, l'application se rechargera automatiquement (pas de recompilation). Tous les navigateurs connectés rechargeront également -- Un module JS est généré qui fournit les éléments suivants : - - Les méthodes Javascript permettant d'appeler vos méthodes Go avec JSDoc autogénérée, vous fournissant des indications sur les méthodes - - Les versions TypeScript de vos structures Go, qui peuvent être construites et transmises à vos méthodes go -- Un second module JS est généré qui fournit une déclaration des méthodes et structures pour l'exécutable -- Sur macOS, il regroupera l'application dans un fichier `.app` et l'exécutera. Il utilisera un `build/darwin/Info.dev.plist` pour le développement. +- A JS module is generated that provides the following: + - JavaScript wrappers of your Go methods with autogenerated JSDoc, providing code hinting + - TypeScript versions of your Go structs, that can be constructed and passed to your go methods +- A second JS module is generated that provides a wrapper + TS declaration for the runtime +- On macOS, it will bundle the application into a `.app` file and run it. It will use a `build/darwin/Info.dev.plist` for development. | Option | Description | Par défaut | |:------------------------------------ |:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |:------------------------ | +| -appargs "args" | Arguments passés à l'application en style shell | | | -assetdir "./chemin/vers/les/assets" | Sert les assets depuis le répertoire donné au lieu d'utiliser le fichier FS fourni | Valeur dans `wails.json` | | -browser | Ouvre un navigateur à `http://localhost:34115` au démarrage | | | -compiler "compiler" | Utiliser un autre compilateur pour compiler, par exemple go1.15beta1 | go | -| -e | Extensions pour déclencher les rebuilds (séparés par des virgules) | go | -| -reloaddirs | Répertoires supplémentaires pour déclencher les recharges (séparés par des virgules) | Valeur dans `wails.json` | -| -ldflags "flags" | Options supplémentaires à passer au compilateur | | -| -tags "extra tags" | Options de construction à passer au compilateur (séparées par des guillemets et des espaces) | | -| -loglevel "loglevel" | Niveau de log à utiliser - Trace, Debug, Info, Warning, Error | Debug | -| -noreload | Désactiver le rechargement automatique lorsque les actifs changent | | -| -nocolour | Désactiver la couleur dans le terminal | false | -| -nogen | Désactiver la génération du module | | -| -v | Niveau de verbosité (0 - silencieux, 1 - par défaut, 2 - verbeux) | 1 | -| -wailsjsdir | Le répertoire où stocker les modules JS Wails générés | Valeur dans `wails.json` | | -debounce | Le temps d'attente pour le rechargement après qu'une modification d'actif est détectée | 100 (millisecondes) | | -devserver "host:port" | L'adresse à laquelle lier le serveur de développement wails | "localhost:34115" | +| -extensions | Extensions pour déclencher les rebuilds (séparés par des virgules) | go | +| -forcebuild | Force build of application | | | -frontenddevserverurl "url" | Utiliser l'url du serveur de développement tiers pour servir les actifs, EG Vite | "" | -| -appargs "args" | Arguments passés à l'application en style shell | | -| -save | Sauvegarde les options `assetdir`, `reloaddirs`, `wailsjsdir`, `debounce`, `devserver` and `frontenddevserverurl` dans `wails.json` pour quelles deviennent les informations par défaut pour les prochaines utilisations. | | -| -race | Construire avec le détecteur Go race | false | -| -s | Ignorer la construction du frontend | false | +| -ldflags "flags" | Options supplémentaires à passer au compilateur | | +| -loglevel "loglevel" | Niveau de log à utiliser - Trace, Debug, Info, Warning, Error | Debug | +| -nocolour | Désactiver la couleur dans le terminal | false | +| -noreload | Désactiver le rechargement automatique lorsque les actifs changent | | | -nosyncgomod | Ne pas synchroniser go.mod avec la version Wails | false | - - +| -race | Construire avec le détecteur Go race | false | +| -reloaddirs | Répertoires supplémentaires pour déclencher les recharges (séparés par des virgules) | Valeur dans `wails.json` | +| -s | Ignorer la construction du frontend | false | +| -save | Sauvegarde les options `assetdir`, `reloaddirs`, `wailsjsdir`, `debounce`, `devserver` and `frontenddevserverurl` dans `wails.json` pour quelles deviennent les informations par défaut pour les prochaines utilisations. | | +| -skipbindings | Skip bindings generation | | +| -tags "extra tags" | Options de construction à passer au compilateur (séparées par des guillemets et des espaces) | | +| -v | Niveau de verbosité (0 - silencieux, 1 - par défaut, 2 - verbeux) | 1 | +| -wailsjsdir | Le répertoire où stocker les modules JS Wails générés | Valeur dans `wails.json` | Exemple: diff --git a/website/i18n/fr/docusaurus-plugin-content-pages/changelog.mdx b/website/i18n/fr/docusaurus-plugin-content-pages/changelog.mdx index c635063f..e2073d6f 100644 --- a/website/i18n/fr/docusaurus-plugin-content-pages/changelog.mdx +++ b/website/i18n/fr/docusaurus-plugin-content-pages/changelog.mdx @@ -13,7 +13,15 @@ Le format est basé sur [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) ## [Unreleased] -## [v2.5.1] - 2023-05-16 +### Corrections + +- Avoid app crashing when the Linux GTK key is empty by @aminya in [PR](https://github.com/wailsapp/wails/pull/2672) + +### Changements + +- Changed styling of `doctor` command. Changed by @MarvinJWendt in [PR](https://github.com/wailsapp/wails/pull/2660) + +## v2.5.1 - 2023-05-16 ### Modifications importantes diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/guides/troubleshooting.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/guides/troubleshooting.mdx index 235f8cb5..458e636f 100644 --- a/website/i18n/ja/docusaurus-plugin-content-docs/current/guides/troubleshooting.mdx +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/guides/troubleshooting.mdx @@ -47,11 +47,11 @@ var assets embed.FS アプリケーションの`info.plist`が無効である可能性があります。 `build/.app/Contents/info.plist`ファイルを更新し、データが有効かどうかを確認します。たとえば、バイナリ名が正しいかどうかを確認してください。 変更を反映するには、ファイルを`build/darwin`ディレクトリにコピーします。 -## My application is not displaying the correct icon in Windows Explorer +## Windowsのエクスプローラにアプリケーションアイコンが正しく表示されません -If your application is not displaying the correct icon, try deleting the hidden `IconCache.db` file located in the `C:\Users\<your username>\AppData\Local` directory. This will force Windows to rebuild the icon cache. +アプリケーションアイコンが正しく表示されない場合は、`C:\Users\<あなたのユーザ名>\AppData\Local`ディレクトリ内にある、`IconCache.db`という隠しファイルを削除してみてください。 これにより、Windowsのアイコンキャッシュが強制的に再作成されます。 -Source: https://github.com/wailsapp/wails/issues/2360#issuecomment-1556070036 +出典: https://github.com/wailsapp/wails/issues/2360#issuecomment-1556070036 ## 可変長引数を持つバックエンドメソッドをフロントエンドから呼び出せません diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/current/reference/cli.mdx b/website/i18n/ja/docusaurus-plugin-content-docs/current/reference/cli.mdx index 9c7a29fd..5c3f7728 100644 --- a/website/i18n/ja/docusaurus-plugin-content-docs/current/reference/cli.mdx +++ b/website/i18n/ja/docusaurus-plugin-content-docs/current/reference/cli.mdx @@ -51,27 +51,32 @@ WailsではGitHubでホストされているリモートテンプレートをサ | フラグ | 説明 | デフォルト | |:-------------------- |:-------------------------------------------------------------------------------------------------------------------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------- | -| -platform | 指定された[プラットフォーム](../reference/cli.mdx#platforms)(カンマ区切り) 向けにビルドする。例: `windows/arm64`。 アーキテクチャを指定しない場合は、`runtime.GOARCH`の値が使用されます。 | platform = `GOOS` environment variable if given else `runtime.GOOS`.
arch = `GOARCH` envrionment variable if given else `runtime.GOARCH`. | | -clean | `build/bin`ディレクトリをクリーンする | | | -compiler "compiler" | 違うGoコンパイラを使用する。例: go1.15beta1 | go | +| -debug | アプリケーションのデバッグ情報を保持する。 これにより、アプリケーションウィンドウで開発者ツールを使用することを許可できます。 | | +| -dryrun | 実際には実行せずにbuildコマンドの結果を表示する | | +| -f | アプリケーションを強制的にビルド | | +| -garbleargs | garbleへ渡す引数 | `-literals -tiny -seed=random` | | -ldflags "flags" | コンパイラに渡す追加のldflags | | +| -m | コンパイル前のmod tidyの実行をスキップする | | | -nopackage | アプリケーションをパッケージ化しない | | +| -nocolour | 出力文字に色をつけない | | +| -nosyncgomod | go.modとWailsのバージョンを同期させない | | +| -nsis | Windows向けのNSISインストーラを生成する | | | -o filename | 出力ファイル名 | | -| -s | フロントエンドのビルドをスキップ | false | -| -f | アプリケーションを強制的にビルド | false | +| -obfuscated | [garble](https://github.com/burrowers/garble)を使用してアプリケーションを難読化する | | +| -platform | 指定された[プラットフォーム](../reference/cli.mdx#platforms)(カンマ区切り) 向けにビルドする。例: `windows/arm64`。 アーキテクチャを指定しない場合は、`runtime.GOARCH`の値が使用されます。 | platform = `GOOS` environment variable if given else `runtime.GOOS`.
arch = `GOARCH` envrionment variable if given else `runtime.GOARCH`. | +| -race | Goのrace detectorを使用してビルドする | | +| -s | フロントエンドのビルドをスキップ | | +| -skipbindings | バインディングの生成をスキップする | | | -tags "extra tags" | Goコンパイラに渡すビルドタグ。 値は引用符で囲んでください。 また、スペースまたはカンマで区切ってください(両方は使用しないでください)。 | | +| -trimpath | 実行可能ファイルから、すべてのファイルシステムパスを削除する | | +| -u | プロジェクトの`go.mod`を更新し、CLIと同じバージョンのWailsを使用する | | | -upx | "upx"を使用して最終的にバイナリを圧縮する | | | -upxflags | upxに渡すフラグ | | | -v int | 詳細度レベル (0 - サイレント, 1 - デフォルト, 2 - 詳細) | 1 | | -webview2 | WebView2インストーラーのストラテジ: download,embed,browser,error | download | -| -u | プロジェクトの`go.mod`を更新し、CLIと同じバージョンのWailsを使用する | | -| -debug | アプリケーションのデバッグ情報を保持する。 これにより、アプリケーションウィンドウで開発者ツールを使用することを許可できます。 | false | -| -trimpath | 実行可能ファイルから、すべてのファイルシステムパスを削除する | false | -| -race | Goのrace detectorを使用してビルドする | false | | -windowsconsole | Windiws向けビルドでコンソールウィンドウを維持する | | -| -obfuscate | [garble](https://github.com/burrowers/garble)を使用してアプリケーションを難読化する | false | -| -garbleargs | garbleへ渡す引数 | `-literals -tiny -seed=random` | -| -nosyncgomod | go.modとWailsのバージョンを同期させない | false | `webview2`フラグの詳細については、[Windows](../guides/windows.mdx)ガイドをご覧ください。 @@ -159,37 +164,36 @@ Your system is ready for Wails development! - ウォッチャーが起動し、Goファイルの変更を検出した際には、アプリがリビルドされます - `http://localhost:34115`でWebサーバが起動し、HTTP経由でアプリケーション(フロントエンドだけではありません)が提供されます。 これにより、任意のブラウザ拡張機能を使用することができます - すべてのアプリケーションアセットはディスクから読み込まれます。 アセットが変更された場合、アプリケーションは自動的に、リビルドではなくリロードされます。 接続されているすべてのブラウザもリロードされます -- 以下を提供するJSモジュールが生成されます: - - コードヒントを提供してくれるJSDocが自動付与された、GoメソッドのJavaScriptラッパー - - インスタンス生成したりGoメソッドに渡すことのできる、Go構造体のTypeScriptバージョン -- ランタイム用のラッパーおよびTypeScript型定義を含むJSモジュールも生成されます -- MacOSでは、アプリケーションを`.app`ファイルにバンドルして実行されます。 開発向けに、`build/darwin/Info.dev.plist`が使用されます。 +- 以下のものを含むJSモジュールが生成されます: + - GoメソッドのJavaScriptラッパー (コードヒントに有用なJSDocも自動付与されています) + - Goの構造体のTypeScriptバージョン (構造体のインスタンスを生成したり、Goメソッドの引数として渡したりすることができます) +- 別のJSモジュールとして、ランタイムのラッパーおよびTS定義も生成されます +- macOSの場合、アプリケーションは`.app`ファイルにバンドルされて実行されます。 これには、開発用の`build/darwin/Info.dev.plist`を使用します。 | フラグ | 説明 | デフォルト | |:---------------------------- |:----------------------------------------------------------------------------------------------------------------------------- |:--------------------- | +| -appargs "args" | シェル形式でアプリケーションに渡される引数 | | | -assetdir "./path/to/assets" | 通常のアセットFSを使用する代わりに、指定されたディレクトリからアセットを提供する | `wails.json`で指定されている値 | | -browser | 起動時にブラウザで`http://localhost:34115`を開く | | | -compiler "compiler" | 違うGoコンパイラを使用する。例: go1.15beta1 | go | -| -e | リビルドをトリガーする拡張子 (カンマ区切り) | go | -| -reloaddirs | リロードをトリガーする追加ディレクトリ (カンマ区切り) | `wails.json`で指定されている値 | -| -ldflags "flags" | コンパイラに渡す追加のldflags | | -| -tags "extra tags" | コンパイラへ渡すビルドタグ (引用符およびスペース区切り) | | -| -loglevel "loglevel" | 使用するログレベル - Trace, Debug, Info, Warning, Error | Debug | -| -noreload | アセットが変更されたときの自動リロードを無効にする | | -| -nocolour | CLIのカラー出力を無効にする | false | -| -nogen | モジュールの生成を無効にする | | -| -v | 詳細度レベル (0 - サイレント, 1 - デフォルト, 2 - 詳細) | 1 | -| -wailsjsdir | 生成されたWailsのJSモジュールを格納するディレクトリ | `wails.json`で指定されている値 | | -debounce | アセットの変更が検出されたあと、リロードするまでの時間 | 100 (ミリ秒) | | -devserver "host:port" | Wails開発サーバをバインドするアドレス | "localhost:34115" | +| -extensions | リビルドをトリガーする拡張子 (カンマ区切り) | go | +| -forcebuild | アプリケーションを強制的にビルドする | | | -frontenddevserverurl "url" | アセットを提供するサードパーティ製の開発サーバ(例: Vite) を使用する | "" | -| -appargs "args" | シェル形式でアプリケーションに渡される引数 | | -| -save | 指定された`assetdir`、`reloaddirs`、`wailsjsdir`、`debounce`、`devserver`、`frontenddevserverurl`フラグの値を、`wails.json`へ保存し、次回以降のデフォルト値にする | | -| -race | Goのrace detectorを使用してビルドする | false | -| -s | フロントエンドのビルドをスキップ | false | +| -ldflags "flags" | コンパイラに渡す追加のldflags | | +| -loglevel "loglevel" | 使用するログレベル - Trace, Debug, Info, Warning, Error | Debug | +| -nocolour | CLIのカラー出力を無効にする | false | +| -noreload | アセットが変更されたときの自動リロードを無効にする | | | -nosyncgomod | go.modとWailsのバージョンを同期させない | false | - - +| -race | Goのrace detectorを使用してビルドする | false | +| -reloaddirs | リロードをトリガーする追加ディレクトリ (カンマ区切り) | `wails.json`で指定されている値 | +| -s | フロントエンドのビルドをスキップ | false | +| -save | 指定された`assetdir`、`reloaddirs`、`wailsjsdir`、`debounce`、`devserver`、`frontenddevserverurl`フラグの値を、`wails.json`へ保存し、次回以降のデフォルト値にする | | +| -skipbindings | バインディングの生成をスキップする | | +| -tags "extra tags" | コンパイラへ渡すビルドタグ (引用符およびスペース区切り) | | +| -v | 詳細度レベル (0 - サイレント, 1 - デフォルト, 2 - 詳細) | 1 | +| -wailsjsdir | 生成されたWailsのJSモジュールを格納するディレクトリ | `wails.json`で指定されている値 | 例: diff --git a/website/i18n/ja/docusaurus-plugin-content-docs/version-v2.5.0.json b/website/i18n/ja/docusaurus-plugin-content-docs/version-v2.5.0.json index c7fb70c8..f7250a99 100644 --- a/website/i18n/ja/docusaurus-plugin-content-docs/version-v2.5.0.json +++ b/website/i18n/ja/docusaurus-plugin-content-docs/version-v2.5.0.json @@ -4,35 +4,35 @@ "description": "The label for version v2.5.0" }, "sidebar.docs.category.Getting Started": { - "message": "Getting Started", + "message": "はじめよう", "description": "The label for category Getting Started in sidebar docs" }, "sidebar.docs.category.Reference": { - "message": "Reference", + "message": "リファレンス", "description": "The label for category Reference in sidebar docs" }, "sidebar.docs.category.Runtime": { - "message": "Runtime", + "message": "ランタイム", "description": "The label for category Runtime in sidebar docs" }, "sidebar.docs.category.Community": { - "message": "Community", + "message": "コミュニティ", "description": "The label for category Community in sidebar docs" }, "sidebar.docs.category.Showcase": { - "message": "Showcase", + "message": "事例紹介", "description": "The label for category Showcase in sidebar docs" }, "sidebar.docs.category.Guides": { - "message": "Guides", + "message": "ガイド", "description": "The label for category Guides in sidebar docs" }, "sidebar.docs.category.Tutorials": { - "message": "Tutorials", + "message": "チュートリアル", "description": "The label for category Tutorials in sidebar docs" }, "sidebar.docs.link.Contributing": { - "message": "Contributing", + "message": "コントリビューション", "description": "The label for link Contributing in sidebar docs, linking to /community-guide#ways-of-contributing" } } diff --git a/website/i18n/ja/docusaurus-plugin-content-pages/changelog.mdx b/website/i18n/ja/docusaurus-plugin-content-pages/changelog.mdx index 866a230e..e8963ce5 100644 --- a/website/i18n/ja/docusaurus-plugin-content-pages/changelog.mdx +++ b/website/i18n/ja/docusaurus-plugin-content-pages/changelog.mdx @@ -13,7 +13,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] -## [v2.5.1] - 2023-05-16 +### Fixed + +- Avoid app crashing when the Linux GTK key is empty by @aminya in [PR](https://github.com/wailsapp/wails/pull/2672) + +### Changed + +- Changed styling of `doctor` command. Changed by @MarvinJWendt in [PR](https://github.com/wailsapp/wails/pull/2660) + +## v2.5.1 - 2023-05-16 ### Breaking Changes diff --git a/website/i18n/ko/docusaurus-plugin-content-docs/current/reference/cli.mdx b/website/i18n/ko/docusaurus-plugin-content-docs/current/reference/cli.mdx index 71d51b61..10e021f5 100644 --- a/website/i18n/ko/docusaurus-plugin-content-docs/current/reference/cli.mdx +++ b/website/i18n/ko/docusaurus-plugin-content-docs/current/reference/cli.mdx @@ -51,27 +51,32 @@ If you are unsure about a template, inspect `package.json` and `wails.json` for | Flag | Description | Default | |:-------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------- | -| -platform | Build for the given (comma delimited) [platforms](../reference/cli.mdx#platforms) eg. `windows/arm64`. Note, if you do not give the architecture, `runtime.GOARCH` is used. | platform = `GOOS` environment variable if given else `runtime.GOOS`.
arch = `GOARCH` envrionment variable if given else `runtime.GOARCH`. | | -clean | Cleans the `build/bin` directory | | | -compiler "compiler" | Use a different go compiler to build, eg go1.15beta1 | go | +| -debug | Retains debug information in the application. Allows the use of the devtools in the application window | | +| -dryrun | Prints the build command without executing it | | +| -f | Force build application | | +| -garbleargs | Arguments to pass to garble | `-literals -tiny -seed=random` | | -ldflags "flags" | Additional ldflags to pass to the compiler | | +| -m | Skip mod tidy before compile | | | -nopackage | Do not package application | | +| -nocolour | Disable colour in output | | +| -nosyncgomod | Do not sync go.mod with the Wails version | | +| -nsis | Generate NSIS installer for Windows | | | -o filename | Output filename | | -| -s | Skip building the frontend | false | -| -f | Force build application | false | +| -obfuscated | Obfuscate the application using [garble](https://github.com/burrowers/garble) | | +| -platform | Build for the given (comma delimited) [platforms](../reference/cli.mdx#platforms) eg. `windows/arm64`. Note, if you do not give the architecture, `runtime.GOARCH` is used. | platform = `GOOS` environment variable if given else `runtime.GOOS`.
arch = `GOARCH` envrionment variable if given else `runtime.GOARCH`. | +| -race | Build with Go's race detector | | +| -s | Skip building the frontend | | +| -skipbindings | Skip bindings generation | | | -tags "extra tags" | Build tags to pass to Go compiler. Must be quoted. Space or comma (but not both) separated | | +| -trimpath | Remove all file system paths from the resulting executable. | | +| -u | Updates your project's `go.mod` to use the same version of Wails as the CLI | | | -upx | Compress final binary using "upx" | | | -upxflags | Flags to pass to upx | | | -v int | Verbosity level (0 - silent, 1 - default, 2 - verbose) | 1 | | -webview2 | WebView2 installer strategy: download,embed,browser,error | download | -| -u | Updates your project's `go.mod` to use the same version of Wails as the CLI | | -| -debug | Retains debug information in the application. Allows the use of the devtools in the application window | false | -| -trimpath | Remove all file system paths from the resulting executable. | false | -| -race | Build with Go's race detector | false | | -windowsconsole | Keep the console window for Windows builds | | -| -obfuscate | Obfuscate the application using [garble](https://github.com/burrowers/garble) | false | -| -garbleargs | Arguments to pass to garble | `-literals -tiny -seed=random` | -| -nosyncgomod | Do not sync go.mod with the Wails version | false | For a detailed description of the `webview2` flag, please refer to the [Windows](../guides/windows.mdx) Guide. @@ -167,29 +172,28 @@ Your system is ready for Wails development! | Flag | Description | Default | |:---------------------------- |:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |:--------------------- | +| -appargs "args" | Arguments passed to the application in shell style | | | -assetdir "./path/to/assets" | Serve assets from the given directory instead of using the provided asset FS | Value in `wails.json` | | -browser | Opens a browser to `http://localhost:34115` on startup | | | -compiler "compiler" | Use a different go compiler to build, eg go1.15beta1 | go | -| -e | Extensions to trigger rebuilds (comma separated) | go | -| -reloaddirs | Additional directories to trigger reloads (comma separated) | Value in `wails.json` | -| -ldflags "flags" | Additional ldflags to pass to the compiler | | -| -tags "extra tags" | Build tags to pass to compiler (quoted and space separated) | | -| -loglevel "loglevel" | Loglevel to use - Trace, Debug, Info, Warning, Error | Debug | -| -noreload | Disable automatic reload when assets change | | -| -nocolour | Turn off colour cli output | false | -| -nogen | Disable generate module | | -| -v | Verbosity level (0 - silent, 1 - standard, 2 - verbose) | 1 | -| -wailsjsdir | The directory to generate the generated Wails JS modules | Value in `wails.json` | | -debounce | The time to wait for reload after an asset change is detected | 100 (milliseconds) | | -devserver "host:port" | The address to bind the wails dev server to | "localhost:34115" | +| -extensions | Extensions to trigger rebuilds (comma separated) | go | +| -forcebuild | Force build of application | | | -frontenddevserverurl "url" | Use 3rd party dev server url to serve assets, EG Vite | "" | -| -appargs "args" | Arguments passed to the application in shell style | | -| -save | Saves the given `assetdir`, `reloaddirs`, `wailsjsdir`, `debounce`, `devserver` and `frontenddevserverurl` flags in `wails.json` to become the defaults for subsequent invocations. | | -| -race | Build with Go's race detector | false | -| -s | Skip building the frontend | false | +| -ldflags "flags" | Additional ldflags to pass to the compiler | | +| -loglevel "loglevel" | Loglevel to use - Trace, Debug, Info, Warning, Error | Debug | +| -nocolour | Turn off colour cli output | false | +| -noreload | Disable automatic reload when assets change | | | -nosyncgomod | Do not sync go.mod with the Wails version | false | - - +| -race | Build with Go's race detector | false | +| -reloaddirs | Additional directories to trigger reloads (comma separated) | Value in `wails.json` | +| -s | Skip building the frontend | false | +| -save | Saves the given `assetdir`, `reloaddirs`, `wailsjsdir`, `debounce`, `devserver` and `frontenddevserverurl` flags in `wails.json` to become the defaults for subsequent invocations. | | +| -skipbindings | Skip bindings generation | | +| -tags "extra tags" | Build tags to pass to compiler (quoted and space separated) | | +| -v | Verbosity level (0 - silent, 1 - standard, 2 - verbose) | 1 | +| -wailsjsdir | The directory to generate the generated Wails JS modules | Value in `wails.json` | Example: diff --git a/website/i18n/ko/docusaurus-plugin-content-pages/changelog.mdx b/website/i18n/ko/docusaurus-plugin-content-pages/changelog.mdx index a9e70506..0bc23b16 100644 --- a/website/i18n/ko/docusaurus-plugin-content-pages/changelog.mdx +++ b/website/i18n/ko/docusaurus-plugin-content-pages/changelog.mdx @@ -13,7 +13,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] -## [v2.5.1] - 2023-05-16 +### Fixed + +- Avoid app crashing when the Linux GTK key is empty by @aminya in [PR](https://github.com/wailsapp/wails/pull/2672) + +### Changed + +- Changed styling of `doctor` command. Changed by @MarvinJWendt in [PR](https://github.com/wailsapp/wails/pull/2660) + +## v2.5.1 - 2023-05-16 ### Breaking Changes diff --git a/website/i18n/pt/docusaurus-plugin-content-docs/current/reference/cli.mdx b/website/i18n/pt/docusaurus-plugin-content-docs/current/reference/cli.mdx index 7e9fb535..f1fe9aeb 100644 --- a/website/i18n/pt/docusaurus-plugin-content-docs/current/reference/cli.mdx +++ b/website/i18n/pt/docusaurus-plugin-content-docs/current/reference/cli.mdx @@ -51,27 +51,32 @@ If you are unsure about a template, inspect `package.json` and `wails.json` for | Flag | Descrição | Padrão | |:-------------------- |:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |:----------------------------------------------------------------------------------------------------------------------------------------------------- | -| -platform | Compila para as plataformas [(delimitadas por vírgula)](../reference/cli.mdx#platforms) por exemplo. `windows/arm64`. Note, se você não der arquitetura, `runtime.GOARCH` é usado. | platform = `variável de ambiente GOOS` se determinado `runtime.GOOS`.
arch = `GOARCH` variável de envrionment se for dado `runtime.GOARCH`. | | -clean | Limpa o diretório `compilação/bin` | | | -compiler "compiler" | Use um compilador de ida diferente para realizar build, por exemplo, go1.15beta1 | go | +| -debug | Mantém as informações de depuração no aplicativo. Permite o uso das ferramentas devtools na janela do aplicativo | | +| -dryrun | Prints the build command without executing it | | +| -f | Forçar compilação de aplicação | | +| -garbleargs | Argumentos para passar para o garble | `-literals -tiny -seed=random` | | -ldflags "flags" | Ldflags adicionais para passar para o compilador | | +| -m | Skip mod tidy before compile | | | -nopackage | Não empacotar aplicação | | +| -nocolour | Disable colour in output | | +| -nosyncgomod | Do not sync go.mod with the Wails version | | +| -nsis | Generate NSIS installer for Windows | | | -o nome de arquivo | Nome do Arquivo de Saída | | -| -s | Pular build do frontend | false | -| -f | Forçar compilação de aplicação | false | +| -obfuscated | Ofuscar a aplicação usando [garble](https://github.com/burrowers/garble) | | +| -platform | Compila para as plataformas [(delimitadas por vírgula)](../reference/cli.mdx#platforms) por exemplo. `windows/arm64`. Note, se você não der arquitetura, `runtime.GOARCH` é usado. | platform = `variável de ambiente GOOS` se determinado `runtime.GOOS`.
arch = `GOARCH` variável de envrionment se for dado `runtime.GOARCH`. | +| -race | Realiza build com o Go race detector | | +| -s | Pular build do frontend | | +| -skipbindings | Skip bindings generation | | | -tags "extra tags" | Compilar tags para passar para o compilador Go. Deve ser citado. Separados por espaço ou vírgula (mas não ambos) | | +| -trimpath | Remove todos os caminhos do sistema de arquivo do executável resultante. | | +| -u | Atualiza o `go.mod` do seu projeto para usar a mesma versão de Wails que o CLI | | | -upx | Comprimir binário final usando "upx" | | | -upxflags | Flags para passar para o upx | | | -v int | Nível de verbosidade(0 - silencioso, 1 - padrão, 2 - verbose) | 1 | | -webview2 | Estratégia de instalação WebView2: download,embed,browser,error | baixar | -| -u | Atualiza o `go.mod` do seu projeto para usar a mesma versão de Wails que o CLI | | -| -debug | Mantém as informações de depuração no aplicativo. Permite o uso das ferramentas devtools na janela do aplicativo | false | -| -trimpath | Remove todos os caminhos do sistema de arquivo do executável resultante. | false | -| -race | Realiza build com o Go race detector | false | | -windowsconsole | Manter a janela de console para builds do Windows | | -| -obfuscate | Ofuscar a aplicação usando [garble](https://github.com/burrowers/garble) | false | -| -garbleargs | Argumentos para passar para o garble | `-literals -tiny -seed=random` | -| -nosyncgomod | Do not sync go.mod with the Wails version | false | Para uma descrição detalhada do sinalizador `webview2`, consulte o guia [Windows](../guides/windows.mdx). @@ -159,37 +164,36 @@ Your system is ready for Wails development! - Um observador é iniciado e acionará uma reconstrução do seu aplicativo de desenvolvimento se ele detectar alterações em seus arquivos go - Um servidor web foi iniciado em `http://localhost:34115` que serve sua aplicação (não apenas frontend) sobre http. Isso permite que você use suas extensões de desenvolvimento de navegador favoritas - Todos os conteúdos do aplicativo são carregados do disco. Se forem alterados, o aplicativo irá recarregar automaticamente (não reconstruir). Todos os navegadores conectados também recarregarão -- Um módulo JS é gerado que fornece o seguinte: +- A JS module is generated that provides the following: - JavaScript wrappers of your Go methods with autogenerated JSDoc, providing code hinting - - Versões do TypeScript de suas structs Go, que podem ser construídas e passadas para os métodos da sua ida -- Um segundo módulo JS é gerado que fornece uma declaração wrapper + TS para o tempo de execução -- No macOS, ele irá empacotar a aplicação em um arquivo `.app` e executá-lo. Será usado um `build/darwin/Info.dev.plist` para desenvolvimento. + - TypeScript versions of your Go structs, that can be constructed and passed to your go methods +- A second JS module is generated that provides a wrapper + TS declaration for the runtime +- On macOS, it will bundle the application into a `.app` file and run it. It will use a `build/darwin/Info.dev.plist` for development. | Flag | Descrição | Padrão | |:--------------------------------- |:---------------------------------------------------------------------------------------------------------------------------------------------------------------- |:--------------------- | +| -appargs "args" | Argumentos passados para o aplicativo no estilo shell | | | -assetdir "./caminho/para/midias" | Serve os arquivos a partir do diretório fornecido em vez de usar os arquivos FS fornecidos | Valor em `wails.json` | | -browser | Abre um navegador para `http://localhost:34115` na inicialização | | | -compiler "compiler" | Use um compilador de ida diferente para realizar build, por exemplo, go1.15beta1 | go | -| -e | Extensões para acionar reconstruções (separadas por vírgula) | go | -| -reloaddirs | Diretórios adicionais para acionar recarregamentos (separados por vírgula) | Valor em `wails.json` | -| -ldflags "flags" | Ldflags adicionais para passar para o compilador | | -| -tags "extra tags" | Compilar tags para passar para o compilador (citado e espaço separado) | | -| -loglevel "loglevel" | Nível de log a ser usado - Trace, Debug, Info, Warning, Error | Debug | -| -noreload | Desativar a recarga automática quando os arquivos forem alterados | | -| -nocolour | Desativar saída da colorida da cli | false | -| -nogen | Desativar módulo de geração | | -| -v | Nível de verbosidade(0 - silencioso, 1 - padrão, 2 - verbose) | 1 | -| -wailsjsdir | O diretório para gerar os módulos gerados do Wails JS | Valor em `wails.json` | | -debounce | O tempo de esperar por recarregar depois que uma alteração de ativo for detectada | 100 (milliseconds) | | -devserver "host:port" | O endereço para vincular o servidor de desenvolvimento de wails a | "localhost:34115" | +| -extensions | Extensões para acionar reconstruções (separadas por vírgula) | go | +| -forcebuild | Force build of application | | | -frontenddevserverurl "url" | Usar URL do servidor de desenvolvimento de terceiros para servir midias, Vite EG | "" | -| -appargs "args" | Argumentos passados para o aplicativo no estilo shell | | -| -save | Salva o `assetdir`, `reloaddirs`,`wailsjsdir`,`debounce`,`devserver` e `frontenddevserverurl` passado, flag em `wails.json` para realizar chamadas subsequentes. | | -| -race | Realiza build com o Go race detector | false | -| -s | Pular build do frontend | false | +| -ldflags "flags" | Ldflags adicionais para passar para o compilador | | +| -loglevel "loglevel" | Nível de log a ser usado - Trace, Debug, Info, Warning, Error | Debug | +| -nocolour | Desativar saída da colorida da cli | false | +| -noreload | Desativar a recarga automática quando os arquivos forem alterados | | | -nosyncgomod | Do not sync go.mod with the Wails version | false | - - +| -race | Realiza build com o Go race detector | false | +| -reloaddirs | Diretórios adicionais para acionar recarregamentos (separados por vírgula) | Valor em `wails.json` | +| -s | Pular build do frontend | false | +| -save | Salva o `assetdir`, `reloaddirs`,`wailsjsdir`,`debounce`,`devserver` e `frontenddevserverurl` passado, flag em `wails.json` para realizar chamadas subsequentes. | | +| -skipbindings | Skip bindings generation | | +| -tags "extra tags" | Compilar tags para passar para o compilador (citado e espaço separado) | | +| -v | Nível de verbosidade(0 - silencioso, 1 - padrão, 2 - verbose) | 1 | +| -wailsjsdir | O diretório para gerar os módulos gerados do Wails JS | Valor em `wails.json` | Exemplo: diff --git a/website/i18n/pt/docusaurus-plugin-content-pages/changelog.mdx b/website/i18n/pt/docusaurus-plugin-content-pages/changelog.mdx index 03c8f676..c12395f4 100644 --- a/website/i18n/pt/docusaurus-plugin-content-pages/changelog.mdx +++ b/website/i18n/pt/docusaurus-plugin-content-pages/changelog.mdx @@ -13,7 +13,15 @@ O formato é baseado em [Manter um Log de Alterações](https://keepachangelog.c ## [Unreleased] -## [v2.5.1] - 2023-05-16 +### Corrigido + +- Avoid app crashing when the Linux GTK key is empty by @aminya in [PR](https://github.com/wailsapp/wails/pull/2672) + +### Alterado + +- Changed styling of `doctor` command. Changed by @MarvinJWendt in [PR](https://github.com/wailsapp/wails/pull/2660) + +## v2.5.1 - 2023-05-16 ### Grandes Alterações diff --git a/website/i18n/ru/docusaurus-plugin-content-docs/current/reference/cli.mdx b/website/i18n/ru/docusaurus-plugin-content-docs/current/reference/cli.mdx index 71d51b61..10e021f5 100644 --- a/website/i18n/ru/docusaurus-plugin-content-docs/current/reference/cli.mdx +++ b/website/i18n/ru/docusaurus-plugin-content-docs/current/reference/cli.mdx @@ -51,27 +51,32 @@ If you are unsure about a template, inspect `package.json` and `wails.json` for | Flag | Description | Default | |:-------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |:--------------------------------------------------------------------------------------------------------------------------------------------------- | -| -platform | Build for the given (comma delimited) [platforms](../reference/cli.mdx#platforms) eg. `windows/arm64`. Note, if you do not give the architecture, `runtime.GOARCH` is used. | platform = `GOOS` environment variable if given else `runtime.GOOS`.
arch = `GOARCH` envrionment variable if given else `runtime.GOARCH`. | | -clean | Cleans the `build/bin` directory | | | -compiler "compiler" | Use a different go compiler to build, eg go1.15beta1 | go | +| -debug | Retains debug information in the application. Allows the use of the devtools in the application window | | +| -dryrun | Prints the build command without executing it | | +| -f | Force build application | | +| -garbleargs | Arguments to pass to garble | `-literals -tiny -seed=random` | | -ldflags "flags" | Additional ldflags to pass to the compiler | | +| -m | Skip mod tidy before compile | | | -nopackage | Do not package application | | +| -nocolour | Disable colour in output | | +| -nosyncgomod | Do not sync go.mod with the Wails version | | +| -nsis | Generate NSIS installer for Windows | | | -o filename | Output filename | | -| -s | Skip building the frontend | false | -| -f | Force build application | false | +| -obfuscated | Obfuscate the application using [garble](https://github.com/burrowers/garble) | | +| -platform | Build for the given (comma delimited) [platforms](../reference/cli.mdx#platforms) eg. `windows/arm64`. Note, if you do not give the architecture, `runtime.GOARCH` is used. | platform = `GOOS` environment variable if given else `runtime.GOOS`.
arch = `GOARCH` envrionment variable if given else `runtime.GOARCH`. | +| -race | Build with Go's race detector | | +| -s | Skip building the frontend | | +| -skipbindings | Skip bindings generation | | | -tags "extra tags" | Build tags to pass to Go compiler. Must be quoted. Space or comma (but not both) separated | | +| -trimpath | Remove all file system paths from the resulting executable. | | +| -u | Updates your project's `go.mod` to use the same version of Wails as the CLI | | | -upx | Compress final binary using "upx" | | | -upxflags | Flags to pass to upx | | | -v int | Verbosity level (0 - silent, 1 - default, 2 - verbose) | 1 | | -webview2 | WebView2 installer strategy: download,embed,browser,error | download | -| -u | Updates your project's `go.mod` to use the same version of Wails as the CLI | | -| -debug | Retains debug information in the application. Allows the use of the devtools in the application window | false | -| -trimpath | Remove all file system paths from the resulting executable. | false | -| -race | Build with Go's race detector | false | | -windowsconsole | Keep the console window for Windows builds | | -| -obfuscate | Obfuscate the application using [garble](https://github.com/burrowers/garble) | false | -| -garbleargs | Arguments to pass to garble | `-literals -tiny -seed=random` | -| -nosyncgomod | Do not sync go.mod with the Wails version | false | For a detailed description of the `webview2` flag, please refer to the [Windows](../guides/windows.mdx) Guide. @@ -167,29 +172,28 @@ Your system is ready for Wails development! | Flag | Description | Default | |:---------------------------- |:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |:--------------------- | +| -appargs "args" | Arguments passed to the application in shell style | | | -assetdir "./path/to/assets" | Serve assets from the given directory instead of using the provided asset FS | Value in `wails.json` | | -browser | Opens a browser to `http://localhost:34115` on startup | | | -compiler "compiler" | Use a different go compiler to build, eg go1.15beta1 | go | -| -e | Extensions to trigger rebuilds (comma separated) | go | -| -reloaddirs | Additional directories to trigger reloads (comma separated) | Value in `wails.json` | -| -ldflags "flags" | Additional ldflags to pass to the compiler | | -| -tags "extra tags" | Build tags to pass to compiler (quoted and space separated) | | -| -loglevel "loglevel" | Loglevel to use - Trace, Debug, Info, Warning, Error | Debug | -| -noreload | Disable automatic reload when assets change | | -| -nocolour | Turn off colour cli output | false | -| -nogen | Disable generate module | | -| -v | Verbosity level (0 - silent, 1 - standard, 2 - verbose) | 1 | -| -wailsjsdir | The directory to generate the generated Wails JS modules | Value in `wails.json` | | -debounce | The time to wait for reload after an asset change is detected | 100 (milliseconds) | | -devserver "host:port" | The address to bind the wails dev server to | "localhost:34115" | +| -extensions | Extensions to trigger rebuilds (comma separated) | go | +| -forcebuild | Force build of application | | | -frontenddevserverurl "url" | Use 3rd party dev server url to serve assets, EG Vite | "" | -| -appargs "args" | Arguments passed to the application in shell style | | -| -save | Saves the given `assetdir`, `reloaddirs`, `wailsjsdir`, `debounce`, `devserver` and `frontenddevserverurl` flags in `wails.json` to become the defaults for subsequent invocations. | | -| -race | Build with Go's race detector | false | -| -s | Skip building the frontend | false | +| -ldflags "flags" | Additional ldflags to pass to the compiler | | +| -loglevel "loglevel" | Loglevel to use - Trace, Debug, Info, Warning, Error | Debug | +| -nocolour | Turn off colour cli output | false | +| -noreload | Disable automatic reload when assets change | | | -nosyncgomod | Do not sync go.mod with the Wails version | false | - - +| -race | Build with Go's race detector | false | +| -reloaddirs | Additional directories to trigger reloads (comma separated) | Value in `wails.json` | +| -s | Skip building the frontend | false | +| -save | Saves the given `assetdir`, `reloaddirs`, `wailsjsdir`, `debounce`, `devserver` and `frontenddevserverurl` flags in `wails.json` to become the defaults for subsequent invocations. | | +| -skipbindings | Skip bindings generation | | +| -tags "extra tags" | Build tags to pass to compiler (quoted and space separated) | | +| -v | Verbosity level (0 - silent, 1 - standard, 2 - verbose) | 1 | +| -wailsjsdir | The directory to generate the generated Wails JS modules | Value in `wails.json` | Example: diff --git a/website/i18n/ru/docusaurus-plugin-content-pages/changelog.mdx b/website/i18n/ru/docusaurus-plugin-content-pages/changelog.mdx index 866a230e..e8963ce5 100644 --- a/website/i18n/ru/docusaurus-plugin-content-pages/changelog.mdx +++ b/website/i18n/ru/docusaurus-plugin-content-pages/changelog.mdx @@ -13,7 +13,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] -## [v2.5.1] - 2023-05-16 +### Fixed + +- Avoid app crashing when the Linux GTK key is empty by @aminya in [PR](https://github.com/wailsapp/wails/pull/2672) + +### Changed + +- Changed styling of `doctor` command. Changed by @MarvinJWendt in [PR](https://github.com/wailsapp/wails/pull/2660) + +## v2.5.1 - 2023-05-16 ### Breaking Changes diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/cli.mdx b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/cli.mdx index b46f13cf..d6d3720a 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/cli.mdx +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/reference/cli.mdx @@ -51,27 +51,32 @@ Wails CLI 有许多用于管理项目的命令。 所有命令都以此方式运 | 标志 | 描述 | 默认 | |:--------------- |:------------------------------------------------------------------------------------------------------------- |:---------------------------------------------------------------------------------------------------------- | -| -platform | 为指定的 [平台](../reference/cli#平台)(逗号分割)构建,例如: `windows/arm64`。 `windows/arm64`。 注意,如果不给出架构,则使用 `runtime.GOARCH`。 | 如果给定环境变量 platform = `GOOS` 否则等于 `runtime.GOOS`。
如果给定环境变量 arch = `GOARCH` 否则等于 `runtime.GOARCH`. | | -clean | 清理 `build/bin` 目录 | | | -compiler "编译器" | 使用不同的 go 编译器来构建,例如 go1.15beta1 | go | +| -debug | 在应用程序中保留调试信息。 允许在应用程序窗口中使用 devtools | | +| -dryrun | 打印构建命令但不执行它 | | +| -f | 强制构建应用 | | +| -garbleargs | 传递给 garble 的参数 | `-literals -tiny -seed=random` | | -ldflags "标志" | 传递给编译器的额外 ldflags | | +| -m | 编译前跳过 mod tidy | | | -nopackage | 不打包应用程序 | | +| -nocolour | 在输出中禁用颜色 | | +| -nosyncgomod | 不同步 go.mod 中的 Wails 版本 | | +| -nsis | 为 Windows 生成 NSIS 安装程序 | | | -o 文件名 | 输出文件名 | | -| -s | 跳过前端构建 | false | -| -f | 强制构建应用 | false | +| -obfuscated | 使用 [garble](https://github.com/burrowers/garble) 混淆应用程序 | | +| -platform | 为指定的 [平台](../reference/cli#平台)(逗号分割)构建,例如: `windows/arm64`。 `windows/arm64`。 注意,如果不给出架构,则使用 `runtime.GOARCH`。 | 如果给定环境变量 platform = `GOOS` 否则等于 `runtime.GOOS`。
如果给定环境变量 arch = `GOARCH` 否则等于 `runtime.GOARCH`. | +| -race | 使用 Go 的竞态检测器构建 | | +| -s | 跳过前端构建 | | +| -skipbindings | 跳过 bindings 生成 | | | -tags "额外标签" | 构建标签以传递给 Go 编译器。 必须引用。 空格或逗号(但不能同时使用)分隔 | | +| -trimpath | 从生成的可执行文件中删除所有文件系统路径。 | | +| -u | 更新项目的 `go.mod` 以使用与 CLI 相同版本的 Wails | | | -upx | 使用 “upx” 压缩最终二进制文件 | | | -upxflags | 传递给 upx 的标志 | | | -v int | 详细级别 (0 - silent, 1 - default, 2 - verbose) | 1 | | -webview2 | WebView2 安装策略:download,embed,browser,error. | download | -| -u | 更新项目的 `go.mod` 以使用与 CLI 相同版本的 Wails | | -| -debug | 在应用程序中保留调试信息。 允许在应用程序窗口中使用 devtools | false | -| -trimpath | 从生成的可执行文件中删除所有文件系统路径。 | false | -| -race | 使用 Go 的竞态检测器构建 | false | | -windowsconsole | 保留Windows构建控制台窗口 | | -| -obfuscate | 使用 [garble](https://github.com/burrowers/garble) 混淆应用程序 | false | -| -garbleargs | 传递给 garble 的参数 | `-literals -tiny -seed=random` | -| -nosyncgomod | 不同步 go.mod 中的 Wails 版本 | false | 有关 `webview2` 标志的详细描述,请参阅 [Windows 系统指南](../guides/windows)。 @@ -161,35 +166,34 @@ Your system is ready for Wails development! - 所有应用程序资源都从磁盘加载。 如果它们被更改,应用程序将自动重新加载(而不是重新构建)。 所有连接的浏览器也将重新加载 - 生成的 JS 模块提供以下内容: - 带有自动生成的 JSDoc 的 Go 方法的 JavaScript 包装器,提供代码提示 - - 您的 Go 结构体的 TypeScript 版本,可以构造并传递给您的 Go 方法 -- 生成的第二个 JS 模块,为运行时提供包装器 + TS 声明 -- 在 macOS 上,它会将应用程序打包到一个 `.app` 文件并运行它。 开发模式它将使用 `build/darwin/Info.dev.plist` 。 + - 您的 Go 结构的 TypeScript 版本,可以构建并传递给您的 go 方法 +- 生成第二个 JS 模块,为运行时提供包装器 + TS 声明 +- 在 macOS 上,它将应用程序捆绑到一个 `.app` 文件中并运行它。 开发模式将使用 `build/darwin/Info.dev.plist` 。 | 标志 | 描述 | 默认 | |:---------------------------- |:-------------------------------------------------------------------------------------------------------------------------------- |:----------------- | +| -appargs "参数" | 以 shell 样式传递给应用程序的参数 | | | -assetdir "./path/to/assets" | 从给定目录提供资产,而不是使用提供的资产 FS | `wails.json` 中的值 | | -browser | 在启动时打开浏览器到 `http://localhost:34115` | | | -compiler "编译器" | 使用不同的 go 编译器来构建,例如 go1.15beta1 | go | -| -e | 触发重新构建的扩展(逗号分隔) | go | -| -reloaddirs | 触发重新加载的附加目录(逗号分隔) | `wails.json` 中的值 | -| -ldflags "标志" | 传递给编译器的额外 ldflags | | -| -tags "额外标签" | 传递给编译器的构建标签(引号和空格分隔) | | -| -loglevel "日志级别" | 要使用的日志级别 - Trace, Debug, Info, Warning, Error | Debug(调试) | -| -noreload | 资产更改时禁用自动重新加载 | | -| -nocolour | 关闭彩色命令行输出 | false | -| -nogen | 禁用生成模块 | | -| -v | 详细级别 (0 - silent, 1 - standard, 2 - verbose) | 1 | -| -wailsjsdir | 生成生成的Wails JS模块的目录 | `wails.json` 中的值 | | -debounce | 检测到资产更改后等待重新加载的时间 | 100 (毫秒) | | -devserver "host:port" | 将 wails 开发服务器绑定到的地址 | "localhost:34115" | +| -extensions | 触发重新构建的扩展(逗号分隔) | go | +| -forcebuild | 强制构建应用程序 | | | -frontenddevserverurl "url" | 使用 3rd 方开发服务器 url 提供资产,例如:Vite | "" | -| -appargs "参数" | 以 shell 样式传递给应用程序的参数 | | -| -save | 将指定的 `assetdir`、 `reloaddirs`、 `wailsjsdir`、 `debounce` 、 `devserver` 和 `frontenddevserverurl` 标志的值保存到 `wails.json` 以成为后续调用的默认值。 | | -| -race | 使用 Go 的竞态检测器构建 | false | -| -s | 跳过前端构建 | false | +| -ldflags "标志" | 传递给编译器的额外 ldflags | | +| -loglevel "日志级别" | 要使用的日志级别 - Trace, Debug, Info, Warning, Error | Debug(调试) | +| -nocolour | 关闭彩色命令行输出 | false | +| -noreload | 资产更改时禁用自动重新加载 | | | -nosyncgomod | 不同步 go.mod 中的 Wails 版本 | false | - - +| -race | 使用 Go 的竞态检测器构建 | false | +| -reloaddirs | 触发重新加载的附加目录(逗号分隔) | `wails.json` 中的值 | +| -s | 跳过前端构建 | false | +| -save | 将指定的 `assetdir`、 `reloaddirs`、 `wailsjsdir`、 `debounce` 、 `devserver` 和 `frontenddevserverurl` 标志的值保存到 `wails.json` 以成为后续调用的默认值。 | | +| -skipbindings | 跳过 bindings 生成 | | +| -tags "额外标签" | 传递给编译器的构建标签(引号和空格分隔) | | +| -v | 详细级别 (0 - silent, 1 - standard, 2 - verbose) | 1 | +| -wailsjsdir | 生成生成的Wails JS模块的目录 | `wails.json` 中的值 | 示例: diff --git a/website/i18n/zh-Hans/docusaurus-plugin-content-pages/changelog.mdx b/website/i18n/zh-Hans/docusaurus-plugin-content-pages/changelog.mdx index 8cf68556..bb874869 100644 --- a/website/i18n/zh-Hans/docusaurus-plugin-content-pages/changelog.mdx +++ b/website/i18n/zh-Hans/docusaurus-plugin-content-pages/changelog.mdx @@ -13,7 +13,15 @@ ## [即将发布] -## [v2.5.1] - 2023-05-16 +### 修复 + +- 当 Linux GTK 密钥为空时避免应用程序崩溃。 由 @aminya 在这个 [PR](https://github.com/wailsapp/wails/pull/2672) 中修复。 + +### 变更 + +- 更改了 `doctor` 命令的样式。 由 @MarvinJWendt 在 [PR](https://github.com/wailsapp/wails/pull/2660) 中更改。 + +## v2.5.1 - 2023-05-16 ### 重大变更 @@ -87,8 +95,8 @@ ### 修复 - Fixed failing build hooks when `build/bin` was missing. @Lyimmi 在 [PR](https://github.com/wailsapp/wails/pull/2273) 中修复 -- Fixed fullscreen mode for frameless window on Windows to fully cover the taskbar when changing into fullscreen from maximised state. @stffabi 在 [PR](https://github.com/wailsapp/wails/pull/2279) 中修复 -- Fixed set window background colour on Windows when setting the colour via runtime. @stffabi 在 [PR](https://github.com/wailsapp/wails/pull/2279) 中修复 +- Fixed fullscreen mode for frameless window on Windows to fully cover the taskbar when changing into fullscreen from maximised state. Fixed by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2279) +- Fixed set window background colour on Windows when setting the colour via runtime. Fixed by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2279) - Fixed the showing of a white border around a fullscreen window when `DisableWindowIcon` is active on Windows. Fixed by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2299) - Fixed the sometimes lagging drag experience with `--wails-draggable` on Windows. Fixed by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2302) - Fixed applying the default arch to platform flag in wails cli. If only a `GOOS` has been supplied as platform flag e.g. `wails build --platform windows` the current architecture wasn't applied and the build failed. Fixed by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2309) From 6d857bf61ad8e4835b84ab58e37407a2da1dfe03 Mon Sep 17 00:00:00 2001 From: 5aaee9 <7685264+5aaee9@users.noreply.github.com> Date: Sat, 3 Jun 2023 15:26:24 -0600 Subject: [PATCH 04/36] windows/nsis: add hidpi support for nsis installer (#2694) * feat(windows/nsis): add hidpi support for nsis installer * website: add changelog --- v2/examples/customlayout/build/windows/installer/project.nsi | 3 +++ v2/pkg/buildassets/build/windows/installer/project.nsi | 3 +++ website/src/pages/changelog.mdx | 1 + 3 files changed, 7 insertions(+) diff --git a/v2/examples/customlayout/build/windows/installer/project.nsi b/v2/examples/customlayout/build/windows/installer/project.nsi index 3b1588e0..2ccc0f3f 100644 --- a/v2/examples/customlayout/build/windows/installer/project.nsi +++ b/v2/examples/customlayout/build/windows/installer/project.nsi @@ -45,6 +45,9 @@ 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" diff --git a/v2/pkg/buildassets/build/windows/installer/project.nsi b/v2/pkg/buildassets/build/windows/installer/project.nsi index 7b2148bc..13cc4f02 100644 --- a/v2/pkg/buildassets/build/windows/installer/project.nsi +++ b/v2/pkg/buildassets/build/windows/installer/project.nsi @@ -45,6 +45,9 @@ 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" diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 32a28203..0ed111b6 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Changed styling of `doctor` command. Changed by @MarvinJWendt in [PR](https://github.com/wailsapp/wails/pull/2660) +- Enable HiDPI option by default in windows nsis installer by @5aaee9 in [PR](https://github.com/wailsapp/wails/pull/2694) ## v2.5.1 - 2023-05-16 From 28a2b4fbd9b6424d1048f08449e9001fbc8716ae Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Fri, 9 Jun 2023 10:15:21 +1000 Subject: [PATCH 05/36] [v2] Update go mod dependency versions --- v2/go.mod | 42 +++++++++++++++++----------------- v2/go.sum | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 21 deletions(-) diff --git a/v2/go.mod b/v2/go.mod index a323c32d..c40a121f 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -13,33 +13,33 @@ require ( github.com/go-git/go-git/v5 v5.3.0 github.com/go-ole/go-ole v1.2.6 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 - github.com/google/uuid v1.1.2 + github.com/google/uuid v1.3.0 github.com/jackmordaunt/icns v1.0.0 github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e - github.com/labstack/echo/v4 v4.9.0 - github.com/labstack/gommon v0.3.1 + github.com/labstack/echo/v4 v4.10.2 + github.com/labstack/gommon v0.4.0 github.com/leaanthony/clir v1.3.0 github.com/leaanthony/debme v1.2.1 - github.com/leaanthony/go-ansi-parser v1.0.1 + github.com/leaanthony/go-ansi-parser v1.6.0 github.com/leaanthony/gosod v1.0.3 - github.com/leaanthony/slicer v1.5.0 + github.com/leaanthony/slicer v1.6.0 github.com/leaanthony/winicon v1.0.0 github.com/matryer/is v1.4.0 - github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 + github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/pkg/errors v0.9.1 github.com/pterm/pterm v0.12.49 github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 - github.com/samber/lo v1.27.1 - github.com/stretchr/testify v1.8.0 + github.com/samber/lo v1.38.1 + github.com/stretchr/testify v1.8.1 github.com/tc-hib/winres v0.1.5 github.com/tidwall/sjson v1.1.7 - github.com/tkrajina/go-reflector v0.5.5 + github.com/tkrajina/go-reflector v0.5.6 github.com/wailsapp/mimetype v1.4.1 github.com/wzshiming/ctc v1.2.3 - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 - golang.org/x/net v0.7.0 - golang.org/x/sys v0.5.0 - golang.org/x/tools v0.1.12 + golang.org/x/mod v0.8.0 + golang.org/x/net v0.10.0 + golang.org/x/sys v0.8.0 + golang.org/x/tools v0.6.0 ) require ( @@ -63,8 +63,8 @@ require ( github.com/kr/pretty v0.3.0 // indirect github.com/lithammer/fuzzysearch v1.1.5 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/mattn/go-colorable v0.1.11 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/microcosm-cc/bluemonday v1.0.17 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -73,23 +73,23 @@ require ( github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rivo/uniseg v0.2.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect github.com/sergi/go-diff v1.2.0 // indirect github.com/tidwall/gjson v1.9.3 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.1 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae // indirect github.com/xanzy/ssh-agent v0.3.0 // indirect github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect github.com/yuin/goldmark v1.4.13 // indirect github.com/yuin/goldmark-emoji v1.0.1 // indirect - golang.org/x/crypto v0.1.0 // indirect - golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect + golang.org/x/crypto v0.9.0 // indirect + golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/image v0.5.0 // indirect - golang.org/x/term v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/term v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/v2/go.sum b/v2/go.sum index 1eb91983..415b4e42 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -28,6 +28,11 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU 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/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= +github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= +github.com/aymanbagabas/go-osc52 v1.2.2 h1:NT7wkhEhPTcKnBCdPi9djmyy9L3JOL4+3SsfJyqptCo= +github.com/aymanbagabas/go-osc52 v1.2.2/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= @@ -36,6 +41,8 @@ github.com/bitfield/script v0.19.0 h1:W24f+FQuPab9gXcW8bhcbo5qO8AtrXyu3XOnR4zhHN github.com/bitfield/script v0.19.0/go.mod h1:ana6F8YOSZ3ImT8SauIzuYSqXgFVkSUJ6kgja+WMmIY= github.com/charmbracelet/glamour v0.5.0 h1:wu15ykPdB7X6chxugG/NNfDUbyyrCLV9XBalj5wdu3g= github.com/charmbracelet/glamour v0.5.0/go.mod h1:9ZRtG19AUIzcTm7FGLGbq3D5WKQ5UyZBbQsMQN0XIqc= +github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc= +github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8om2538k9ITBxOc= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -44,6 +51,8 @@ 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/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= +github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= @@ -69,10 +78,13 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +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/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI= @@ -105,8 +117,12 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY= github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= +github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M= +github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k= github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o= github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= +github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/leaanthony/clir v1.0.4/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0= github.com/leaanthony/clir v1.3.0 h1:L9nPDWrmc/qU9UWZZvRaFajWYuO0np9V5p+5gxyYno0= github.com/leaanthony/clir v1.3.0/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0= @@ -114,10 +130,14 @@ github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oO github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA= github.com/leaanthony/go-ansi-parser v1.0.1 h1:97v6c5kYppVsbScf4r/VZdXyQ21KQIfeQOk2DgKxGG4= github.com/leaanthony/go-ansi-parser v1.0.1/go.mod h1:7arTzgVI47srICYhvgUV4CGd063sGEeoSlych5yeSPM= +github.com/leaanthony/go-ansi-parser v1.6.0 h1:T8TuMhFB6TUMIUm0oRrSbgJudTFw9csT3ZK09w0t4Pg= +github.com/leaanthony/go-ansi-parser v1.6.0/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU= github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ= github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRCSG7jGxs4= github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0HtY= github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY= +github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js= +github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8= github.com/leaanthony/winicon v1.0.0 h1:ZNt5U5dY71oEoKZ97UVwJRT4e+5xo5o/ieKuHuk8NqQ= github.com/leaanthony/winicon v1.0.0/go.mod h1:en5xhijl92aphrJdmRPlh4NI1L6wq3gEm0LpXAPghjU= github.com/lithammer/fuzzysearch v1.1.5 h1:Ag7aKU08wp0R9QCfF4GoGST9HbmAIeLP7xwMrOBEp1c= @@ -128,21 +148,34 @@ 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.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +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.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/microcosm-cc/bluemonday v1.0.17 h1:Z1a//hgsQ4yjC+8zEkV8IWySkXnsxmdSY642CTFQb5Y= github.com/microcosm-cc/bluemonday v1.0.17/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= +github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= +github.com/microcosm-cc/bluemonday v1.0.24 h1:NGQoPtwGVcbGkKfvyYk1yRqknzBuoMiUrO6R7uFTPlw= +github.com/microcosm-cc/bluemonday v1.0.24/go.mod h1:ArQySAMps0790cHSkdPEJ7bGkF2VePWH773hsJNSHf8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.9.0 h1:wnbOaGz+LUR3jNT0zOzinPnyDaCZUQRZj9GxK8eRVl8= github.com/muesli/termenv v0.9.0/go.mod h1:R/LzAKf+suGs4IsO95y7+7DpFHO0KABgnZqtlyx2mBw= +github.com/muesli/termenv v0.13.0/go.mod h1:sP1+uffeLaEYpyOTb8pLCUctGcGLnoFjSn4YJK5e2bc= +github.com/muesli/termenv v0.15.1 h1:UzuTb/+hhlBugQz28rpzey4ZuKcZ03MeKsoG7IJZIxs= +github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= @@ -150,6 +183,8 @@ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 h1:acNfDZXmm28D2Yg/c3ALnZStzNaZMSagpbr96vY6Zjc= github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +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.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -167,12 +202,16 @@ github.com/pterm/pterm v0.12.49/go.mod h1:D4OBoWNqAfXkm5QLTjIgjNiMXPHemLJHnIreGU github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI= github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs= github.com/samber/lo v1.27.1 h1:sTXwkRiIFIQG+G0HeAvOEnGjqWeWtI9cg5/n51KrxPg= github.com/samber/lo v1.27.1/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+Rhg= +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.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 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= @@ -180,6 +219,7 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -187,6 +227,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tc-hib/winres v0.1.5 h1:2dA5yfjdoEA3UyRaOC92HNMt3jap66pLzoW4MjpC/0M= github.com/tc-hib/winres v0.1.5/go.mod h1:pe6dOR40VOrGz8PkzreVKNvEKnlE8t4yR8A8naL+t7A= github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= @@ -203,10 +244,14 @@ github.com/tidwall/sjson v1.1.7 h1:sgVPwu/yygHJ2m1pJDLgGM/h+1F5odx5Q9ljG3imRm8= github.com/tidwall/sjson v1.1.7/go.mod h1:w/yG+ezBeTdUxiKs5NcPicO9diP38nk96QBAbIIGeFs= github.com/tkrajina/go-reflector v0.5.5 h1:gwoQFNye30Kk7NrExj8zm3zFtrGPqOkzFMLuQZg1DtQ= github.com/tkrajina/go-reflector v0.5.5/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4= +github.com/tkrajina/go-reflector v0.5.6 h1:hKQ0gyocG7vgMD2M3dRlYN6WBBOmdoOzJ6njQSepKdE= +github.com/tkrajina/go-reflector v0.5.6/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o= github.com/wzshiming/ctc v1.2.3 h1:q+hW3IQNsjIlOFBTGZZZeIXTElFM4grF4spW/errh/c= @@ -221,6 +266,9 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU= +github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os= github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -229,22 +277,31 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI= golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= 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/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -271,24 +328,35 @@ golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= 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.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= 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.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 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 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 3dbe6e96c13f4d2245a9e8a6858d62b68a209f60 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Jun 2023 10:40:39 +1000 Subject: [PATCH 06/36] chore: update sponsors.svg (#2701) Co-authored-by: leaanthony --- website/static/img/sponsors.svg | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/website/static/img/sponsors.svg b/website/static/img/sponsors.svg index d4d16761..4953896d 100644 --- a/website/static/img/sponsors.svg +++ b/website/static/img/sponsors.svg @@ -21,7 +21,7 @@ text {
Covering Costs Nick - + Marcus @@ -35,32 +35,28 @@ text { Matt Holt Buying Breakfast - tc-hib - + tc-hib + - Liam - + Liam + - Tai Groot - + Tai Groot + - Michael - + Michael + - Bironou - + Bironou + - Arden - - - - beproac... - + Arden + Buying Coffee From 41edd78953f069d1599f8516ca660703b539e878 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 10 Jun 2023 17:01:01 +1000 Subject: [PATCH 07/36] Update format-markdown-files.yml --- .github/workflows/format-markdown-files.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/format-markdown-files.yml b/.github/workflows/format-markdown-files.yml index d3054642..a8f7de9c 100644 --- a/.github/workflows/format-markdown-files.yml +++ b/.github/workflows/format-markdown-files.yml @@ -1,9 +1,5 @@ name: Format Markdown Files -on: - workflow_dispatch: - push: - branches: [master] jobs: format_markdown_files: From f2ab205415eb8aecf4d2f913e7600fad40819540 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 10 Jun 2023 17:04:31 +1000 Subject: [PATCH 08/36] [chore] Use webview2 package (#2687) * [v2 windows] Use external webview2 package * Update CHANGELOG --- v2/go.mod | 2 + v2/go.sum | 2 + .../frontend/desktop/windows/frontend.go | 2 +- .../desktop/windows/go-webview2/LICENSE | 22 - .../desktop/windows/go-webview2/README.md | 27 - .../windows/go-webview2/internal/w32/w32.go | 157 ------ .../go-webview2/pkg/combridge/bridge.go | 239 --------- .../go-webview2/pkg/combridge/iunknown.go | 56 -- .../pkg/combridge/iunknown_impl.go | 74 --- .../go-webview2/pkg/combridge/syscall.go | 39 -- .../go-webview2/pkg/combridge/vtables.go | 147 ----- .../pkg/edge/COREWEBVIEW2_COLOR.go | 10 - .../COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND.go | 11 - .../pkg/edge/COREWEBVIEW2_KEY_EVENT_KIND.go | 12 - .../edge/COREWEBVIEW2_MOVE_FOCUS_REASON.go | 11 - .../edge/COREWEBVIEW2_PHYSICAL_KEY_STATUS.go | 12 - .../edge/COREWEBVIEW2_PROCESS_FAILED_KIND.go | 49 -- .../edge/COREWEBVIEW2_WEB_RESOURCE_CONTEXT.go | 25 - ...eWebView2AcceleratorKeyPressedEventArgs.go | 79 --- ...bView2AcceleratorKeyPressedEventHandler.go | 53 -- .../pkg/edge/ICoreWebView2Controller.go | 160 ------ .../pkg/edge/ICoreWebView2Controller2.go | 75 --- ...eCoreWebView2ControllerCompletedHandler.go | 53 -- ...reWebView2HttpHeadersCollectionIterator.go | 78 --- .../edge/ICoreWebView2HttpRequestHeaders.go | 101 ---- ...oreWebView2NavigationCompletedEventArgs.go | 18 - ...WebView2NavigationCompletedEventHandler.go | 53 -- .../ICoreWebView2ProcessFailedEventArgs.go | 41 -- .../ICoreWebView2ProcessFailedEventHandler.go | 53 -- .../pkg/edge/ICoreWebView2Settings.go | 271 ---------- .../edge/ICoreWebView2WebResourceRequest.go | 102 ---- ...reWebView2WebResourceRequestedEventArgs.go | 52 -- ...ebView2WebResourceRequestedEventHandler.go | 50 -- .../edge/ICoreWebView2WebResourceResponse.go | 28 - .../go-webview2/pkg/edge/ICoreWebView2_2.go | 18 - .../go-webview2/pkg/edge/ICoreWebView2_3.go | 62 --- .../pkg/edge/ICoreWebViewSettings.go | 397 -------------- .../windows/go-webview2/pkg/edge/IStream.go | 54 -- .../windows/go-webview2/pkg/edge/chromium.go | 419 --------------- .../go-webview2/pkg/edge/chromium_386.go | 23 - .../go-webview2/pkg/edge/chromium_amd64.go | 20 - .../go-webview2/pkg/edge/chromium_arm64.go | 23 - .../go-webview2/pkg/edge/corewebview2.go | 503 ------------------ .../go-webview2/pkg/edge/create_env_go.go | 29 - .../go-webview2/pkg/edge/create_env_native.go | 41 -- .../windows/go-webview2/pkg/edge/guid.go | 225 -------- .../windows/go-webview2/webviewloader/LICENSE | 16 - .../go-webview2/webviewloader/README.md | 19 - .../webviewloader/arm64/WebView2Loader.dll | Bin 124328 -> 0 bytes .../go-webview2/webviewloader/env_create.go | 176 ------ .../webviewloader/env_create_completed.go | 42 -- .../webviewloader/env_create_options.go | 276 ---------- .../go-webview2/webviewloader/find_dll.go | 74 --- .../webviewloader/find_dll_installed.go | 94 ---- .../webviewloader/native_module.go | 173 ------ .../webviewloader/native_module_386.go | 8 - .../webviewloader/native_module_amd64.go | 8 - .../webviewloader/native_module_arm64.go | 8 - .../go-webview2/webviewloader/syscall.go | 143 ----- .../go-webview2/webviewloader/version.go | 147 ----- .../webviewloader/x64/WebView2Loader.dll | Bin 137640 -> 0 bytes .../webviewloader/x86/WebView2Loader.dll | Bin 107416 -> 0 bytes .../frontend/desktop/windows/window.go | 3 +- v2/internal/system/system_windows.go | 2 +- v2/internal/wv2installer/wv2installer.go | 2 +- website/src/pages/changelog.mdx | 1 + 66 files changed, 9 insertions(+), 5161 deletions(-) delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/LICENSE delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/README.md delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/internal/w32/w32.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/bridge.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown_impl.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/syscall.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/vtables.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_COLOR.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_KEY_EVENT_KIND.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_MOVE_FOCUS_REASON.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PHYSICAL_KEY_STATUS.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PROCESS_FAILED_KIND.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_WEB_RESOURCE_CONTEXT.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventArgs.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventHandler.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller2.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2CreateCoreWebView2ControllerCompletedHandler.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpHeadersCollectionIterator.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpRequestHeaders.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventArgs.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventHandler.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventArgs.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventHandler.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Settings.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequest.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventArgs.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventHandler.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceResponse.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_2.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_3.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebViewSettings.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/IStream.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_386.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_amd64.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_arm64.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/corewebview2.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_go.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_native.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/guid.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/LICENSE delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/README.md delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/arm64/WebView2Loader.dll delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_completed.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_options.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll_installed.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_386.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_amd64.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_arm64.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/syscall.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/version.go delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/x64/WebView2Loader.dll delete mode 100644 v2/internal/frontend/desktop/windows/go-webview2/webviewloader/x86/WebView2Loader.dll diff --git a/v2/go.mod b/v2/go.mod index c40a121f..5d45d171 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -35,6 +35,7 @@ require ( github.com/tidwall/sjson v1.1.7 github.com/tkrajina/go-reflector v0.5.6 github.com/wailsapp/mimetype v1.4.1 + github.com/wailsapp/go-webview2 v1.0.1 github.com/wzshiming/ctc v1.2.3 golang.org/x/mod v0.8.0 golang.org/x/net v0.10.0 @@ -59,6 +60,7 @@ require ( github.com/gorilla/css v1.0.0 // indirect github.com/imdario/mergo v0.3.12 // 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 v0.0.0-20201106050909-4977a11b4351 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/lithammer/fuzzysearch v1.1.5 // indirect diff --git a/v2/go.sum b/v2/go.sum index 415b4e42..0a312566 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -250,6 +250,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/wailsapp/go-webview2 v1.0.1 h1:dEJIeEApW/MhO2tTMISZBFZPuW7kwrFA1NtgFB1z1II= +github.com/wailsapp/go-webview2 v1.0.1/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs= diff --git a/v2/internal/frontend/desktop/windows/frontend.go b/v2/internal/frontend/desktop/windows/frontend.go index 82289e05..c4186eda 100644 --- a/v2/internal/frontend/desktop/windows/frontend.go +++ b/v2/internal/frontend/desktop/windows/frontend.go @@ -21,9 +21,9 @@ import ( "time" "github.com/bep/debounce" + "github.com/wailsapp/go-webview2/pkg/edge" "github.com/wailsapp/wails/v2/internal/binding" "github.com/wailsapp/wails/v2/internal/frontend" - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge" "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/win32" "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc" "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc/w32" diff --git a/v2/internal/frontend/desktop/windows/go-webview2/LICENSE b/v2/internal/frontend/desktop/windows/go-webview2/LICENSE deleted file mode 100644 index ef2a0f48..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -MIT License - -Copyright (c) 2020 John Chadwick -Some portions Copyright (c) 2017 Serge Zaitsev - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/v2/internal/frontend/desktop/windows/go-webview2/README.md b/v2/internal/frontend/desktop/windows/go-webview2/README.md deleted file mode 100644 index 7379b302..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/README.md +++ /dev/null @@ -1,27 +0,0 @@ -# go-webview2 - -This is a proof of concept for embedding Webview2 into Go without CGo. It is based -on [webview/webview](https://github.com/webview/webview) and provides a compatible API. - -## Notice - -Because this version doesn't currently have an EdgeHTML fallback, it will not work unless you have a Webview2 runtime -installed. In addition, it requires the Webview2Loader DLL in order to function. Adding an EdgeHTML fallback should be -technically possible but will likely require much worse hacks since the API is not strictly COM to my knowledge. - -## Demo - -For now, you'll need to install the Webview2 runtime, as it does not ship with Windows. - -[WebView2 runtime](https://developer.microsoft.com/en-us/microsoft-edge/webview2/) - -After that, you should be able to run go-webview2 directly: - -``` -go run go-webview2/cmd/demo -``` - -This will use go-winloader to load an embedded copy of WebView2Loader.dll. - -If this does not work, please try running from a directory that has an appropriate copy of `WebView2Loader.dll` for your -GOARCH. If _that_ worked, *please* file a bug so we can figure out what's wrong with go-winloader :) \ No newline at end of file diff --git a/v2/internal/frontend/desktop/windows/go-webview2/internal/w32/w32.go b/v2/internal/frontend/desktop/windows/go-webview2/internal/w32/w32.go deleted file mode 100644 index 2b564173..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/internal/w32/w32.go +++ /dev/null @@ -1,157 +0,0 @@ -//go:build windows - -package w32 - -import ( - "syscall" - "unicode/utf16" - "unsafe" - - "golang.org/x/sys/windows" -) - -var ( - ole32 = windows.NewLazySystemDLL("ole32") - Ole32CoInitializeEx = ole32.NewProc("CoInitializeEx") - - kernel32 = windows.NewLazySystemDLL("kernel32") - Kernel32GetCurrentThreadID = kernel32.NewProc("GetCurrentThreadId") - - shlwapi = windows.NewLazySystemDLL("shlwapi") - shlwapiSHCreateMemStream = shlwapi.NewProc("SHCreateMemStream") - - user32 = windows.NewLazySystemDLL("user32") - User32LoadImageW = user32.NewProc("LoadImageW") - User32GetSystemMetrics = user32.NewProc("GetSystemMetrics") - User32RegisterClassExW = user32.NewProc("RegisterClassExW") - User32CreateWindowExW = user32.NewProc("CreateWindowExW") - User32DestroyWindow = user32.NewProc("DestroyWindow") - User32ShowWindow = user32.NewProc("ShowWindow") - User32UpdateWindow = user32.NewProc("UpdateWindow") - User32SetFocus = user32.NewProc("SetFocus") - User32GetMessageW = user32.NewProc("GetMessageW") - User32TranslateMessage = user32.NewProc("TranslateMessage") - User32DispatchMessageW = user32.NewProc("DispatchMessageW") - User32DefWindowProcW = user32.NewProc("DefWindowProcW") - User32GetClientRect = user32.NewProc("GetClientRect") - User32PostQuitMessage = user32.NewProc("PostQuitMessage") - User32SetWindowTextW = user32.NewProc("SetWindowTextW") - User32PostThreadMessageW = user32.NewProc("PostThreadMessageW") - User32GetWindowLongPtrW = user32.NewProc("GetWindowLongPtrW") - User32SetWindowLongPtrW = user32.NewProc("SetWindowLongPtrW") - User32AdjustWindowRect = user32.NewProc("AdjustWindowRect") - User32SetWindowPos = user32.NewProc("SetWindowPos") -) - -const ( - SystemMetricsCxIcon = 11 - SystemMetricsCyIcon = 12 -) - -const ( - SWShow = 5 -) - -const ( - SWPNoZOrder = 0x0004 - SWPNoActivate = 0x0010 - SWPNoMove = 0x0002 - SWPFrameChanged = 0x0020 -) - -const ( - WMDestroy = 0x0002 - WMMove = 0x0003 - WMSize = 0x0005 - WMClose = 0x0010 - WMQuit = 0x0012 - WMGetMinMaxInfo = 0x0024 - WMNCLButtonDown = 0x00A1 - WMMoving = 0x0216 - WMApp = 0x8000 -) - -const ( - GWLStyle = -16 -) - -const ( - WSOverlapped = 0x00000000 - WSMaximizeBox = 0x00020000 - WSThickFrame = 0x00040000 - WSCaption = 0x00C00000 - WSSysMenu = 0x00080000 - WSMinimizeBox = 0x00020000 - WSOverlappedWindow = (WSOverlapped | WSCaption | WSSysMenu | WSThickFrame | WSMinimizeBox | WSMaximizeBox) -) - -type WndClassExW struct { - CbSize uint32 - Style uint32 - LpfnWndProc uintptr - CnClsExtra int32 - CbWndExtra int32 - HInstance windows.Handle - HIcon windows.Handle - HCursor windows.Handle - HbrBackground windows.Handle - LpszMenuName *uint16 - LpszClassName *uint16 - HIconSm windows.Handle -} - -type Rect struct { - Left int32 - Top int32 - Right int32 - Bottom int32 -} - -type MinMaxInfo struct { - PtReserved Point - PtMaxSize Point - PtMaxPosition Point - PtMinTrackSize Point - PtMaxTrackSize Point -} - -type Point struct { - X, Y int32 -} - -type Msg struct { - Hwnd syscall.Handle - Message uint32 - WParam uintptr - LParam uintptr - Time uint32 - Pt Point - LPrivate uint32 -} - -func Utf16PtrToString(p *uint16) string { - if p == nil { - return "" - } - // Find NUL terminator. - end := unsafe.Pointer(p) - n := 0 - for *(*uint16)(end) != 0 { - end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p)) - n++ - } - s := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:n:n] - return string(utf16.Decode(s)) -} - -func SHCreateMemStream(data []byte) (uintptr, error) { - ret, _, err := shlwapiSHCreateMemStream.Call( - uintptr(unsafe.Pointer(&data[0])), - uintptr(len(data)), - ) - if ret == 0 { - return 0, err - } - - return ret, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/bridge.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/bridge.go deleted file mode 100644 index ccf04243..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/bridge.go +++ /dev/null @@ -1,239 +0,0 @@ -//go:build windows - -package combridge - -import ( - "fmt" - "runtime" - "sync" - "sync/atomic" -) - -var ( - comIfcePointersL sync.RWMutex - comIfcePointers = map[uintptr]*comObject{} // Map from ComInterfacePointer to the Go ComObject -) - -// Resolve the GoInterface of the specified ComInterfacePointer -func Resolve[T IUnknown](ifceP uintptr) T { - comIfcePointersL.RLock() - comObj := comIfcePointers[ifceP] - comIfcePointersL.RUnlock() - - var n T - if comObj != nil { - t := comObj.resolve(ifceP) - if t != nil { - n = t.(T) - } - } - - return n -} - -// New returns a new ComObject which implements the specified Com Interface, com calls will be redirected -// to the specified go interface. -func New[T IUnknown](obj T) *ComObject[T] { - cObj := new( - ifceDef[T]{obj}, - ) - return newComObject[T](cObj) -} - -// New2 returns a new ComObject which implements the two specified Com Interfaces, com calls will be redirected -// to those interfaces accordingly. -// This is needed if a ComObject should implement two interfaces that are not descendants of each other, -// then you get multiple inheritance. -func New2[T IUnknown, T2 IUnknown](obj T, obj2 T2) *ComObject[T] { - cObj := new( - ifceDef[T]{obj}, - ifceDef[T2]{obj2}, - ) - return newComObject[T](cObj) -} - -// new returns a new ComObject which implements multiple specified Com Interfaces, com calls will be redirected -// to the specified go interfaces accordingly. -// This is needed if a ComObject should implement multiple interfaces that are not descendants of each other, -// then you get multiple inheritance. -func new(impls ...ifceImpl) *comObject { - impls = append([]ifceImpl{ifceDef[IUnknown]{}}, impls...) - - cObj := &comObject{ - refCount: 1, - ifces: map[string]int{}, - ifcesImpl: make([]comInterfaceDesc, len(impls)), - } - - for i, ifceDef := range impls { - vtable, err := ifceDef.ifce() - if err != nil { - panic(err) - } - - needsImplement := false - for table := vtable; table != nil; table = table.Parent { - guid := table.ComGUID - if i, found := cObj.ifces[guid]; found { - // This Interface is already implemented - if guid == iUnknownGUID { - // IUnknown is a special interface and never has an user specific implementation - } else if cObj.ifcesImpl[i].impl != ifceDef.impl() { - panic(fmt.Sprintf("Interface '%s' is already implemented by another object", table.Name)) - } - - break - } - - needsImplement = true - cObj.ifces[guid] = i - } - - if !needsImplement { - continue - } - - ifceP, ifcePSlice := allocUintptrObject(1) - ifcePSlice[0] = vtable.ComVTable - cObj.ifcesImpl[i] = comInterfaceDesc{ifceP, ifceDef.impl()} - } - - comIfcePointersL.Lock() - for _, ifceImpl := range cObj.ifcesImpl { - comIfcePointers[ifceImpl.ref] = cObj - } - comIfcePointersL.Unlock() - - return cObj -} - -func newComObject[T IUnknown](comObj *comObject) *ComObject[T] { - c := &ComObject[T]{obj: comObj} - // Make sure to async release since release needs locks and might block the finalizer goroutine for a longer period - runtime.SetFinalizer(c, func(obj *ComObject[T]) { obj.close(true) }) - return c -} - -// ComObject describes an exported go instance to be used as a ComObject which implements -// the specified Interface. -type ComObject[T IUnknown] struct { - obj *comObject - closed int32 -} - -// Ref returns the native uintptr that points to the ComObject that is an interface pointer to T. -// This can be used in native calls. If the object has been closed this function will panic. -func (o *ComObject[T]) Ref() uintptr { - if atomic.LoadInt32(&o.closed) != 0 { - panic("ComObject has been released") - } - return o.obj.queryInterface(guidOf[T](), false) -} - -// Close releases the native com object from the go side. It will only be destroyed if the ref counter -// reaches zero. -// After closing `Ref()` will panic. -func (o *ComObject[T]) Close() error { - o.close(false) - return nil -} - -// close releases the native com object from the go side. It will only be destroyed if the ref counter -// reaches zero. -// After closing `Ref()` will panic. -func (o *ComObject[T]) close(asyncRelease bool) { - if atomic.CompareAndSwapInt32(&o.closed, 0, 1) { - runtime.SetFinalizer(o, nil) - if asyncRelease { - go o.obj.release() - } else { - o.obj.release() - } - } -} - -type comInterfaceDesc struct { - ref uintptr // The native Com InterfacePointer - impl any // The golang target object -} - -type comObject struct { - l sync.Mutex - - refCount int32 - ifces map[string]int // Map of ComInterfaceGUID to Interface Slots - ifcesImpl []comInterfaceDesc // Slots with InterfaceDescriptors -} - -func (c *comObject) queryInterface(ifceGUID string, withAddRef bool) uintptr { - c.l.Lock() - defer c.l.Unlock() - if c.refCount <= 0 { - panic("call on released com object") - } - - i, found := c.ifces[ifceGUID] - if !found { - return 0 - } - - if withAddRef { - c.refCount++ - } - return c.ifcesImpl[i].ref -} - -func (c *comObject) resolve(ifceP uintptr) any { - c.l.Lock() - defer c.l.Unlock() - if c.refCount <= 0 { - panic("call on destroyed com object") - } - - for _, ifce := range c.ifcesImpl { - if ifce.ref != ifceP { - continue - } - - return ifce.impl - } - return nil -} - -func (c *comObject) addRef() int32 { - c.l.Lock() - defer c.l.Unlock() - if c.refCount <= 0 { - panic("call on destroyed com object") - } - - c.refCount++ - return c.refCount -} - -func (c *comObject) release() int32 { - c.l.Lock() - defer c.l.Unlock() - if c.refCount <= 0 { - panic("call on destroyed com object") - } - - if c.refCount--; c.refCount == 0 { - comIfcePointersL.Lock() - for _, ref := range c.ifcesImpl { - delete(comIfcePointers, ref.ref) - } - comIfcePointersL.Unlock() - - for _, impl := range c.ifcesImpl { - ref := impl.ref - if ref == 0 { - continue - } - - globalFree(ref) - } - } - - return c.refCount -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown.go deleted file mode 100644 index 90d7247f..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown.go +++ /dev/null @@ -1,56 +0,0 @@ -//go:build windows - -package combridge - -import ( - "golang.org/x/sys/windows" -) - -const iUnknownGUID = "{00000000-0000-0000-C000-000000000046}" - -func init() { - registerVTableInternal[IUnknown, IUnknown]( - iUnknownGUID, - true, - iUnknownQueryInterface, - iUnknownAddRef, - iUnknownRelease, - ) -} - -type IUnknown interface{} - -func iUnknownQueryInterface(this uintptr, refiid *windows.GUID, ppvObject *uintptr) uintptr { - if refiid == nil || ppvObject == nil { - return uintptr(windows.E_INVALIDARG) - } - - comIfcePointersL.RLock() - obj := comIfcePointers[this] - comIfcePointersL.RUnlock() - - ref := obj.queryInterface(refiid.String(), true) - if ref != 0 { - *ppvObject = ref - return windows.NO_ERROR - } - - *ppvObject = 0 - return uintptr(windows.E_NOINTERFACE) -} - -func iUnknownAddRef(this uintptr) uintptr { - comIfcePointersL.RLock() - obj := comIfcePointers[this] - comIfcePointersL.RUnlock() - - return uintptr(obj.addRef()) -} - -func iUnknownRelease(this uintptr) uintptr { - comIfcePointersL.RLock() - obj := comIfcePointers[this] - comIfcePointersL.RUnlock() - - return uintptr(obj.release()) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown_impl.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown_impl.go deleted file mode 100644 index 4c748d46..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/iunknown_impl.go +++ /dev/null @@ -1,74 +0,0 @@ -//go:build windows - -package combridge - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -// IUnknownFromPointer cast a generic pointer into a IUnknownImpl pointer -func IUnknownFromPointer(ref unsafe.Pointer) *IUnknownImpl { - return (*IUnknownImpl)(ref) -} - -// IUnknownFromPointer cast native pointer into a IUnknownImpl pointer -func IUnknownFromUintptr(ref uintptr) *IUnknownImpl { - return IUnknownFromPointer(unsafe.Pointer(ref)) -} - -type IUnknownVtbl struct { - queryInterface uintptr - addRef uintptr - release uintptr -} - -func (i *IUnknownVtbl) QueryInterface(this unsafe.Pointer, refiid *windows.GUID, ppvObject **IUnknownImpl) error { - r, _, _ := syscall.SyscallN( - i.queryInterface, - uintptr(this), - uintptr(unsafe.Pointer(refiid)), - uintptr(unsafe.Pointer(ppvObject)), - ) - - if r != uintptr(windows.S_OK) { - return syscall.Errno(r) - } - - return nil -} - -func (i *IUnknownVtbl) AddRef(this unsafe.Pointer) uint32 { - r, _, _ := syscall.SyscallN( - i.addRef, - uintptr(this), - ) - return uint32(r) -} - -func (i *IUnknownVtbl) Release(this unsafe.Pointer) uint32 { - r, _, _ := syscall.SyscallN( - i.release, - uintptr(this), - ) - - return uint32(r) -} - -type IUnknownImpl struct { - vtbl *IUnknownVtbl -} - -func (i *IUnknownImpl) QueryInterface(refiid *windows.GUID, ppvObject **IUnknownImpl) error { - return i.vtbl.QueryInterface(unsafe.Pointer(i), refiid, ppvObject) -} - -func (i *IUnknownImpl) AddRef() uint32 { - return i.vtbl.AddRef(unsafe.Pointer(i)) -} - -func (i *IUnknownImpl) Release() uint32 { - return i.vtbl.Release(unsafe.Pointer(i)) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/syscall.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/syscall.go deleted file mode 100644 index 17b7f500..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/syscall.go +++ /dev/null @@ -1,39 +0,0 @@ -//go:build windows - -package combridge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - procGlobalAlloc = modkernel32.NewProc("GlobalAlloc") - procGlobalFree = modkernel32.NewProc("GlobalFree") - - uintptrSize = unsafe.Sizeof(uintptr(0)) -) - -func allocUintptrObject(size int) (uintptr, []uintptr) { - v := globalAlloc(uintptr(size) * uintptrSize) - slice := unsafe.Slice((*uintptr)(unsafe.Pointer(v)), size) - return v, slice -} - -func globalAlloc(dwBytes uintptr) uintptr { - ret, _, _ := procGlobalAlloc.Call(uintptr(0), dwBytes) - if ret == 0 { - panic("globalAlloc failed") - } - - return ret -} - -func globalFree(data uintptr) { - ret, _, _ := procGlobalFree.Call(data) - if ret != 0 { - panic("globalFree failed") - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/vtables.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/vtables.go deleted file mode 100644 index b099a784..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge/vtables.go +++ /dev/null @@ -1,147 +0,0 @@ -//go:build windows - -package combridge - -import ( - "fmt" - "reflect" - "sync" - - "golang.org/x/sys/windows" -) - -var ( - vTablesL sync.Mutex - vTables = make(map[string]*vTable) -) - -// RegisterVTable registers the vtable trampoline methods for the specified ComInterface -// TBase is the base interface of T, and must be another ComInterface which roots in IUnknown or IUnknown itself. -// The first paramter of the fn is always the uintptr of the ComObject and the GoObject can be resolved with Resolve(). -// After having resolved the GoObject the call must be redirected to the GoObject. -// Typically a trampoline FN looks like this. -// -// func _ICoreWebView2NavigationCompletedEventHandlerInvoke(this uintptr, sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) uintptr { -// return combridge.Resolve[_ICoreWebView2NavigationCompletedEventHandler](this).NavigationCompleted(sender, args) -// } -// -// The order of registration must be in the correct order as specified in the IDL of the interface. -func RegisterVTable[TParent, T IUnknown](guid string, fns ...interface{}) { - registerVTableInternal[TParent, T](guid, false, fns...) -} - -type vTable struct { - Parent *vTable - - Name string - ComGUID string - ComVTable uintptr - ComProcs []uintptr -} - -func registerVTableInternal[TParent, T IUnknown](guid string, isInternal bool, fns ...interface{}) { - vTablesL.Lock() - defer vTablesL.Unlock() - - t, tName := typeInterfaceToString[T]() - tParent, tParentName := typeInterfaceToString[TParent]() - if !t.Implements(tParent) { - panic(fmt.Errorf("RegisterVTable '%s': '%s' must implement '%s'", tName, tName, tParentName)) - } - - if !isInternal { - if t == reflect.TypeOf((*IUnknown)(nil)).Elem() { - panic(fmt.Errorf("RegisterVTable '%s' IUnknown can't be registered", tName)) - } - - if t == tParent { - panic(fmt.Errorf("RegisterVTable '%s': T and TParent can't be the same type", tName)) - } - } - - var parent *vTable - var parentProcs []uintptr - var parentProcsCount int - if t != tParent { - parent = vTables[tParentName] - if parent == nil { - panic(fmt.Errorf("RegisterVTable '%s': Parent VTable '%s' not registered", tName, tParentName)) - } - - parentProcs = parent.ComProcs - parentProcsCount = len(parentProcs) - } - - comGuid, err := windows.GUIDFromString(guid) - if err != nil { - panic(fmt.Errorf("RegisterVTable '%s': invalid guid: %s", tName, err)) - } - - vTable := &vTable{ - Parent: parent, - Name: tName, - ComGUID: comGuid.String(), - } - vTable.ComVTable, vTable.ComProcs = allocUintptrObject(parentProcsCount + len(fns)) - - for i, proc := range parentProcs { - vTable.ComProcs[i] = proc - } - - for i, fn := range fns { - vTable.ComProcs[parentProcsCount+i] = windows.NewCallback(fn) - } - - vTables[tName] = vTable -} - -func typeInterfaceToString[T any]() (reflect.Type, string) { - t := reflect.TypeOf((*T)(nil)) - if t.Kind() != reflect.Pointer { - panic("must be a (*yourInterfaceType)(nil)") - } - t = t.Elem() - return t, t.PkgPath() + "/" + t.Name() -} - -func typeInterfaceToStringOnly[T any]() string { - _, nane := typeInterfaceToString[T]() - return nane -} - -func guidOf[T any]() string { - vtable := vTableOf[T]() - if vtable == nil { - return "" - } - return vtable.ComGUID -} - -func vTableOf[T any]() *vTable { - name := typeInterfaceToStringOnly[T]() - vTablesL.Lock() - defer vTablesL.Unlock() - - return vTables[name] -} - -type ifceImpl interface { - impl() any - ifce() (*vTable, error) -} - -type ifceDef[T any] struct { - objImpl any -} - -func (i ifceDef[T]) impl() any { - return i.objImpl -} - -func (i ifceDef[T]) ifce() (*vTable, error) { - vtable := vTableOf[T]() - if vtable == nil { - return nil, fmt.Errorf("Unable to find vTable for %s", typeInterfaceToStringOnly[T]()) - } - return vtable, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_COLOR.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_COLOR.go deleted file mode 100644 index 429ecef2..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_COLOR.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_COLOR struct { - A uint8 - R uint8 - G uint8 - B uint8 -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND.go deleted file mode 100644 index ed106ed4..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND uint32 - -const ( - COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY = iota - COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_ALLOW - COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY_CORS -) diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_KEY_EVENT_KIND.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_KEY_EVENT_KIND.go deleted file mode 100644 index 60714753..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_KEY_EVENT_KIND.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_KEY_EVENT_KIND uint32 - -const ( - COREWEBVIEW2_KEY_EVENT_KIND_KEY_DOWN = 0 - COREWEBVIEW2_KEY_EVENT_KIND_KEY_UP = 1 - COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_DOWN = 2 - COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_UP = 3 -) diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_MOVE_FOCUS_REASON.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_MOVE_FOCUS_REASON.go deleted file mode 100644 index c1679cc3..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_MOVE_FOCUS_REASON.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_MOVE_FOCUS_REASON uint32 - -const ( - COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC = 0 - COREWEBVIEW2_MOVE_FOCUS_REASON_NEXT = 1 - COREWEBVIEW2_MOVE_FOCUS_REASON_PREVIOUS = 2 -) diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PHYSICAL_KEY_STATUS.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PHYSICAL_KEY_STATUS.go deleted file mode 100644 index dd883425..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PHYSICAL_KEY_STATUS.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_PHYSICAL_KEY_STATUS struct { - RepeatCount uint32 - ScanCode uint32 - IsExtendedKey bool - IsMenuKeyDown bool - WasKeyDown bool - IsKeyReleased bool -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PROCESS_FAILED_KIND.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PROCESS_FAILED_KIND.go deleted file mode 100644 index a7e9aa33..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_PROCESS_FAILED_KIND.go +++ /dev/null @@ -1,49 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_PROCESS_FAILED_KIND uint32 - -const ( - // Indicates that the browser process ended unexpectedly. The WebView - // automatically moves to the Closed state. The app has to recreate a new - // WebView to recover from this failure. - COREWEBVIEW2_PROCESS_FAILED_KIND_BROWSER_PROCESS_EXITED = 0 - - // Indicates that the main frame's render process ended unexpectedly. A new - // render process is created automatically and navigated to an error page. - // You can use the `Reload` method to try to reload the page that failed. - COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_EXITED = 1 - - // Indicates that the main frame's render process is unresponsive. - // - // Note that this does not seem to work right now. - // Does not fire for simple long running script case, the only related test - // SitePerProcessBrowserTest::NoCommitTimeoutForInvisibleWebContents is - // disabled. - COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_UNRESPONSIVE = 2 - - // Indicates that a frame-only render process ended unexpectedly. The process - // exit does not affect the top-level document, only a subset of the - // subframes within it. The content in these frames is replaced with an error - // page in the frame. - COREWEBVIEW2_PROCESS_FAILED_KIND_FRAME_RENDER_PROCESS_EXITED = 3 - - // Indicates that a utility process ended unexpectedly. - COREWEBVIEW2_PROCESS_FAILED_KIND_UTILITY_PROCESS_EXITED = 4 - - // Indicates that a sandbox helper process ended unexpectedly. - COREWEBVIEW2_PROCESS_FAILED_KIND_SANDBOX_HELPER_PROCESS_EXITED = 5 - - // Indicates that the GPU process ended unexpectedly. - COREWEBVIEW2_PROCESS_FAILED_KIND_GPU_PROCESS_EXITED = 6 - - // Indicates that a PPAPI plugin process ended unexpectedly. - COREWEBVIEW2_PROCESS_FAILED_KIND_PPAPI_PLUGIN_PROCESS_EXITED = 7 - - // Indicates that a PPAPI plugin broker process ended unexpectedly. - COREWEBVIEW2_PROCESS_FAILED_KIND_PPAPI_BROKER_PROCESS_EXITED = 8 - - // Indicates that a process of unspecified kind ended unexpectedly. - COREWEBVIEW2_PROCESS_FAILED_KIND_UNKNOWN_PROCESS_EXITED = 9 -) diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_WEB_RESOURCE_CONTEXT.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_WEB_RESOURCE_CONTEXT.go deleted file mode 100644 index 2e9261d0..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/COREWEBVIEW2_WEB_RESOURCE_CONTEXT.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build windows - -package edge - -type COREWEBVIEW2_WEB_RESOURCE_CONTEXT uint32 - -const ( - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL = 0 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_DOCUMENT = 1 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_STYLESHEET = 2 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_IMAGE = 3 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_MEDIA = 4 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_FONT = 5 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_SCRIPT = 6 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_XML_HTTP_REQUEST = 7 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_FETCH = 8 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_TEXT_TRACK = 9 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_EVENT_SOURCE = 10 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_WEBSOCKET = 11 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_MANIFEST = 12 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_SIGNED_EXCHANGE = 13 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_PING = 14 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_CSP_VIOLATION_REPORT = 15 - COREWEBVIEW2_WEB_RESOURCE_CONTEXT_OTHER = 16 -) diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventArgs.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventArgs.go deleted file mode 100644 index 2a3a9c82..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventArgs.go +++ /dev/null @@ -1,79 +0,0 @@ -//go:build windows - -package edge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2AcceleratorKeyPressedEventArgsVtbl struct { - _IUnknownVtbl - GetKeyEventKind ComProc - GetVirtualKey ComProc - GetKeyEventLParam ComProc - GetPhysicalKeyStatus ComProc - GetHandled ComProc - PutHandled ComProc -} - -type ICoreWebView2AcceleratorKeyPressedEventArgs struct { - vtbl *_ICoreWebView2AcceleratorKeyPressedEventArgsVtbl -} - -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetKeyEventKind() (COREWEBVIEW2_KEY_EVENT_KIND, error) { - var err error - var keyEventKind COREWEBVIEW2_KEY_EVENT_KIND - _, _, err = i.vtbl.GetKeyEventKind.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&keyEventKind)), - ) - if err != windows.ERROR_SUCCESS { - return 0, err - } - return keyEventKind, nil -} - -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetVirtualKey() (uint, error) { - var err error - var virtualKey uint - _, _, err = i.vtbl.GetVirtualKey.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&virtualKey)), - ) - if err != windows.ERROR_SUCCESS { - return 0, err - } - return virtualKey, nil -} - -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetPhysicalKeyStatus() (COREWEBVIEW2_PHYSICAL_KEY_STATUS, error) { - var err error - var physicalKeyStatus COREWEBVIEW2_PHYSICAL_KEY_STATUS - _, _, err = i.vtbl.GetPhysicalKeyStatus.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&physicalKeyStatus)), - ) - if err != windows.ERROR_SUCCESS { - return COREWEBVIEW2_PHYSICAL_KEY_STATUS{}, err - } - return physicalKeyStatus, nil -} - -func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) PutHandled(handled bool) error { - var err error - - _, _, err = i.vtbl.PutHandled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(handled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventHandler.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventHandler.go deleted file mode 100644 index 2c276560..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2AcceleratorKeyPressedEventHandler.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build windows - -package edge - -type _ICoreWebView2AcceleratorKeyPressedEventHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type ICoreWebView2AcceleratorKeyPressedEventHandler struct { - vtbl *_ICoreWebView2AcceleratorKeyPressedEventHandlerVtbl - impl _ICoreWebView2AcceleratorKeyPressedEventHandlerImpl -} - -func (i *ICoreWebView2AcceleratorKeyPressedEventHandler) AddRef() uintptr { - return i.AddRef() -} -func _ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownQueryInterface(this *ICoreWebView2AcceleratorKeyPressedEventHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownAddRef(this *ICoreWebView2AcceleratorKeyPressedEventHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownRelease(this *ICoreWebView2AcceleratorKeyPressedEventHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2AcceleratorKeyPressedEventHandlerInvoke(this *ICoreWebView2AcceleratorKeyPressedEventHandler, sender *ICoreWebView2Controller, args *ICoreWebView2AcceleratorKeyPressedEventArgs) uintptr { - return this.impl.AcceleratorKeyPressed(sender, args) -} - -type _ICoreWebView2AcceleratorKeyPressedEventHandlerImpl interface { - _IUnknownImpl - AcceleratorKeyPressed(sender *ICoreWebView2Controller, args *ICoreWebView2AcceleratorKeyPressedEventArgs) uintptr -} - -var _ICoreWebView2AcceleratorKeyPressedEventHandlerFn = _ICoreWebView2AcceleratorKeyPressedEventHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2AcceleratorKeyPressedEventHandlerInvoke), -} - -func newICoreWebView2AcceleratorKeyPressedEventHandler(impl _ICoreWebView2AcceleratorKeyPressedEventHandlerImpl) *ICoreWebView2AcceleratorKeyPressedEventHandler { - return &ICoreWebView2AcceleratorKeyPressedEventHandler{ - vtbl: &_ICoreWebView2AcceleratorKeyPressedEventHandlerFn, - impl: impl, - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller.go deleted file mode 100644 index c95a00ad..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller.go +++ /dev/null @@ -1,160 +0,0 @@ -//go:build windows - -package edge - -import ( - "math" - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32" - "golang.org/x/sys/windows" -) - -type _ICoreWebView2ControllerVtbl struct { - _IUnknownVtbl - GetIsVisible ComProc - PutIsVisible ComProc - GetBounds ComProc - PutBounds ComProc - GetZoomFactor ComProc - PutZoomFactor ComProc - AddZoomFactorChanged ComProc - RemoveZoomFactorChanged ComProc - SetBoundsAndZoomFactor ComProc - MoveFocus ComProc - AddMoveFocusRequested ComProc - RemoveMoveFocusRequested ComProc - AddGotFocus ComProc - RemoveGotFocus ComProc - AddLostFocus ComProc - RemoveLostFocus ComProc - AddAcceleratorKeyPressed ComProc - RemoveAcceleratorKeyPressed ComProc - GetParentWindow ComProc - PutParentWindow ComProc - NotifyParentWindowPositionChanged ComProc - Close ComProc - GetCoreWebView2 ComProc -} - -type ICoreWebView2Controller struct { - vtbl *_ICoreWebView2ControllerVtbl -} - -func (i *ICoreWebView2Controller) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2Controller) GetBounds() (*w32.Rect, error) { - var err error - var bounds w32.Rect - _, _, err = i.vtbl.GetBounds.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&bounds)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - return &bounds, nil -} - -func (i *ICoreWebView2Controller) PutBounds(bounds w32.Rect) error { - var err error - - _, _, err = i.vtbl.PutBounds.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&bounds)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Controller) MoveFocus(reason COREWEBVIEW2_MOVE_FOCUS_REASON) error { - var err error - - _, _, err = i.vtbl.MoveFocus.Call( - uintptr(unsafe.Pointer(i)), - uintptr(reason), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Controller) AddAcceleratorKeyPressed(eventHandler *ICoreWebView2AcceleratorKeyPressedEventHandler, token *_EventRegistrationToken) error { - var err error - _, _, err = i.vtbl.AddAcceleratorKeyPressed.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(eventHandler)), - uintptr(unsafe.Pointer(&token)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Controller) PutIsVisible(isVisible bool) error { - var err error - - _, _, err = i.vtbl.PutIsVisible.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isVisible)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Controller) GetICoreWebView2Controller2() *ICoreWebView2Controller2 { - - var result *ICoreWebView2Controller2 - - iidICoreWebView2Controller2 := NewGUID("{c979903e-d4ca-4228-92eb-47ee3fa96eab}") - i.vtbl.QueryInterface.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(iidICoreWebView2Controller2)), - uintptr(unsafe.Pointer(&result))) - - return result -} - -func (i *ICoreWebView2Controller) NotifyParentWindowPositionChanged() error { - var err error - _, _, err = i.vtbl.NotifyParentWindowPositionChanged.Call( - uintptr(unsafe.Pointer(i)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Controller) PutZoomFactor(zoomFactor float64) error { - var err error - _, _, err = i.vtbl.PutZoomFactor.Call( - uintptr(unsafe.Pointer(i)), - uintptr(math.Float64bits(zoomFactor)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Controller) GetZoomFactor() (float64, error) { - var err error - var zoomFactorUint64 uint64 - _, _, err = i.vtbl.GetZoomFactor.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&zoomFactorUint64)), - ) - if err != windows.ERROR_SUCCESS { - return 0.0, err - } - return math.Float64frombits(zoomFactorUint64), nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller2.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller2.go deleted file mode 100644 index eff315a9..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Controller2.go +++ /dev/null @@ -1,75 +0,0 @@ -//go:build windows - -package edge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2Controller2Vtbl struct { - _IUnknownVtbl - GetIsVisible ComProc - PutIsVisible ComProc - GetBounds ComProc - PutBounds ComProc - GetZoomFactor ComProc - PutZoomFactor ComProc - AddZoomFactorChanged ComProc - RemoveZoomFactorChanged ComProc - SetBoundsAndZoomFactor ComProc - MoveFocus ComProc - AddMoveFocusRequested ComProc - RemoveMoveFocusRequested ComProc - AddGotFocus ComProc - RemoveGotFocus ComProc - AddLostFocus ComProc - RemoveLostFocus ComProc - AddAcceleratorKeyPressed ComProc - RemoveAcceleratorKeyPressed ComProc - GetParentWindow ComProc - PutParentWindow ComProc - NotifyParentWindowPositionChanged ComProc - Close ComProc - GetCoreWebView2 ComProc - GetDefaultBackgroundColor ComProc - PutDefaultBackgroundColor ComProc -} - -type ICoreWebView2Controller2 struct { - vtbl *_ICoreWebView2Controller2Vtbl -} - -func (i *ICoreWebView2Controller2) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2Controller2) GetDefaultBackgroundColor() (*COREWEBVIEW2_COLOR, error) { - var err error - var backgroundColor *COREWEBVIEW2_COLOR - _, _, err = i.vtbl.GetDefaultBackgroundColor.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&backgroundColor)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - return backgroundColor, nil -} - -func (i *ICoreWebView2Controller2) PutDefaultBackgroundColor(backgroundColor COREWEBVIEW2_COLOR) error { - var err error - - // Cast to a uint32 as that's what the call is expecting - col := *(*uint32)(unsafe.Pointer(&backgroundColor)) - - _, _, err = i.vtbl.PutDefaultBackgroundColor.Call( - uintptr(unsafe.Pointer(i)), - uintptr(col), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2CreateCoreWebView2ControllerCompletedHandler.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2CreateCoreWebView2ControllerCompletedHandler.go deleted file mode 100644 index c0e4d13b..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2CreateCoreWebView2ControllerCompletedHandler.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build windows - -package edge - -type _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type iCoreWebView2CreateCoreWebView2ControllerCompletedHandler struct { - vtbl *_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl - impl _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerImpl -} - -func (i *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler) AddRef() uintptr { - return i.AddRef() -} -func _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownQueryInterface(this *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownAddRef(this *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownRelease(this *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerInvoke(this *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler, errorCode uintptr, createdController *ICoreWebView2Controller) uintptr { - return this.impl.CreateCoreWebView2ControllerCompleted(errorCode, createdController) -} - -type _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerImpl interface { - _IUnknownImpl - CreateCoreWebView2ControllerCompleted(errorCode uintptr, createdController *ICoreWebView2Controller) uintptr -} - -var _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerFn = _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerInvoke), -} - -func newICoreWebView2CreateCoreWebView2ControllerCompletedHandler(impl _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerImpl) *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler { - return &iCoreWebView2CreateCoreWebView2ControllerCompletedHandler{ - vtbl: &_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerFn, - impl: impl, - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpHeadersCollectionIterator.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpHeadersCollectionIterator.go deleted file mode 100644 index 0c9eacb4..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpHeadersCollectionIterator.go +++ /dev/null @@ -1,78 +0,0 @@ -//go:build windows - -package edge - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2HttpHeadersCollectionIteratorVtbl struct { - _IUnknownVtbl - GetCurrentHeader ComProc - GetHasCurrentHeader ComProc - MoveNext ComProc -} - -type ICoreWebView2HttpHeadersCollectionIterator struct { - vtbl *_ICoreWebView2HttpHeadersCollectionIteratorVtbl -} - -func (i *ICoreWebView2HttpHeadersCollectionIterator) Release() error { - return i.vtbl.CallRelease(unsafe.Pointer(i)) -} - -func (i *ICoreWebView2HttpHeadersCollectionIterator) HasCurrentHeader() (bool, error) { - var hasHeader int32 - res, _, err := i.vtbl.GetHasCurrentHeader.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&hasHeader)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - if windows.Handle(res) != windows.S_OK { - return false, syscall.Errno(res) - } - return hasHeader != 0, nil -} - -func (i *ICoreWebView2HttpHeadersCollectionIterator) GetCurrentHeader() (string, string, error) { - // Create *uint16 to hold result - var _name *uint16 - var _value *uint16 - res, _, err := i.vtbl.GetCurrentHeader.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&_name)), - uintptr(unsafe.Pointer(&_value)), - ) - if err != windows.ERROR_SUCCESS { - return "", "", err - } - if windows.Handle(res) != windows.S_OK { - return "", "", syscall.Errno(res) - } - // Get result and cleanup - name := windows.UTF16PtrToString(_name) - windows.CoTaskMemFree(unsafe.Pointer(_name)) - value := windows.UTF16PtrToString(_value) - windows.CoTaskMemFree(unsafe.Pointer(_value)) - return name, value, nil -} - -func (i *ICoreWebView2HttpHeadersCollectionIterator) MoveNext() (bool, error) { - var next int32 - res, _, err := i.vtbl.MoveNext.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&next)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - if windows.Handle(res) != windows.S_OK { - return false, syscall.Errno(res) - } - return next != 0, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpRequestHeaders.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpRequestHeaders.go deleted file mode 100644 index 5a147b29..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2HttpRequestHeaders.go +++ /dev/null @@ -1,101 +0,0 @@ -//go:build windows - -package edge - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -const ( - ERROR_ELEMENT_NOT_FOUND syscall.Errno = 0x80070490 -) - -type _ICoreWebView2HttpRequestHeadersVtbl struct { - _IUnknownVtbl - GetHeader ComProc - GetHeaders ComProc - Contains ComProc - SetHeader ComProc - RemoveHeader ComProc - GetIterator ComProc -} - -type ICoreWebView2HttpRequestHeaders struct { - vtbl *_ICoreWebView2HttpRequestHeadersVtbl -} - -func (i *ICoreWebView2HttpRequestHeaders) Release() error { - return i.vtbl.CallRelease(unsafe.Pointer(i)) -} - -// GetHeader returns the value of the specified header. If the header is not found -// ERROR_ELEMENT_NOT_FOUND is returned as error. -func (i *ICoreWebView2HttpRequestHeaders) GetHeader(name string) (string, error) { - _name, err := windows.UTF16PtrFromString(name) - if err != nil { - return "", nil - } - - var _value *uint16 - res, _, err := i.vtbl.GetHeader.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_name)), - uintptr(unsafe.Pointer(&_value)), - ) - if err != windows.ERROR_SUCCESS { - return "", err - } - if windows.Handle(res) != windows.S_OK { - return "", syscall.Errno(res) - } - - value := windows.UTF16PtrToString(_value) - windows.CoTaskMemFree(unsafe.Pointer(_value)) - return value, nil -} - -// SetHeader sets the specified header to the value. -func (i *ICoreWebView2HttpRequestHeaders) SetHeader(name, value string) error { - _name, err := windows.UTF16PtrFromString(name) - if err != nil { - return nil - } - - _value, err := windows.UTF16PtrFromString(value) - if err != nil { - return nil - } - - res, _, err := i.vtbl.SetHeader.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_name)), - uintptr(unsafe.Pointer(_value)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - if windows.Handle(res) != windows.S_OK { - return syscall.Errno(res) - } - return nil -} - -// GetIterator returns an iterator over the collection of request headers. Make sure to call -// Release on the returned Object after finished using it. -func (i *ICoreWebView2HttpRequestHeaders) GetIterator() (*ICoreWebView2HttpHeadersCollectionIterator, error) { - var headers *ICoreWebView2HttpHeadersCollectionIterator - res, _, err := i.vtbl.GetIterator.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&headers)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - if windows.Handle(res) != windows.S_OK { - return nil, syscall.Errno(res) - } - return headers, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventArgs.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventArgs.go deleted file mode 100644 index c3998e0a..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventArgs.go +++ /dev/null @@ -1,18 +0,0 @@ -//go:build windows - -package edge - -type _ICoreWebView2NavigationCompletedEventArgsVtbl struct { - _IUnknownVtbl - GetIsSuccess ComProc - GetWebErrorStatus ComProc - GetNavigationId ComProc -} - -type ICoreWebView2NavigationCompletedEventArgs struct { - vtbl *_ICoreWebView2NavigationCompletedEventArgsVtbl -} - -func (i *ICoreWebView2NavigationCompletedEventArgs) AddRef() uintptr { - return i.AddRef() -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventHandler.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventHandler.go deleted file mode 100644 index 456da507..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2NavigationCompletedEventHandler.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build windows - -package edge - -type _ICoreWebView2NavigationCompletedEventHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type ICoreWebView2NavigationCompletedEventHandler struct { - vtbl *_ICoreWebView2NavigationCompletedEventHandlerVtbl - impl _ICoreWebView2NavigationCompletedEventHandlerImpl -} - -func (i *ICoreWebView2NavigationCompletedEventHandler) AddRef() uintptr { - return i.AddRef() -} -func _ICoreWebView2NavigationCompletedEventHandlerIUnknownQueryInterface(this *ICoreWebView2NavigationCompletedEventHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2NavigationCompletedEventHandlerIUnknownAddRef(this *ICoreWebView2NavigationCompletedEventHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2NavigationCompletedEventHandlerIUnknownRelease(this *ICoreWebView2NavigationCompletedEventHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2NavigationCompletedEventHandlerInvoke(this *ICoreWebView2NavigationCompletedEventHandler, sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) uintptr { - return this.impl.NavigationCompleted(sender, args) -} - -type _ICoreWebView2NavigationCompletedEventHandlerImpl interface { - _IUnknownImpl - NavigationCompleted(sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) uintptr -} - -var _ICoreWebView2NavigationCompletedEventHandlerFn = _ICoreWebView2NavigationCompletedEventHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2NavigationCompletedEventHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2NavigationCompletedEventHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2NavigationCompletedEventHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2NavigationCompletedEventHandlerInvoke), -} - -func newICoreWebView2NavigationCompletedEventHandler(impl _ICoreWebView2NavigationCompletedEventHandlerImpl) *ICoreWebView2NavigationCompletedEventHandler { - return &ICoreWebView2NavigationCompletedEventHandler{ - vtbl: &_ICoreWebView2NavigationCompletedEventHandlerFn, - impl: impl, - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventArgs.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventArgs.go deleted file mode 100644 index b6d3cda1..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventArgs.go +++ /dev/null @@ -1,41 +0,0 @@ -//go:build windows - -package edge - -import ( - "fmt" - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2ProcessFailedEventArgsVtbl struct { - _IUnknownVtbl - GetProcessFailedKind ComProc -} - -type ICoreWebView2ProcessFailedEventArgs struct { - vtbl *_ICoreWebView2ProcessFailedEventArgsVtbl -} - -func (i *ICoreWebView2ProcessFailedEventArgs) GetProcessFailedKind() (COREWEBVIEW2_PROCESS_FAILED_KIND, error) { - kind := COREWEBVIEW2_PROCESS_FAILED_KIND(0xffffffff) - hr, _, err := i.vtbl.GetProcessFailedKind.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&kind)), - ) - - if windows.Handle(hr) != windows.S_OK { - return 0, syscall.Errno(hr) - } - - if kind == 0xffffffff { - if err == nil { - err = fmt.Errorf("unknown error") - } - return 0, err - } - - return kind, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventHandler.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventHandler.go deleted file mode 100644 index fc8c7369..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2ProcessFailedEventHandler.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build windows - -package edge - -type _ICoreWebView2ProcessFailedEventHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type ICoreWebView2ProcessFailedEventHandler struct { - vtbl *_ICoreWebView2ProcessFailedEventHandlerVtbl - impl _ICoreWebView2ProcessFailedEventHandlerImpl -} - -func (i *ICoreWebView2ProcessFailedEventHandler) AddRef() uintptr { - return i.AddRef() -} -func _ICoreWebView2ProcessFailedEventHandlerIUnknownQueryInterface(this *ICoreWebView2ProcessFailedEventHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2ProcessFailedEventHandlerIUnknownAddRef(this *ICoreWebView2ProcessFailedEventHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2ProcessFailedEventHandlerIUnknownRelease(this *ICoreWebView2ProcessFailedEventHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2ProcessFailedEventHandlerInvoke(this *ICoreWebView2ProcessFailedEventHandler, sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs) uintptr { - return this.impl.ProcessFailed(sender, args) -} - -type _ICoreWebView2ProcessFailedEventHandlerImpl interface { - _IUnknownImpl - ProcessFailed(sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs) uintptr -} - -var _ICoreWebView2ProcessFailedEventHandlerFn = _ICoreWebView2ProcessFailedEventHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2ProcessFailedEventHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2ProcessFailedEventHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2ProcessFailedEventHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2ProcessFailedEventHandlerInvoke), -} - -func newICoreWebView2ProcessFailedEventHandler(impl _ICoreWebView2ProcessFailedEventHandlerImpl) *ICoreWebView2ProcessFailedEventHandler { - return &ICoreWebView2ProcessFailedEventHandler{ - vtbl: &_ICoreWebView2ProcessFailedEventHandlerFn, - impl: impl, - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Settings.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Settings.go deleted file mode 100644 index a4ba613d..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2Settings.go +++ /dev/null @@ -1,271 +0,0 @@ -//go:build windows - -package edge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2SettingsVtbl struct { - _IUnknownVtbl - GetIsScriptEnabled ComProc - PutIsScriptEnabled ComProc - GetIsWebMessageEnabled ComProc - PutIsWebMessageEnabled ComProc - GetAreDefaultScriptDialogsEnabled ComProc - PutAreDefaultScriptDialogsEnabled ComProc - GetIsStatusBarEnabled ComProc - PutIsStatusBarEnabled ComProc - GetAreDevToolsEnabled ComProc - PutAreDevToolsEnabled ComProc - GetAreDefaultContextMenusEnabled ComProc - PutAreDefaultContextMenusEnabled ComProc - GetAreHostObjectsAllowed ComProc - PutAreHostObjectsAllowed ComProc - GetIsZoomControlEnabled ComProc - PutIsZoomControlEnabled ComProc - GetIsBuiltInErrorPageEnabled ComProc - PutIsBuiltInErrorPageEnabled ComProc -} - -type ICoreWebView2Settings struct { - vtbl *_ICoreWebView2SettingsVtbl -} - -func (i *ICoreWebView2Settings) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2Settings) GetIsScriptEnabled() (bool, error) { - var err error - var isScriptEnabled bool - _, _, err = i.vtbl.GetIsScriptEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isScriptEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return isScriptEnabled, nil -} - -func (i *ICoreWebView2Settings) PutIsScriptEnabled(isScriptEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsScriptEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isScriptEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetIsWebMessageEnabled() (bool, error) { - var err error - var isWebMessageEnabled bool - _, _, err = i.vtbl.GetIsWebMessageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isWebMessageEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return isWebMessageEnabled, nil -} - -func (i *ICoreWebView2Settings) PutIsWebMessageEnabled(isWebMessageEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsWebMessageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isWebMessageEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetAreDefaultScriptDialogsEnabled() (bool, error) { - var err error - var areDefaultScriptDialogsEnabled bool - _, _, err = i.vtbl.GetAreDefaultScriptDialogsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&areDefaultScriptDialogsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return areDefaultScriptDialogsEnabled, nil -} - -func (i *ICoreWebView2Settings) PutAreDefaultScriptDialogsEnabled(areDefaultScriptDialogsEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutAreDefaultScriptDialogsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(areDefaultScriptDialogsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetIsStatusBarEnabled() (bool, error) { - var err error - var isStatusBarEnabled bool - _, _, err = i.vtbl.GetIsStatusBarEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isStatusBarEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return isStatusBarEnabled, nil -} - -func (i *ICoreWebView2Settings) PutIsStatusBarEnabled(isStatusBarEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsStatusBarEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isStatusBarEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetAreDevToolsEnabled() (bool, error) { - var err error - var areDevToolsEnabled bool - _, _, err = i.vtbl.GetAreDevToolsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&areDevToolsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return areDevToolsEnabled, nil -} - -func (i *ICoreWebView2Settings) PutAreDevToolsEnabled(areDevToolsEnabled bool) error { - var err error - _, _, err = i.vtbl.PutAreDevToolsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(areDevToolsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetAreDefaultContextMenusEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetAreDefaultContextMenusEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebView2Settings) PutAreDefaultContextMenusEnabled(enabled bool) error { - var err error - _, _, err = i.vtbl.PutAreDefaultContextMenusEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetAreHostObjectsAllowed() (bool, error) { - var err error - var allowed bool - _, _, err = i.vtbl.GetAreHostObjectsAllowed.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&allowed)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return allowed, nil -} - -func (i *ICoreWebView2Settings) PutAreHostObjectsAllowed(allowed bool) error { - var err error - - _, _, err = i.vtbl.PutAreHostObjectsAllowed.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(allowed)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetIsZoomControlEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetIsZoomControlEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebView2Settings) PutIsZoomControlEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsZoomControlEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2Settings) GetIsBuiltInErrorPageEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetIsBuiltInErrorPageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebView2Settings) PutIsBuiltInErrorPageEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsBuiltInErrorPageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequest.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequest.go deleted file mode 100644 index fe7f2cfa..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequest.go +++ /dev/null @@ -1,102 +0,0 @@ -//go:build windows - -package edge - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2WebResourceRequestVtbl struct { - _IUnknownVtbl - GetUri ComProc - PutUri ComProc - GetMethod ComProc - PutMethod ComProc - GetContent ComProc - PutContent ComProc - GetHeaders ComProc -} - -type ICoreWebView2WebResourceRequest struct { - vtbl *_ICoreWebView2WebResourceRequestVtbl -} - -func (i *ICoreWebView2WebResourceRequest) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2WebResourceRequest) GetMethod() (string, error) { - // Create *uint16 to hold result - var _method *uint16 - res, _, err := i.vtbl.GetMethod.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&_method)), - ) - if err != windows.ERROR_SUCCESS { - return "", err - } - if windows.Handle(res) != windows.S_OK { - return "", syscall.Errno(res) - } - // Get result and cleanup - uri := windows.UTF16PtrToString(_method) - windows.CoTaskMemFree(unsafe.Pointer(_method)) - return uri, nil -} - -func (i *ICoreWebView2WebResourceRequest) GetUri() (string, error) { - var err error - // Create *uint16 to hold result - var _uri *uint16 - _, _, err = i.vtbl.GetUri.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&_uri)), - ) - if err != windows.ERROR_SUCCESS { - return "", err - } // Get result and cleanup - uri := windows.UTF16PtrToString(_uri) - windows.CoTaskMemFree(unsafe.Pointer(_uri)) - return uri, nil -} - -// GetContent returns the body of the request. Returns nil if there's no body. Make sure to call -// Release on the returned IStream after finished using it. -func (i *ICoreWebView2WebResourceRequest) GetContent() (*IStream, error) { - var stream *IStream - res, _, err := i.vtbl.GetContent.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&stream)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - if windows.Handle(res) != windows.S_OK { - return nil, syscall.Errno(res) - } - return stream, nil -} - -// GetHeaders returns the mutable HTTP request headers. Make sure to call -// Release on the returned Object after finished using it. -func (i *ICoreWebView2WebResourceRequest) GetHeaders() (*ICoreWebView2HttpRequestHeaders, error) { - var headers *ICoreWebView2HttpRequestHeaders - res, _, err := i.vtbl.GetHeaders.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&headers)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - if windows.Handle(res) != windows.S_OK { - return nil, syscall.Errno(res) - } - return headers, nil -} - -func (i *ICoreWebView2WebResourceRequest) Release() error { - return i.vtbl.CallRelease(unsafe.Pointer(i)) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventArgs.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventArgs.go deleted file mode 100644 index 614594e8..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventArgs.go +++ /dev/null @@ -1,52 +0,0 @@ -//go:build windows - -package edge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -type _ICoreWebView2WebResourceRequestedEventArgsVtbl struct { - _IUnknownVtbl - GetRequest ComProc - GetResponse ComProc - PutResponse ComProc - GetDeferral ComProc - GetResourceContext ComProc -} - -type ICoreWebView2WebResourceRequestedEventArgs struct { - vtbl *_ICoreWebView2WebResourceRequestedEventArgsVtbl -} - -func (i *ICoreWebView2WebResourceRequestedEventArgs) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2WebResourceRequestedEventArgs) PutResponse(response *ICoreWebView2WebResourceResponse) error { - var err error - - _, _, err = i.vtbl.PutResponse.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(response)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2WebResourceRequestedEventArgs) GetRequest() (*ICoreWebView2WebResourceRequest, error) { - var err error - var request *ICoreWebView2WebResourceRequest - _, _, err = i.vtbl.GetRequest.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&request)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - return request, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventHandler.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventHandler.go deleted file mode 100644 index d0860c3b..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceRequestedEventHandler.go +++ /dev/null @@ -1,50 +0,0 @@ -//go:build windows - -package edge - -type _ICoreWebView2WebResourceRequestedEventHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type iCoreWebView2WebResourceRequestedEventHandler struct { - vtbl *_ICoreWebView2WebResourceRequestedEventHandlerVtbl - impl _ICoreWebView2WebResourceRequestedEventHandlerImpl -} - -func _ICoreWebView2WebResourceRequestedEventHandlerIUnknownQueryInterface(this *iCoreWebView2WebResourceRequestedEventHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2WebResourceRequestedEventHandlerIUnknownAddRef(this *iCoreWebView2WebResourceRequestedEventHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2WebResourceRequestedEventHandlerIUnknownRelease(this *iCoreWebView2WebResourceRequestedEventHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2WebResourceRequestedEventHandlerInvoke(this *iCoreWebView2WebResourceRequestedEventHandler, sender *ICoreWebView2, args *ICoreWebView2WebResourceRequestedEventArgs) uintptr { - return this.impl.WebResourceRequested(sender, args) -} - -type _ICoreWebView2WebResourceRequestedEventHandlerImpl interface { - _IUnknownImpl - WebResourceRequested(sender *ICoreWebView2, args *ICoreWebView2WebResourceRequestedEventArgs) uintptr -} - -var _ICoreWebView2WebResourceRequestedEventHandlerFn = _ICoreWebView2WebResourceRequestedEventHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2WebResourceRequestedEventHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2WebResourceRequestedEventHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2WebResourceRequestedEventHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2WebResourceRequestedEventHandlerInvoke), -} - -func newICoreWebView2WebResourceRequestedEventHandler(impl _ICoreWebView2WebResourceRequestedEventHandlerImpl) *iCoreWebView2WebResourceRequestedEventHandler { - return &iCoreWebView2WebResourceRequestedEventHandler{ - vtbl: &_ICoreWebView2WebResourceRequestedEventHandlerFn, - impl: impl, - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceResponse.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceResponse.go deleted file mode 100644 index dd02e608..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2WebResourceResponse.go +++ /dev/null @@ -1,28 +0,0 @@ -//go:build windows - -package edge - -import "unsafe" - -type _ICoreWebView2WebResourceResponseVtbl struct { - _IUnknownVtbl - GetContent ComProc - PutContent ComProc - GetHeaders ComProc - GetStatusCode ComProc - PutStatusCode ComProc - GetReasonPhrase ComProc - PutReasonPhrase ComProc -} - -type ICoreWebView2WebResourceResponse struct { - vtbl *_ICoreWebView2WebResourceResponseVtbl -} - -func (i *ICoreWebView2WebResourceResponse) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebView2WebResourceResponse) Release() error { - return i.vtbl.CallRelease(unsafe.Pointer(i)) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_2.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_2.go deleted file mode 100644 index 85a4f71f..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_2.go +++ /dev/null @@ -1,18 +0,0 @@ -//go:build windows - -package edge - -type iCoreWebView2_2Vtbl struct { - iCoreWebView2Vtbl - AddWebResourceResponseReceived ComProc - RemoveWebResourceResponseReceived ComProc - NavigateWithWebResourceRequest ComProc - AddDomContentLoaded ComProc - RemoveDomContentLoaded ComProc - GetCookieManager ComProc - GetEnvironment ComProc -} - -type ICoreWebView2_2 struct { - vtbl *iCoreWebView2_2Vtbl -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_3.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_3.go deleted file mode 100644 index 58424bd6..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebView2_3.go +++ /dev/null @@ -1,62 +0,0 @@ -//go:build windows - -package edge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -type iCoreWebView2_3Vtbl struct { - iCoreWebView2_2Vtbl - TrySuspend ComProc - Resume ComProc - GetIsSuspended ComProc - SetVirtualHostNameToFolderMapping ComProc - ClearVirtualHostNameToFolderMapping ComProc -} - -type ICoreWebView2_3 struct { - vtbl *iCoreWebView2_3Vtbl -} - -func (i *ICoreWebView2_3) SetVirtualHostNameToFolderMapping(hostName, folderPath string, accessKind COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND) error { - _hostName, err := windows.UTF16PtrFromString(hostName) - if err != nil { - return err - } - - _folderPath, err := windows.UTF16PtrFromString(folderPath) - if err != nil { - return err - } - - _, _, err = i.vtbl.SetVirtualHostNameToFolderMapping.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_hostName)), - uintptr(unsafe.Pointer(_folderPath)), - uintptr(accessKind), - ) - if err != windows.ERROR_SUCCESS { - return err - } - - return nil -} - -func (i *ICoreWebView2) GetICoreWebView2_3() *ICoreWebView2_3 { - var result *ICoreWebView2_3 - - iidICoreWebView2_3 := NewGUID("{A0D6DF20-3B92-416D-AA0C-437A9C727857}") - _, _, _ = i.vtbl.QueryInterface.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(iidICoreWebView2_3)), - uintptr(unsafe.Pointer(&result))) - - return result -} - -func (e *Chromium) GetICoreWebView2_3() *ICoreWebView2_3 { - return e.webview.GetICoreWebView2_3() -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebViewSettings.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebViewSettings.go deleted file mode 100644 index 6c6b16d7..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/ICoreWebViewSettings.go +++ /dev/null @@ -1,397 +0,0 @@ -//go:build windows - -package edge - -import ( - "unsafe" - - "golang.org/x/sys/windows" -) - -// ICoreWebviewSettings is the merged settings class - -type _ICoreWebViewSettingsVtbl struct { - _IUnknownVtbl - GetIsScriptEnabled ComProc - PutIsScriptEnabled ComProc - GetIsWebMessageEnabled ComProc - PutIsWebMessageEnabled ComProc - GetAreDefaultScriptDialogsEnabled ComProc - PutAreDefaultScriptDialogsEnabled ComProc - GetIsStatusBarEnabled ComProc - PutIsStatusBarEnabled ComProc - GetAreDevToolsEnabled ComProc - PutAreDevToolsEnabled ComProc - GetAreDefaultContextMenusEnabled ComProc - PutAreDefaultContextMenusEnabled ComProc - GetAreHostObjectsAllowed ComProc - PutAreHostObjectsAllowed ComProc - GetIsZoomControlEnabled ComProc - PutIsZoomControlEnabled ComProc - GetIsBuiltInErrorPageEnabled ComProc - PutIsBuiltInErrorPageEnabled ComProc - GetUserAgent ComProc // ICoreWebView2Settings2: SDK 1.0.864.35 - PutUserAgent ComProc - GetAreBrowserAcceleratorKeysEnabled ComProc // ICoreWebView2Settings3: SDK 1.0.864.35 - PutAreBrowserAcceleratorKeysEnabled ComProc - GetIsPasswordAutosaveEnabled ComProc // ICoreWebView2Settings4: SDK 1.0.902.49 - PutIsPasswordAutosaveEnabled ComProc - GetIsGeneralAutofillEnabled ComProc - PutIsGeneralAutofillEnabled ComProc - GetIsPinchZoomEnabled ComProc // ICoreWebView2Settings5: SDK 1.0.902.49 - PutIsPinchZoomEnabled ComProc - GetIsSwipeNavigationEnabled ComProc // ICoreWebView2Settings6: SDK 1.0.992.28 - PutIsSwipeNavigationEnabled ComProc -} - -type ICoreWebViewSettings struct { - vtbl *_ICoreWebViewSettingsVtbl -} - -func (i *ICoreWebViewSettings) AddRef() uintptr { - return i.AddRef() -} - -func (i *ICoreWebViewSettings) GetIsScriptEnabled() (bool, error) { - var err error - var isScriptEnabled bool - _, _, err = i.vtbl.GetIsScriptEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isScriptEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return isScriptEnabled, nil -} - -func (i *ICoreWebViewSettings) PutIsScriptEnabled(isScriptEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsScriptEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isScriptEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetIsWebMessageEnabled() (bool, error) { - var err error - var isWebMessageEnabled bool - _, _, err = i.vtbl.GetIsWebMessageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isWebMessageEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return isWebMessageEnabled, nil -} - -func (i *ICoreWebViewSettings) PutIsWebMessageEnabled(isWebMessageEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsWebMessageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isWebMessageEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetAreDefaultScriptDialogsEnabled() (bool, error) { - var err error - var areDefaultScriptDialogsEnabled bool - _, _, err = i.vtbl.GetAreDefaultScriptDialogsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&areDefaultScriptDialogsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return areDefaultScriptDialogsEnabled, nil -} - -func (i *ICoreWebViewSettings) PutAreDefaultScriptDialogsEnabled(areDefaultScriptDialogsEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutAreDefaultScriptDialogsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(areDefaultScriptDialogsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetIsStatusBarEnabled() (bool, error) { - var err error - var isStatusBarEnabled bool - _, _, err = i.vtbl.GetIsStatusBarEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&isStatusBarEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return isStatusBarEnabled, nil -} - -func (i *ICoreWebViewSettings) PutIsStatusBarEnabled(isStatusBarEnabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsStatusBarEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(isStatusBarEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetAreDevToolsEnabled() (bool, error) { - var err error - var areDevToolsEnabled bool - _, _, err = i.vtbl.GetAreDevToolsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&areDevToolsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return areDevToolsEnabled, nil -} - -func (i *ICoreWebViewSettings) PutAreDevToolsEnabled(areDevToolsEnabled bool) error { - var err error - _, _, err = i.vtbl.PutAreDevToolsEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(areDevToolsEnabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetAreDefaultContextMenusEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetAreDefaultContextMenusEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebViewSettings) PutAreDefaultContextMenusEnabled(enabled bool) error { - var err error - _, _, err = i.vtbl.PutAreDefaultContextMenusEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetAreHostObjectsAllowed() (bool, error) { - var err error - var allowed bool - _, _, err = i.vtbl.GetAreHostObjectsAllowed.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&allowed)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return allowed, nil -} - -func (i *ICoreWebViewSettings) PutAreHostObjectsAllowed(allowed bool) error { - var err error - - _, _, err = i.vtbl.PutAreHostObjectsAllowed.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(allowed)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetIsZoomControlEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetIsZoomControlEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebViewSettings) PutIsZoomControlEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsZoomControlEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetIsBuiltInErrorPageEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetIsBuiltInErrorPageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebViewSettings) PutIsBuiltInErrorPageEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsBuiltInErrorPageEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetUserAgent() (string, error) { - var err error - // Create *uint16 to hold result - var _userAgent *uint16 - _, _, err = i.vtbl.GetUserAgent.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_userAgent)), - ) - if err != windows.ERROR_SUCCESS { - return "", err - } // Get result and cleanup - userAgent := windows.UTF16PtrToString(_userAgent) - windows.CoTaskMemFree(unsafe.Pointer(_userAgent)) - return userAgent, nil -} - -func (i *ICoreWebViewSettings) PutUserAgent(userAgent string) error { - var err error - // Convert string 'userAgent' to *uint16 - _userAgent, err := windows.UTF16PtrFromString(userAgent) - if err != nil { - return err - } - - _, _, err = i.vtbl.PutUserAgent.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_userAgent)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetAreBrowserAcceleratorKeysEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetAreBrowserAcceleratorKeysEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebViewSettings) PutAreBrowserAcceleratorKeysEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutAreBrowserAcceleratorKeysEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetIsPinchZoomEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetIsPinchZoomEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebViewSettings) PutIsPinchZoomEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsPinchZoomEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebViewSettings) GetIsSwipeNavigationEnabled() (bool, error) { - var err error - var enabled bool - _, _, err = i.vtbl.GetIsSwipeNavigationEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&enabled)), - ) - if err != windows.ERROR_SUCCESS { - return false, err - } - return enabled, nil -} - -func (i *ICoreWebViewSettings) PutIsSwipeNavigationEnabled(enabled bool) error { - var err error - - _, _, err = i.vtbl.PutIsSwipeNavigationEnabled.Call( - uintptr(unsafe.Pointer(i)), - uintptr(boolToInt(enabled)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/IStream.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/IStream.go deleted file mode 100644 index 9e29ca4f..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/IStream.go +++ /dev/null @@ -1,54 +0,0 @@ -//go:build windows - -package edge - -import ( - "io" - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -type _IStreamVtbl struct { - _IUnknownVtbl - Read ComProc - Write ComProc -} - -type IStream struct { - vtbl *_IStreamVtbl -} - -func (i *IStream) Release() error { - return i.vtbl.CallRelease(unsafe.Pointer(i)) -} - -func (i *IStream) Read(p []byte) (int, error) { - bufLen := len(p) - if bufLen == 0 { - return 0, nil - } - - var n int - res, _, err := i.vtbl.Read.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&p[0])), - uintptr(bufLen), - uintptr(unsafe.Pointer(&n)), - ) - if err != windows.ERROR_SUCCESS { - return 0, err - } - - switch windows.Handle(res) { - case windows.S_OK: - // The buffer has been completely filled - return n, nil - case windows.S_FALSE: - // The buffer has been filled with less than len data and the stream is EOF - return n, io.EOF - default: - return 0, syscall.Errno(res) - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium.go deleted file mode 100644 index 376891bb..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium.go +++ /dev/null @@ -1,419 +0,0 @@ -//go:build windows -// +build windows - -package edge - -import ( - "errors" - "log" - "os" - "path/filepath" - "strings" - "sync/atomic" - "syscall" - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32" - "golang.org/x/sys/windows" -) - -type Rect = w32.Rect - -type Chromium struct { - hwnd uintptr - controller *ICoreWebView2Controller - webview *ICoreWebView2 - inited uintptr - envCompleted *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler - controllerCompleted *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler - webMessageReceived *iCoreWebView2WebMessageReceivedEventHandler - permissionRequested *iCoreWebView2PermissionRequestedEventHandler - webResourceRequested *iCoreWebView2WebResourceRequestedEventHandler - acceleratorKeyPressed *ICoreWebView2AcceleratorKeyPressedEventHandler - navigationCompleted *ICoreWebView2NavigationCompletedEventHandler - processFailed *ICoreWebView2ProcessFailedEventHandler - - environment *ICoreWebView2Environment - - padding Rect - - // Settings - Debug bool - DataPath string - BrowserPath string - AdditionalBrowserArgs []string - - // permissions - permissions map[CoreWebView2PermissionKind]CoreWebView2PermissionState - globalPermission *CoreWebView2PermissionState - - // Callbacks - MessageCallback func(string) - WebResourceRequestedCallback func(request *ICoreWebView2WebResourceRequest, args *ICoreWebView2WebResourceRequestedEventArgs) - NavigationCompletedCallback func(sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) - ProcessFailedCallback func(sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs) - AcceleratorKeyCallback func(uint) bool -} - -func NewChromium() *Chromium { - e := &Chromium{} - /* - All these handlers are passed to native code through syscalls with 'uintptr(unsafe.Pointer(handler))' and we know - that a pointer to those will be kept in the native code. Furthermore these handlers als contain pointer to other Go - structs like the vtable. - This violates the unsafe.Pointer rule '(4) Conversion of a Pointer to a uintptr when calling syscall.Syscall.' because - theres no guarantee that Go doesn't move these objects. - AFAIK currently the Go runtime doesn't move HEAP objects, so we should be safe with these handlers. But they don't - guarantee it, because in the future Go might use a compacting GC. - There's a proposal to add a runtime.Pin function, to prevent moving pinned objects, which would allow to easily fix - this issue by just pinning the handlers. The https://go-review.googlesource.com/c/go/+/367296/ should land in Go 1.19. - */ - e.envCompleted = newICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler(e) - e.controllerCompleted = newICoreWebView2CreateCoreWebView2ControllerCompletedHandler(e) - e.webMessageReceived = newICoreWebView2WebMessageReceivedEventHandler(e) - e.permissionRequested = newICoreWebView2PermissionRequestedEventHandler(e) - e.webResourceRequested = newICoreWebView2WebResourceRequestedEventHandler(e) - e.acceleratorKeyPressed = newICoreWebView2AcceleratorKeyPressedEventHandler(e) - e.navigationCompleted = newICoreWebView2NavigationCompletedEventHandler(e) - e.processFailed = newICoreWebView2ProcessFailedEventHandler(e) - e.permissions = make(map[CoreWebView2PermissionKind]CoreWebView2PermissionState) - - return e -} - -func (e *Chromium) Embed(hwnd uintptr) bool { - e.hwnd = hwnd - - dataPath := e.DataPath - if dataPath == "" { - currentExePath := make([]uint16, windows.MAX_PATH) - _, err := windows.GetModuleFileName(windows.Handle(0), ¤tExePath[0], windows.MAX_PATH) - if err != nil { - // What to do here? - return false - } - currentExeName := filepath.Base(windows.UTF16ToString(currentExePath)) - dataPath = filepath.Join(os.Getenv("AppData"), currentExeName) - } - - if e.BrowserPath != "" { - if _, err := os.Stat(e.BrowserPath); errors.Is(err, os.ErrNotExist) { - log.Printf("Browser path %s does not exist", e.BrowserPath) - return false - } - } - - browserArgs := strings.Join(e.AdditionalBrowserArgs, " ") - if err := createCoreWebView2EnvironmentWithOptions(e.BrowserPath, dataPath, e.envCompleted, browserArgs); err != nil { - log.Printf("Error calling Webview2Loader: %v", err) - return false - } - - var msg w32.Msg - for { - if atomic.LoadUintptr(&e.inited) != 0 { - break - } - r, _, _ := w32.User32GetMessageW.Call( - uintptr(unsafe.Pointer(&msg)), - 0, - 0, - 0, - ) - if r == 0 { - break - } - w32.User32TranslateMessage.Call(uintptr(unsafe.Pointer(&msg))) - w32.User32DispatchMessageW.Call(uintptr(unsafe.Pointer(&msg))) - } - e.Init("window.external={invoke:s=>window.chrome.webview.postMessage(s)}") - return true -} - -func (e *Chromium) SetPadding(padding Rect) { - if e.padding.Top == padding.Top && e.padding.Bottom == padding.Bottom && - e.padding.Left == padding.Left && e.padding.Right == padding.Right { - - return - } - - e.padding = padding - e.Resize() -} - -func (e *Chromium) Resize() { - if e.hwnd == 0 { - return - } - - var bounds w32.Rect - w32.User32GetClientRect.Call(e.hwnd, uintptr(unsafe.Pointer(&bounds))) - - bounds.Top += e.padding.Top - bounds.Bottom -= e.padding.Bottom - bounds.Left += e.padding.Left - bounds.Right -= e.padding.Right - - e.SetSize(bounds) -} - -func (e *Chromium) Navigate(url string) { - e.webview.vtbl.Navigate.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(url))), - ) -} - -func (e *Chromium) Init(script string) { - e.webview.vtbl.AddScriptToExecuteOnDocumentCreated.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(script))), - 0, - ) -} - -func (e *Chromium) Eval(script string) { - - _script, err := windows.UTF16PtrFromString(script) - if err != nil { - log.Fatal(err) - } - - e.webview.vtbl.ExecuteScript.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(_script)), - 0, - ) -} - -func (e *Chromium) Show() error { - return e.controller.PutIsVisible(true) -} - -func (e *Chromium) Hide() error { - return e.controller.PutIsVisible(false) -} - -func (e *Chromium) QueryInterface(_, _ uintptr) uintptr { - return 0 -} - -func (e *Chromium) AddRef() uintptr { - return 1 -} - -func (e *Chromium) Release() uintptr { - return 1 -} - -func (e *Chromium) EnvironmentCompleted(res uintptr, env *ICoreWebView2Environment) uintptr { - if int32(res) < 0 { - log.Fatalf("Creating environment failed with %08x: %s", res, syscall.Errno(res)) - } - env.vtbl.AddRef.Call(uintptr(unsafe.Pointer(env))) - e.environment = env - - env.vtbl.CreateCoreWebView2Controller.Call( - uintptr(unsafe.Pointer(env)), - e.hwnd, - uintptr(unsafe.Pointer(e.controllerCompleted)), - ) - return 0 -} - -func (e *Chromium) CreateCoreWebView2ControllerCompleted(res uintptr, controller *ICoreWebView2Controller) uintptr { - if int32(res) < 0 { - log.Fatalf("Creating controller failed with %08x: %s", res, syscall.Errno(res)) - } - controller.vtbl.AddRef.Call(uintptr(unsafe.Pointer(controller))) - e.controller = controller - - var token _EventRegistrationToken - controller.vtbl.GetCoreWebView2.Call( - uintptr(unsafe.Pointer(controller)), - uintptr(unsafe.Pointer(&e.webview)), - ) - e.webview.vtbl.AddRef.Call( - uintptr(unsafe.Pointer(e.webview)), - ) - e.webview.vtbl.AddWebMessageReceived.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(e.webMessageReceived)), - uintptr(unsafe.Pointer(&token)), - ) - e.webview.vtbl.AddPermissionRequested.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(e.permissionRequested)), - uintptr(unsafe.Pointer(&token)), - ) - e.webview.vtbl.AddWebResourceRequested.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(e.webResourceRequested)), - uintptr(unsafe.Pointer(&token)), - ) - e.webview.vtbl.AddNavigationCompleted.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(e.navigationCompleted)), - uintptr(unsafe.Pointer(&token)), - ) - e.webview.vtbl.AddProcessFailed.Call( - uintptr(unsafe.Pointer(e.webview)), - uintptr(unsafe.Pointer(e.processFailed)), - uintptr(unsafe.Pointer(&token)), - ) - - e.controller.AddAcceleratorKeyPressed(e.acceleratorKeyPressed, &token) - - atomic.StoreUintptr(&e.inited, 1) - - return 0 -} - -func (e *Chromium) MessageReceived(sender *ICoreWebView2, args *iCoreWebView2WebMessageReceivedEventArgs) uintptr { - var message *uint16 - args.vtbl.TryGetWebMessageAsString.Call( - uintptr(unsafe.Pointer(args)), - uintptr(unsafe.Pointer(&message)), - ) - if e.MessageCallback != nil { - e.MessageCallback(w32.Utf16PtrToString(message)) - } - sender.vtbl.PostWebMessageAsString.Call( - uintptr(unsafe.Pointer(sender)), - uintptr(unsafe.Pointer(message)), - ) - windows.CoTaskMemFree(unsafe.Pointer(message)) - return 0 -} - -func (e *Chromium) SetPermission(kind CoreWebView2PermissionKind, state CoreWebView2PermissionState) { - e.permissions[kind] = state -} - -func (e *Chromium) SetGlobalPermission(state CoreWebView2PermissionState) { - e.globalPermission = &state -} - -func (e *Chromium) PermissionRequested(_ *ICoreWebView2, args *iCoreWebView2PermissionRequestedEventArgs) uintptr { - var kind CoreWebView2PermissionKind - args.vtbl.GetPermissionKind.Call( - uintptr(unsafe.Pointer(args)), - uintptr(kind), - ) - var result CoreWebView2PermissionState - if e.globalPermission != nil { - result = *e.globalPermission - } else { - var ok bool - result, ok = e.permissions[kind] - if !ok { - result = CoreWebView2PermissionStateDefault - } - } - args.vtbl.PutState.Call( - uintptr(unsafe.Pointer(args)), - uintptr(result), - ) - return 0 -} - -func (e *Chromium) WebResourceRequested(sender *ICoreWebView2, args *ICoreWebView2WebResourceRequestedEventArgs) uintptr { - req, err := args.GetRequest() - if err != nil { - log.Fatal(err) - } - defer req.Release() - - if e.WebResourceRequestedCallback != nil { - e.WebResourceRequestedCallback(req, args) - } - return 0 -} - -func (e *Chromium) AddWebResourceRequestedFilter(filter string, ctx COREWEBVIEW2_WEB_RESOURCE_CONTEXT) { - err := e.webview.AddWebResourceRequestedFilter(filter, ctx) - if err != nil { - log.Fatal(err) - } -} - -func (e *Chromium) Environment() *ICoreWebView2Environment { - return e.environment -} - -// AcceleratorKeyPressed is called when an accelerator key is pressed. -// If the AcceleratorKeyCallback method has been set, it will defer handling of the keypress -// to the callback. That callback returns a bool indicating if the event was handled. -func (e *Chromium) AcceleratorKeyPressed(sender *ICoreWebView2Controller, args *ICoreWebView2AcceleratorKeyPressedEventArgs) uintptr { - if e.AcceleratorKeyCallback == nil { - return 0 - } - eventKind, _ := args.GetKeyEventKind() - if eventKind == COREWEBVIEW2_KEY_EVENT_KIND_KEY_DOWN || - eventKind == COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_DOWN { - virtualKey, _ := args.GetVirtualKey() - status, _ := args.GetPhysicalKeyStatus() - if !status.WasKeyDown { - args.PutHandled(e.AcceleratorKeyCallback(virtualKey)) - return 0 - } - } - args.PutHandled(false) - return 0 -} - -func (e *Chromium) GetSettings() (*ICoreWebViewSettings, error) { - return e.webview.GetSettings() -} - -func (e *Chromium) GetController() *ICoreWebView2Controller { - return e.controller -} - -func boolToInt(input bool) int { - if input { - return 1 - } - return 0 -} - -func (e *Chromium) NavigationCompleted(sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) uintptr { - if e.NavigationCompletedCallback != nil { - e.NavigationCompletedCallback(sender, args) - } - return 0 -} - -func (e *Chromium) ProcessFailed(sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs) uintptr { - if e.ProcessFailedCallback != nil { - e.ProcessFailedCallback(sender, args) - } - return 0 -} - -func (e *Chromium) NotifyParentWindowPositionChanged() error { - //It looks like the wndproc function is called before the controller initialization is complete. - //Because of this the controller is nil - if e.controller == nil { - return nil - } - return e.controller.NotifyParentWindowPositionChanged() -} - -func (e *Chromium) Focus() { - err := e.controller.MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC) - if err != nil { - log.Fatal(err) - } -} - -func (e *Chromium) PutZoomFactor(zoomFactor float64) { - err := e.controller.PutZoomFactor(zoomFactor) - if err != nil { - log.Fatal(err) - } -} - -func (e *Chromium) OpenDevToolsWindow() { - e.webview.OpenDevToolsWindow() -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_386.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_386.go deleted file mode 100644 index 00f6f42f..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_386.go +++ /dev/null @@ -1,23 +0,0 @@ -//go:build windows -// +build windows - -package edge - -import ( - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32" - "unsafe" -) - -func (e *Chromium) SetSize(bounds w32.Rect) { - if e.controller == nil { - return - } - - e.controller.vtbl.PutBounds.Call( - uintptr(unsafe.Pointer(e.controller)), - uintptr(bounds.Left), - uintptr(bounds.Top), - uintptr(bounds.Right), - uintptr(bounds.Bottom), - ) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_amd64.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_amd64.go deleted file mode 100644 index 858b93f1..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_amd64.go +++ /dev/null @@ -1,20 +0,0 @@ -//go:build windows -// +build windows - -package edge - -import ( - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32" - "unsafe" -) - -func (e *Chromium) SetSize(bounds w32.Rect) { - if e.controller == nil { - return - } - - e.controller.vtbl.PutBounds.Call( - uintptr(unsafe.Pointer(e.controller)), - uintptr(unsafe.Pointer(&bounds)), - ) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_arm64.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_arm64.go deleted file mode 100644 index b237792e..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/chromium_arm64.go +++ /dev/null @@ -1,23 +0,0 @@ -//go:build windows -// +build windows - -package edge - -import ( - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32" -) - -func (e *Chromium) SetSize(bounds w32.Rect) { - if e.controller == nil { - return - } - - words := (*[2]uintptr)(unsafe.Pointer(&bounds)) - e.controller.vtbl.PutBounds.Call( - uintptr(unsafe.Pointer(e.controller)), - words[0], - words[1], - ) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/corewebview2.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/corewebview2.go deleted file mode 100644 index 6f1afbd8..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/corewebview2.go +++ /dev/null @@ -1,503 +0,0 @@ -//go:build windows -// +build windows - -package edge - -import ( - "fmt" - "log" - "runtime" - "syscall" - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32" - - "golang.org/x/sys/windows" -) - -func init() { - runtime.LockOSThread() - - r, _, _ := w32.Ole32CoInitializeEx.Call(0, 2) - if int(r) < 0 { - log.Printf("Warning: CoInitializeEx call failed: E=%08x", r) - } -} - -type _EventRegistrationToken struct { - value int64 -} - -type CoreWebView2PermissionKind uint32 - -const ( - CoreWebView2PermissionKindUnknownPermission CoreWebView2PermissionKind = iota - CoreWebView2PermissionKindMicrophone - CoreWebView2PermissionKindCamera - CoreWebView2PermissionKindGeolocation - CoreWebView2PermissionKindNotifications - CoreWebView2PermissionKindOtherSensors - CoreWebView2PermissionKindClipboardRead -) - -type CoreWebView2PermissionState uint32 - -const ( - CoreWebView2PermissionStateDefault CoreWebView2PermissionState = iota - CoreWebView2PermissionStateAllow - CoreWebView2PermissionStateDeny -) - -// ComProc stores a COM procedure. -type ComProc uintptr - -// NewComProc creates a new COM proc from a Go function. -func NewComProc(fn interface{}) ComProc { - return ComProc(windows.NewCallback(fn)) -} - -// Call calls a COM procedure. -// -//go:uintptrescapes -func (p ComProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { - // The magic uintptrescapes comment is needed to prevent moving uintptr(unsafe.Pointer(p)) so calls to .Call() also - // satisfy the unsafe.Pointer rule "(4) Conversion of a Pointer to a uintptr when calling syscall.Syscall." - // Otherwise it might be that pointers get moved, especially pointer onto the Go stack which might grow dynamically. - // See https://pkg.go.dev/unsafe#Pointer and https://github.com/golang/go/issues/34474 - switch len(a) { - case 0: - return syscall.Syscall(uintptr(p), 0, 0, 0, 0) - case 1: - return syscall.Syscall(uintptr(p), 1, a[0], 0, 0) - case 2: - return syscall.Syscall(uintptr(p), 2, a[0], a[1], 0) - case 3: - return syscall.Syscall(uintptr(p), 3, a[0], a[1], a[2]) - case 4: - return syscall.Syscall6(uintptr(p), 4, a[0], a[1], a[2], a[3], 0, 0) - case 5: - return syscall.Syscall6(uintptr(p), 5, a[0], a[1], a[2], a[3], a[4], 0) - case 6: - return syscall.Syscall6(uintptr(p), 6, a[0], a[1], a[2], a[3], a[4], a[5]) - case 7: - return syscall.Syscall9(uintptr(p), 7, a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0) - case 8: - return syscall.Syscall9(uintptr(p), 8, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0) - case 9: - return syscall.Syscall9(uintptr(p), 9, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]) - case 10: - return syscall.Syscall12(uintptr(p), 10, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0) - case 11: - return syscall.Syscall12(uintptr(p), 11, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0) - case 12: - return syscall.Syscall12(uintptr(p), 12, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]) - case 13: - return syscall.Syscall15(uintptr(p), 13, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0) - case 14: - return syscall.Syscall15(uintptr(p), 14, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0) - case 15: - return syscall.Syscall15(uintptr(p), 15, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14]) - default: - panic("too many arguments") - } -} - -// IUnknown - -type _IUnknownVtbl struct { - QueryInterface ComProc - AddRef ComProc - Release ComProc -} - -func (i *_IUnknownVtbl) CallRelease(this unsafe.Pointer) error { - _, _, err := i.Release.Call( - uintptr(this), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -type _IUnknownImpl interface { - QueryInterface(refiid, object uintptr) uintptr - AddRef() uintptr - Release() uintptr -} - -// ICoreWebView2 - -type iCoreWebView2Vtbl struct { - _IUnknownVtbl - GetSettings ComProc - GetSource ComProc - Navigate ComProc - NavigateToString ComProc - AddNavigationStarting ComProc - RemoveNavigationStarting ComProc - AddContentLoading ComProc - RemoveContentLoading ComProc - AddSourceChanged ComProc - RemoveSourceChanged ComProc - AddHistoryChanged ComProc - RemoveHistoryChanged ComProc - AddNavigationCompleted ComProc - RemoveNavigationCompleted ComProc - AddFrameNavigationStarting ComProc - RemoveFrameNavigationStarting ComProc - AddFrameNavigationCompleted ComProc - RemoveFrameNavigationCompleted ComProc - AddScriptDialogOpening ComProc - RemoveScriptDialogOpening ComProc - AddPermissionRequested ComProc - RemovePermissionRequested ComProc - AddProcessFailed ComProc - RemoveProcessFailed ComProc - AddScriptToExecuteOnDocumentCreated ComProc - RemoveScriptToExecuteOnDocumentCreated ComProc - ExecuteScript ComProc - CapturePreview ComProc - Reload ComProc - PostWebMessageAsJSON ComProc - PostWebMessageAsString ComProc - AddWebMessageReceived ComProc - RemoveWebMessageReceived ComProc - CallDevToolsProtocolMethod ComProc - GetBrowserProcessID ComProc - GetCanGoBack ComProc - GetCanGoForward ComProc - GoBack ComProc - GoForward ComProc - GetDevToolsProtocolEventReceiver ComProc - Stop ComProc - AddNewWindowRequested ComProc - RemoveNewWindowRequested ComProc - AddDocumentTitleChanged ComProc - RemoveDocumentTitleChanged ComProc - GetDocumentTitle ComProc - AddHostObjectToScript ComProc - RemoveHostObjectFromScript ComProc - OpenDevToolsWindow ComProc - AddContainsFullScreenElementChanged ComProc - RemoveContainsFullScreenElementChanged ComProc - GetContainsFullScreenElement ComProc - AddWebResourceRequested ComProc - RemoveWebResourceRequested ComProc - AddWebResourceRequestedFilter ComProc - RemoveWebResourceRequestedFilter ComProc - AddWindowCloseRequested ComProc - RemoveWindowCloseRequested ComProc -} - -type ICoreWebView2 struct { - vtbl *iCoreWebView2Vtbl -} - -func (i *ICoreWebView2) GetSettings() (*ICoreWebViewSettings, error) { - var err error - var settings *ICoreWebViewSettings - _, _, err = i.vtbl.GetSettings.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(&settings)), - ) - if err != windows.ERROR_SUCCESS { - return nil, err - } - return settings, nil -} - -// ICoreWebView2Environment - -type iCoreWebView2EnvironmentVtbl struct { - _IUnknownVtbl - CreateCoreWebView2Controller ComProc - CreateWebResourceResponse ComProc - GetBrowserVersionString ComProc - AddNewBrowserVersionAvailable ComProc - RemoveNewBrowserVersionAvailable ComProc -} - -type ICoreWebView2Environment struct { - vtbl *iCoreWebView2EnvironmentVtbl -} - -// CreateWebResourceResponse creates a new ICoreWebView2WebResourceResponse, it must be released after finishing using it. -func (e *ICoreWebView2Environment) CreateWebResourceResponse(content []byte, statusCode int, reasonPhrase string, headers string) (*ICoreWebView2WebResourceResponse, error) { - var err error - var stream uintptr - - if len(content) > 0 { - // Create stream for response - stream, err = w32.SHCreateMemStream(content) - if err != nil { - return nil, err - } - - // Release the IStream after we are finished, CreateWebResourceResponse Call will increase the reference - // count on IStream and therefore it won't be freed until the reference count of the response is 0. - defer (*IStream)(unsafe.Pointer(stream)).Release() - } - - // Convert string 'uri' to *uint16 - _reason, err := windows.UTF16PtrFromString(reasonPhrase) - if err != nil { - return nil, err - } - // Convert string 'uri' to *uint16 - _headers, err := windows.UTF16PtrFromString(headers) - if err != nil { - return nil, err - } - var response *ICoreWebView2WebResourceResponse - hr, _, err := e.vtbl.CreateWebResourceResponse.Call( - uintptr(unsafe.Pointer(e)), - stream, - uintptr(statusCode), - uintptr(unsafe.Pointer(_reason)), - uintptr(unsafe.Pointer(_headers)), - uintptr(unsafe.Pointer(&response)), - ) - if windows.Handle(hr) != windows.S_OK { - return nil, syscall.Errno(hr) - } - - if response == nil { - if err == nil { - err = fmt.Errorf("unknown error") - } - return nil, err - } - return response, nil - -} - -// ICoreWebView2WebMessageReceivedEventArgs - -type iCoreWebView2WebMessageReceivedEventArgsVtbl struct { - _IUnknownVtbl - GetSource ComProc - GetWebMessageAsJSON ComProc - TryGetWebMessageAsString ComProc -} - -type iCoreWebView2WebMessageReceivedEventArgs struct { - vtbl *iCoreWebView2WebMessageReceivedEventArgsVtbl -} - -// ICoreWebView2PermissionRequestedEventArgs - -type iCoreWebView2PermissionRequestedEventArgsVtbl struct { - _IUnknownVtbl - GetURI ComProc - GetPermissionKind ComProc - GetIsUserInitiated ComProc - GetState ComProc - PutState ComProc - GetDeferral ComProc -} - -type iCoreWebView2PermissionRequestedEventArgs struct { - vtbl *iCoreWebView2PermissionRequestedEventArgsVtbl -} - -// ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler - -type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerImpl interface { - _IUnknownImpl - EnvironmentCompleted(res uintptr, env *ICoreWebView2Environment) uintptr -} - -type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler struct { - vtbl *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl - impl iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerImpl -} - -func _ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownQueryInterface(this *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownAddRef(this *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownRelease(this *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke(this *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, res uintptr, env *ICoreWebView2Environment) uintptr { - return this.impl.EnvironmentCompleted(res, env) -} - -var iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerFn = iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke), -} - -func newICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler(impl iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerImpl) *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler { - return &iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler{ - vtbl: &iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerFn, - impl: impl, - } -} - -// ICoreWebView2WebMessageReceivedEventHandler - -type iCoreWebView2WebMessageReceivedEventHandlerImpl interface { - _IUnknownImpl - MessageReceived(sender *ICoreWebView2, args *iCoreWebView2WebMessageReceivedEventArgs) uintptr -} - -type iCoreWebView2WebMessageReceivedEventHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type iCoreWebView2WebMessageReceivedEventHandler struct { - vtbl *iCoreWebView2WebMessageReceivedEventHandlerVtbl - impl iCoreWebView2WebMessageReceivedEventHandlerImpl -} - -func _ICoreWebView2WebMessageReceivedEventHandlerIUnknownQueryInterface(this *iCoreWebView2WebMessageReceivedEventHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2WebMessageReceivedEventHandlerIUnknownAddRef(this *iCoreWebView2WebMessageReceivedEventHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2WebMessageReceivedEventHandlerIUnknownRelease(this *iCoreWebView2WebMessageReceivedEventHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2WebMessageReceivedEventHandlerInvoke(this *iCoreWebView2WebMessageReceivedEventHandler, sender *ICoreWebView2, args *iCoreWebView2WebMessageReceivedEventArgs) uintptr { - return this.impl.MessageReceived(sender, args) -} - -var iCoreWebView2WebMessageReceivedEventHandlerFn = iCoreWebView2WebMessageReceivedEventHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2WebMessageReceivedEventHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2WebMessageReceivedEventHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2WebMessageReceivedEventHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2WebMessageReceivedEventHandlerInvoke), -} - -func newICoreWebView2WebMessageReceivedEventHandler(impl iCoreWebView2WebMessageReceivedEventHandlerImpl) *iCoreWebView2WebMessageReceivedEventHandler { - return &iCoreWebView2WebMessageReceivedEventHandler{ - vtbl: &iCoreWebView2WebMessageReceivedEventHandlerFn, - impl: impl, - } -} - -// ICoreWebView2PermissionRequestedEventHandler - -type iCoreWebView2PermissionRequestedEventHandlerImpl interface { - _IUnknownImpl - PermissionRequested(sender *ICoreWebView2, args *iCoreWebView2PermissionRequestedEventArgs) uintptr -} - -type iCoreWebView2PermissionRequestedEventHandlerVtbl struct { - _IUnknownVtbl - Invoke ComProc -} - -type iCoreWebView2PermissionRequestedEventHandler struct { - vtbl *iCoreWebView2PermissionRequestedEventHandlerVtbl - impl iCoreWebView2PermissionRequestedEventHandlerImpl -} - -func _ICoreWebView2PermissionRequestedEventHandlerIUnknownQueryInterface(this *iCoreWebView2PermissionRequestedEventHandler, refiid, object uintptr) uintptr { - return this.impl.QueryInterface(refiid, object) -} - -func _ICoreWebView2PermissionRequestedEventHandlerIUnknownAddRef(this *iCoreWebView2PermissionRequestedEventHandler) uintptr { - return this.impl.AddRef() -} - -func _ICoreWebView2PermissionRequestedEventHandlerIUnknownRelease(this *iCoreWebView2PermissionRequestedEventHandler) uintptr { - return this.impl.Release() -} - -func _ICoreWebView2PermissionRequestedEventHandlerInvoke(this *iCoreWebView2PermissionRequestedEventHandler, sender *ICoreWebView2, args *iCoreWebView2PermissionRequestedEventArgs) uintptr { - return this.impl.PermissionRequested(sender, args) -} - -var iCoreWebView2PermissionRequestedEventHandlerFn = iCoreWebView2PermissionRequestedEventHandlerVtbl{ - _IUnknownVtbl{ - NewComProc(_ICoreWebView2PermissionRequestedEventHandlerIUnknownQueryInterface), - NewComProc(_ICoreWebView2PermissionRequestedEventHandlerIUnknownAddRef), - NewComProc(_ICoreWebView2PermissionRequestedEventHandlerIUnknownRelease), - }, - NewComProc(_ICoreWebView2PermissionRequestedEventHandlerInvoke), -} - -func newICoreWebView2PermissionRequestedEventHandler(impl iCoreWebView2PermissionRequestedEventHandlerImpl) *iCoreWebView2PermissionRequestedEventHandler { - return &iCoreWebView2PermissionRequestedEventHandler{ - vtbl: &iCoreWebView2PermissionRequestedEventHandlerFn, - impl: impl, - } -} - -func (i *ICoreWebView2) AddWebResourceRequestedFilter(uri string, resourceContext COREWEBVIEW2_WEB_RESOURCE_CONTEXT) error { - var err error - // Convert string 'uri' to *uint16 - _uri, err := windows.UTF16PtrFromString(uri) - if err != nil { - return err - } - _, _, err = i.vtbl.AddWebResourceRequestedFilter.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(_uri)), - uintptr(resourceContext), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} -func (i *ICoreWebView2) AddNavigationCompleted(eventHandler *ICoreWebView2NavigationCompletedEventHandler, token *_EventRegistrationToken) error { - var err error - _, _, err = i.vtbl.AddNavigationCompleted.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(eventHandler)), - uintptr(unsafe.Pointer(&token)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2) AddProcessFailed(eventHandler *ICoreWebView2ProcessFailedEventHandler, token *_EventRegistrationToken) error { - var err error - _, _, err = i.vtbl.AddProcessFailed.Call( - uintptr(unsafe.Pointer(i)), - uintptr(unsafe.Pointer(eventHandler)), - uintptr(unsafe.Pointer(&token)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} - -func (i *ICoreWebView2) OpenDevToolsWindow() error { - var err error - _, _, err = i.vtbl.OpenDevToolsWindow.Call( - uintptr(unsafe.Pointer(i)), - ) - if err != windows.ERROR_SUCCESS { - return err - } - return nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_go.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_go.go deleted file mode 100644 index a3b7374c..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_go.go +++ /dev/null @@ -1,29 +0,0 @@ -//go:build windows && !native_webview2loader - -package edge - -import ( - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/webviewloader" -) - -func createCoreWebView2EnvironmentWithOptions(browserExecutableFolder, userDataFolder string, environmentCompletedHandle *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, additionalBrowserArgs string) error { - e := &environmentCreatedHandler{environmentCompletedHandle} - return webviewloader.CreateCoreWebView2EnvironmentWithOptions( - e, - webviewloader.WithBrowserExecutableFolder(browserExecutableFolder), - webviewloader.WithUserDataFolder(userDataFolder), - webviewloader.WithAdditionalBrowserArguments(additionalBrowserArgs), - ) -} - -type environmentCreatedHandler struct { - originalHandler *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler -} - -func (r *environmentCreatedHandler) EnvironmentCompleted(errorCode webviewloader.HRESULT, createdEnvironment *webviewloader.ICoreWebView2Environment) webviewloader.HRESULT { - env := (*ICoreWebView2Environment)(unsafe.Pointer(createdEnvironment)) - res := r.originalHandler.impl.EnvironmentCompleted(uintptr(errorCode), env) - return webviewloader.HRESULT(res) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_native.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_native.go deleted file mode 100644 index 9b4f02bf..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/create_env_native.go +++ /dev/null @@ -1,41 +0,0 @@ -//go:build windows && native_webview2loader - -package edge - -import ( - "fmt" - "syscall" - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/webviewloader" - - "golang.org/x/sys/windows" -) - -func createCoreWebView2EnvironmentWithOptions(browserExecutableFolder, userDataFolder string, environmentCompletedHandle *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, additionalBrowserArgs string) error { - browserPathPtr, err := windows.UTF16PtrFromString(browserExecutableFolder) - if err != nil { - return fmt.Errorf("Error calling UTF16PtrFromString for %s: %v", browserExecutableFolder, err) - } - - userPathPtr, err := windows.UTF16PtrFromString(userDataFolder) - if err != nil { - return fmt.Errorf("Error calling UTF16PtrFromString for %s: %v", userDataFolder, err) - } - - hr, err := webviewloader.CreateCoreWebView2EnvironmentWithOptions( - browserPathPtr, - userPathPtr, - uintptr(unsafe.Pointer(environmentCompletedHandle)), - additionalBrowserArgs, - ) - - if hr != 0 { - if err == nil || err == windows.ERROR_SUCCESS { - err = syscall.Errno(hr) - } - return err - } - - return nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/guid.go b/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/guid.go deleted file mode 100644 index 007e6058..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge/guid.go +++ /dev/null @@ -1,225 +0,0 @@ -//go:build windows - -package edge - -// This code has been adapted from: https://github.com/go-ole/go-ole - -/* - -The MIT License (MIT) - -Copyright © 2013-2017 Yasuhiro Matsumoto, - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the “Software”), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - -*/ - -const hextable = "0123456789ABCDEF" -const emptyGUID = "{00000000-0000-0000-0000-000000000000}" - -// GUID is Windows API specific GUID type. -// -// This exists to match Windows GUID type for direct passing for COM. -// Format is in xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx. -type GUID struct { - Data1 uint32 - Data2 uint16 - Data3 uint16 - Data4 [8]byte -} - -// NewGUID converts the given string into a globally unique identifier that is -// compliant with the Windows API. -// -// The supplied string may be in any of these formats: -// -// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -// XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX -// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} -// -// The conversion of the supplied string is not case-sensitive. -func NewGUID(guid string) *GUID { - d := []byte(guid) - var d1, d2, d3, d4a, d4b []byte - - switch len(d) { - case 38: - if d[0] != '{' || d[37] != '}' { - return nil - } - d = d[1:37] - fallthrough - case 36: - if d[8] != '-' || d[13] != '-' || d[18] != '-' || d[23] != '-' { - return nil - } - d1 = d[0:8] - d2 = d[9:13] - d3 = d[14:18] - d4a = d[19:23] - d4b = d[24:36] - case 32: - d1 = d[0:8] - d2 = d[8:12] - d3 = d[12:16] - d4a = d[16:20] - d4b = d[20:32] - default: - return nil - } - - var g GUID - var ok1, ok2, ok3, ok4 bool - g.Data1, ok1 = decodeHexUint32(d1) - g.Data2, ok2 = decodeHexUint16(d2) - g.Data3, ok3 = decodeHexUint16(d3) - g.Data4, ok4 = decodeHexByte64(d4a, d4b) - if ok1 && ok2 && ok3 && ok4 { - return &g - } - return nil -} - -func decodeHexUint32(src []byte) (value uint32, ok bool) { - var b1, b2, b3, b4 byte - var ok1, ok2, ok3, ok4 bool - b1, ok1 = decodeHexByte(src[0], src[1]) - b2, ok2 = decodeHexByte(src[2], src[3]) - b3, ok3 = decodeHexByte(src[4], src[5]) - b4, ok4 = decodeHexByte(src[6], src[7]) - value = (uint32(b1) << 24) | (uint32(b2) << 16) | (uint32(b3) << 8) | uint32(b4) - ok = ok1 && ok2 && ok3 && ok4 - return -} - -func decodeHexUint16(src []byte) (value uint16, ok bool) { - var b1, b2 byte - var ok1, ok2 bool - b1, ok1 = decodeHexByte(src[0], src[1]) - b2, ok2 = decodeHexByte(src[2], src[3]) - value = (uint16(b1) << 8) | uint16(b2) - ok = ok1 && ok2 - return -} - -func decodeHexByte64(s1 []byte, s2 []byte) (value [8]byte, ok bool) { - var ok1, ok2, ok3, ok4, ok5, ok6, ok7, ok8 bool - value[0], ok1 = decodeHexByte(s1[0], s1[1]) - value[1], ok2 = decodeHexByte(s1[2], s1[3]) - value[2], ok3 = decodeHexByte(s2[0], s2[1]) - value[3], ok4 = decodeHexByte(s2[2], s2[3]) - value[4], ok5 = decodeHexByte(s2[4], s2[5]) - value[5], ok6 = decodeHexByte(s2[6], s2[7]) - value[6], ok7 = decodeHexByte(s2[8], s2[9]) - value[7], ok8 = decodeHexByte(s2[10], s2[11]) - ok = ok1 && ok2 && ok3 && ok4 && ok5 && ok6 && ok7 && ok8 - return -} - -func decodeHexByte(c1, c2 byte) (value byte, ok bool) { - var n1, n2 byte - var ok1, ok2 bool - n1, ok1 = decodeHexChar(c1) - n2, ok2 = decodeHexChar(c2) - value = (n1 << 4) | n2 - ok = ok1 && ok2 - return -} - -func decodeHexChar(c byte) (byte, bool) { - switch { - case '0' <= c && c <= '9': - return c - '0', true - case 'a' <= c && c <= 'f': - return c - 'a' + 10, true - case 'A' <= c && c <= 'F': - return c - 'A' + 10, true - } - - return 0, false -} - -// String converts the GUID to string form. It will adhere to this pattern: -// -// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} -// -// If the GUID is nil, the string representation of an empty GUID is returned: -// -// {00000000-0000-0000-0000-000000000000} -func (guid *GUID) String() string { - if guid == nil { - return emptyGUID - } - - var c [38]byte - c[0] = '{' - putUint32Hex(c[1:9], guid.Data1) - c[9] = '-' - putUint16Hex(c[10:14], guid.Data2) - c[14] = '-' - putUint16Hex(c[15:19], guid.Data3) - c[19] = '-' - putByteHex(c[20:24], guid.Data4[0:2]) - c[24] = '-' - putByteHex(c[25:37], guid.Data4[2:8]) - c[37] = '}' - return string(c[:]) -} - -func putUint32Hex(b []byte, v uint32) { - b[0] = hextable[byte(v>>24)>>4] - b[1] = hextable[byte(v>>24)&0x0f] - b[2] = hextable[byte(v>>16)>>4] - b[3] = hextable[byte(v>>16)&0x0f] - b[4] = hextable[byte(v>>8)>>4] - b[5] = hextable[byte(v>>8)&0x0f] - b[6] = hextable[byte(v)>>4] - b[7] = hextable[byte(v)&0x0f] -} - -func putUint16Hex(b []byte, v uint16) { - b[0] = hextable[byte(v>>8)>>4] - b[1] = hextable[byte(v>>8)&0x0f] - b[2] = hextable[byte(v)>>4] - b[3] = hextable[byte(v)&0x0f] -} - -func putByteHex(dst, src []byte) { - for i := 0; i < len(src); i++ { - dst[i*2] = hextable[src[i]>>4] - dst[i*2+1] = hextable[src[i]&0x0f] - } -} - -// IsEqualGUID compares two GUID. -// -// Not constant time comparison. -func IsEqualGUID(guid1 *GUID, guid2 *GUID) bool { - return guid1.Data1 == guid2.Data1 && - guid1.Data2 == guid2.Data2 && - guid1.Data3 == guid2.Data3 && - guid1.Data4[0] == guid2.Data4[0] && - guid1.Data4[1] == guid2.Data4[1] && - guid1.Data4[2] == guid2.Data4[2] && - guid1.Data4[3] == guid2.Data4[3] && - guid1.Data4[4] == guid2.Data4[4] && - guid1.Data4[5] == guid2.Data4[5] && - guid1.Data4[6] == guid2.Data4[6] && - guid1.Data4[7] == guid2.Data4[7] -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/LICENSE b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/LICENSE deleted file mode 100644 index af1894c8..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -ISC License (ISC) - -Copyright (c) 2020 John Chadwick -Copyright (c) 2022 Wails Project Developers - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/README.md b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/README.md deleted file mode 100644 index f3e020ec..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Webviewloader - -Webviewloader is a port of [OpenWebView2Loader](https://github.com/jchv/OpenWebView2Loader) to Go. - -It is intended to be feature-complete with the original WebView2Loader distributed with -the WebView2 NuGet package, but some features are intentionally not implemented. - -## Status - -- [x] CompareBrowserVersions -- [x] CreateCoreWebView2Environment -- [x] CreateCoreWebView2EnvironmentWithOptions -- [x] GetAvailableCoreWebView2BrowserVersionString - -## Not implemented features - -- Registry Overrides of Parameters -- Env Variable Overrides of Parameters -- Does not incorporate `GetCurrentPackageInfo` to search for an installed runtime diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/arm64/WebView2Loader.dll b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/arm64/WebView2Loader.dll deleted file mode 100644 index cd1c694b845a66c30fef09ca675ae539107477d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 124328 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

<5wpmu$IPOu%o!P`BnUE?KM;oGeVDi* zBg2#h0u1Khuz}V=@VdtnweDHN!w{0O$n|FjGsBjbpBarFE@qhccr(L9P#X$V-uzc* z)dZEPp!Nx<{r*DRVW$QYg9*o9$IFbYpfaCv;{SSkv-%D@U;O)T@pBz$K#6K7x$xxv72K|)z~A}Fn}vNBBJV0PFEs@D&G`X2($FOtymLxFE1C|to} ziViCx)Zfn8K$)V|1bW4-QlMK6T=ozI$g=YuwfMg!-mxi3>(&f z>RmX88GnnQhiSXIk}QG2_Y?iy2lb zGcZhPU}7+Ps0>P*qN~0sGfb3YV3_iNk-_W*v;3-;$qW;( z>ho|2GE9_rWcaA~|9{8}W_c|>1_qH5hK?W+Q2S5Z;phKfAb*Ky{Xfhw@ozP3t^v~S z(_m-_0*&Q!Ff<5#VV2j*U}D($8C-Uu`O6vMFHju{Y7=~AmS1JY&=B;3o#7|Qod3)W zKRH0|XJ(k_1WtD%t8_#dro3c!_?b{;y2GAPtFq%MKM{#pV9!!$e2Xh9D-#hM>>P%&S1{*VVuNPw!A@2zvRManlQahMg~&8GeG(l&|a0{Y(r+ zui6tgDLXd=If!=6dcw>w(V1aE5vZ*QYEyyo)C*;{sU%*pB#a%puD(2ae?W?C(R5KpBghv1cei*?FKR1;pa&Ph7FpouHb&) z17?m@3XJyGK=y6@^WXFZzr#*>UWP*FKmS8OZEa9L<{zj%&jso4Snx7TN%;MLizo-f zL~tH(hNSfu%8V&! zi*I3I_%Njk8ut!76C0T9uYvm1AR64ZnZOGc1NjrC57eiDrJZ;NhM$@Y4m)3f=5ZN1 zf*2S!6lF3om}nKY1$kXuS!B=1m3@$zAw-kKVJDaM%pk8Sh!|+RNt452=c#Seg1jC< z#2T3xLNs|CcAlEs8>F>kWf3S}fb^YYWH1G(wP$1o_ftV?xDKoc0+|iUM;;6eKRFpe z{R56wnyd~#VetY=mms%-@&Jbc!$i*7_zneD20?~e&W@G;|C_?(K=R1r4luRGtPF+1 ze<5l?ed7Jr%vTpc`#7L>JBJ{o-300vf%-!5{tvv5BCLhn4+Pl*!^rmiXJ)(zPFtX| zlbLB1XuM-3v;2>Rj6cl(vonC}d656Wb;Sa{iI0>SCTc?c3-aqDP}`W9K}(o{K_t`4 zVW%c5L!tM-{~-x&4r^g)C==YjVpx0R&;RKOOh3#XGBao;NICojrEzed4cZ3eVPFse ziGk#h#X;o_$nPNcfW@JHT)-UvW9d&&IV-RApP6wYPX7iY(k#e-3=-fz;e;>Dj9MIy zCKEH57(ngoE%j0iKatIU!Odip!N;((1l(T`UZnx5%b0~%A*V%9m?|(RTmfNNx?BMo z6Uhaq>kSMEqVTc`l$Res`s^1#efEV63>y>=h)x8h6>z^DTGo9=axb)Qn*iz)g7O-u z4p_jzumPl(;efzIMFxS1stgT5khYxgswd3yt5!72{g7o~m;zImoWwA(Nr_=1LxRvm z#Rq~DL28~d%WH`sscA`Kn8@HDGEvb%7~Wq3srmn(aV4m~#R;ktl^G_k1GN>K<9@jR z{68I1w}Ix+4}r^QSQ-31nQ7(UYUY)H4>L^s&djRynVDtP7iMPYoHOI9Rt5$$(D<1q zLqibfLN!a!ymKa~ykcZ9Yv6MDxqyk`=VVrfEefm*TR?Rhs6HqcVweJI=f4o2FQo!$ z^GqmbU@+%coMx%P!eH{CJ#mu?s4iz1i>&!5D=u;CLZJUAE_gg6$f zSuS8=FoTIh%5cz}x5%m|%)+aTL1DtkU=A`5UG8r+^16W|D>R_>C8+*JmjmT*lzaxM z%fayoiaTZIh9JcTv5BC198`yc!h^%t^(U-uLDVbYvVQ`o?Eeg|W1wX}yTi|VCWgY# z;`61R`~c+vXdR3){>ax+W;^)2KX7(Q|^Hq2t=g!IAG z7$M_5pfWCk5i~x?IPp0H!xT^%b)A)A%L^ul$_`dg|3!S&lW+g0gZpmGj1&L=XITmI z$7=>i9}biTKw%RGHRB<(_^Mz=$oTR@ZHJ%WG@;BeQJDeM*AN4>pR_=J`VLMDj1y0R z$28=%!kHLMAIdxY1eKMLH5`!i?85-=W0`};EZ9M1E+VbFGB8X@U}7)>wI@OSiEqsE zS|I;y1?Ba{3==nl@&a?rkIPI9Lf)`6)(k3Vomc*pcKC@{Lvs|I|3P+x(zfCQ@rlT8 z&<4AaK?@u&><&LUTp{uD^#6bH8w?B^B$9Q(eV1#DkiH8jO@jI_jc>vImkS(_{>ui2 z27Yi~1svCk;Qq@7#Rrf+jlybh|78P1g6_m$j0{s^VP-Fen7torHptw>xBo+?{`)^& zVKY?E0^Nyk85yReg4;KkWA>o+J0Q1%%3#nqCa5j>jhS&3XnX~fe_NOtwt&V1Ueq&a zg4KDt{siTzr@{;qpD{B`WM%@zo%kwHIrfNI3|vNo;?RK^l0G2i45W{)&cHCmftkUq zfyv>g0}G=3GZ$n4mw%x35uk8>{vDL(L1u!|1Vk^m4URT$52}}6u!H-9g`lz%R8|>7 z`yZhG7|5(EV6$N52j;l{3ubw(Pe@^d(#CEEx3R%x$!Elv$|_Jg0=2InGRtd$%6?EA z`_gwv8ynQVhK18p&^jh#Py`g8A3YP7$$Nsa;yfMXE^_s93yyKb=3k!hAp7E z4^TN)#^vyn<7fS4CQvy78XII5Teaug|LJAm_P5w7VMc~2CD#~M?q_272%1k~0j)iP z#uua=jM|q3nYW*bq0;Q%|E-WXLT>9o=48NQZ_L804t@PU{Sh+*cpVw2ods#{Bib{J z3=AS*zk=ooenaMXKw$-oS5VtSo`K<~2Q=J@!R4~Zs)x+NtG0vs5ljr=`a9`Y{bf); zqV3!N=^bpKuo8Z~n1Larlgr`fWG056o(v3I>?@5ci|!5Hvg(SUI~LNeGh%%<@{GaRSiT8hYOvJ)TxD zFig<=QGc03(S9PRt^)P%MHw4r&1YhK-O0!h0?u!duHd;vP}u`YqoB4Zs80rpD^UAU z>f8V6Ap1Tu%dY~7V~+dpT?txu2@8vD3=9{pF**DMg)5|N1LbvwRiODq(Ae--W(F-# zTOVYW{(n%t%3ubX;{=7%BW6)8kUE$=vi~}v{Y_*sNL*rX&w%TLLWiGUm|0hSWo7}d zYy8g4r1gWD5nNY-#;|rWFkG-yhSnJj65x4V&=|G@6T=oz|B->2LFgf~xE82<291?I zVHN?;4Siu|&;qUh1KR;@Um(wwifrhR5@cWy!6y%{6Aws$=ioqgg8DL`F*S~>?mt0c z1B#Ca%pzKUe`Bv#Ve7^W7#b#R;AZ%l#=tNI6i=XaD}SpYZSO<|hAT7pA?riqpzB2c z{QoZw>Ysq}0C?UOI_3gO3nGfzpmFRC8VhYEa{j%40+b#alo%$0`g9pg4m&#-KyyhA zLYYhqJ3(WNpn4P34+Z&Cl#zAfihuV{Ff%j+HSshAH7bF|6CmLQ*2~0T0#g6r-+yqr zzI77(y}_7^dViFib%PySApui zL{K~_GE4;3Q^p*iwkN0zKez&B9w&>#Pq02m#)=kqM`Lf2;R`$1Fi@n}h%VPY0z1Mnz%poD6904_W>uOx{rxEDxId1GyQ5 z(cE=`Ly;LAzu>rqhPfa(yiwy7T;@kJuKW%f_ByfE_Kslm=*3hE!fFyh{+!vayif{DSToP}YE z1vA4GM`ng8pt^*yQ3F&yOi)nNnD~l^VM+rdgDGgf24ublBZCQ84I@;|L-mPAc^IaE z)<%HL6#@5EgtewHGfery#9$i50vh{gSOsnaF*0lc&Fg~9@nB>yDQ0r``JP#L6=)ob zgAp>O1uBCb!DfiAN?@|Twu*t_gU4O3ouGW{d6#P^s6K?2e?g$~53x=KGQR$Rp&`f- zWM}X`$a)oMSc%9m1g~UZ_@HsuYo|OTL*W?)h7eG=fy_WDZ&(=uHSTil^gs&3tqcqw zRv3Bjl;>n9WMpCp`OeHRLyTpK-LY3fa3#XE@WL0qLl{KCLs3Z8p{hJOw;{H+)mL^{|Q0_9m53STfXgn;^v z51B=@9x#ioy7>S9bkMlRW?_b%lUW%|kmWWZ$!%sqmFxb7&^Morp)i5Vp$fEi3Zx$r zM`Ej*zWtvLYiF1K2epkwSHa{q|NlRIJ`+P>ir>e7(|2_ z8iMuKGZp>Okc%sNQ?<@BbFCyd%rR1~!JDp!q=! zG&KkQ{@>ET#qhJ^U;K#-28OMZ|8brGjeUdN!^rS4fy?n1i=^W(So%if>4Pg^bt)u$ z5dJ#;|NnGQ*#Vko0r^pQq4vZQCI`@5%>_{T@gCZ4OK@TU&mBP9W*@i~YEJ~k$9^m3 ztM&@aS3Ni(;nMN{|5hD_hD+X#3==c{Lfo127vatm|Nd_Ug)_2yUi|+*fsc`4;t5-a zou?0KbZ4|W?36cUDCA^j2+8^Au=5NPgGq*_L*+?BhKc%~IXie68iI0o9V$5(xx2X% z877`#WH9kmWSFSI>ag=aBS$u<52MZKu#4hpB8;5rK2zI@0Ejx$gnm5Ht4 z5~vRiiepgxIWRD6O<=IQ^1|Fji@ppDTN@bcu4r+doz=m0c9s_-N4Iya z!za+%S1yKzpw7SX9h!_>TAhD6I#&GuZwg8SJ&e5F*{lo~wf}>{_&7Yy!TAAPUhM<> zSt)Ow24rm({T()z1@BAw4uv3E(QqO5{a_@X0?y%E? z;fFcMzo5PjC=G9g)Xy6@4no4{F?jEjm=;VP8b+odJ>dEQyjKh}pMmlK$3e%P9n1-4 zVGuJva53sk^k8&=)K`oQJMCE+3PJn190eIBHh|W${r^8*6g?du#F37bAn6!Xwu8b9 zl;-7YS$`s@$xoeE6v=Km z1dlsNensl1f%fMqGyMEpy#p4Pt9~*wu3G>9|Mb&ZPMRkkIcUE8|9^rxBg4dR=}aq6 z@;U6hCFij7l`z9jF3yIa7fu@8ucR4vzIx0s@r5+Q&l5}zJL78^R{jT#qee6AJi*9d z{wkSa;wxi@pZg&G-N3;J=}$avW}FCG7Y8cS6(krWKyeD{Gi?Kn+dFA?fAOmLp~=i~ z`h}BrxAkA=$=s3EKQjN;U)Ew|2zq7BuyYjygUJgnhKY=h+T9P88GeG|Aj6hH=!G-G zPSE%>D6BRfFhj$ot)TU2jG*?6D7f$VFqvT@sC}`339@G{SP)Y7g7kp&gX&ok z4u-9!SoDGFVvs&i9U#KWuoax29hoPB)}4X+BTNhpL5vIymq303srkYTRg;J)&q3}J zv2^_TAev!k2qVK5kbTHyB*=XU3=Kh``Bsn_R~Q+#zDQ=6_`;mwXEu6RE=Gjq171j2 zg2u>`85l%fIazdj{Ea^m@|W|(Nod}dXB2sTkO5qtOyF2(2QG&|^%lszAa}vS;EOuL zPtf`ma2PP7hMfaLLl7toKw$+cw~W~tww@4k*qOn^U~)nZvaYDZ&S59_s*a$pLmJ(l zjG*@Uy!%k3|5{|6?v6%%LX7GAT z1U#<}vg$2BN#gW9WL{jjjKX80+A9+rm@VYz@A5|*$3{h$6> z+u^4%GXtpab^#PVp-6G|Kbm3ZduGv9U(U0v1hvUPakl^(J`C`_!ig2Xl^uSf?r(*R z&4czhg)`(HsAI@IP|uKi0FqBZ^#!EO2AYcpjnx&iF+_mI@mLPtF>L%bJWFr$GG!j)nFUUvfkA zg5n(}4_XHZRkMNPAv21am&y)1Upq5Qd?D=cldF;Q)JtxMpB{{yr#Kk7PjT*bm}Ji= z{JMjYA%cUkb5;i%!_Sw@8mmBMA}1%Pj5!Q1hd}-{T6AA`rZxkEF_Z?WV{p`gw0jmZ zfzzY{qx?0P_!Jh%_zA2%&cnbkrIV%M5_nFSk#iLX1H(^l28JmhJ||=SCQx4&R1SmM z*r4zPo71QR-{%VEFGTQR<2b84yMsV&2u?WTJxYzw}vLDJ;4cXPiTVL7OV}IbTm0;ui|F- z8PCY`8dUFs+6MKGn&7clP=4TKvKWLFz$RI4ObF6*4iHykHhuwT6M=L)Sx{iQKFXKS5fRJJrYO_Se^kP531id{{IKN1s1NLa_}!~ya#D~1=P1?VPu$cfPuke zGpt|nP-mk2-}xs%=799W#zSE41otB^=2*%zFcgC3o;4Xeq&zR`SiWOmm;zes2d)Dd z7)(Ka1-Z4371BQjjfH{4OjsDE{QUo49PB3OTsk^A$YF#(Q?IhG*zX@dIV3=AeK z85m4K{lgN_+G=KDEhQF)DKIl&ZUmbHuE!yLv@Hw_7dj5*T7vpM8O#i(p#H!LW`>aC zpgC?(znKx-m%6~fs5@~5J9w@i)VI38kf=Lx2|KvIZUS;MFKld*Q5Tf%FK8y}PUK=} zn8c;Yuu@BtVI>zQ!%r5be&! zFeQP30US1<{=jW^L|mZj&jHPUGJwZAz~LOj&M*a(7eZJWrZ_M#m`1Te+={LbKRcV^e;6w|{4|vWwM!uN ze1j6hMNl0N4#Px9I}_B72CW+g)o~BF8GdeMVAujO&x1k29MsPWV`7MSoXjxsYctcz zCWeNfZ}%Bjg4S>yU}TU0n*(jHg7p8bKC%LRJWGLfvLt99B7?(BMi8A`ocjRcFKq2> zNPYgDnR(TVG>4V1L1#V4IsE*=%&_V;H^WaZM#sp ze(?gepBM_G7&~ThusiHL$ph&Z9^_yM`O(d|5~OcF6Gyg_0Jv>1LAsG;Vle~5hHXJ6 z-6z-_cE&qvyl!S=2syz8VJm^yLJm7$uripO;DgLTD=;#IJl1mfspPED{g9b^6{tAU~aLH>Hp?eG)i=P7Iqf*^l4aWI4&h3qv9asu@sgdBdZVRG0h z%qV$!J`+!N6FWo5D`p<8bwMWGFPXWtPOw74K^YVdoDlXQR)!Ez*s?K77bSq}^M;^R zObjOLgG{=Y2bpxQ4btvj!RoNH-bv$iGb2OD3Qh=HiIE}XrJ%#k6@s94EoU~UE&Gzk zVdn~72)}`WAtalXL9m{YEBo=^{~<4#d9>;od9oieF@%8paRQ{5fx!f1?hy`$Dn%wx zTLL`pCJ2g;7hViIPx6BH4RNmmkIMh25`+LF;}% z>vV-z-Twc7I%u90R8D}*_>45K04~SC<8hEa^nw@A4AuiK+m&*wG+QX*JFO= z1Ep2*RX@OcESXnTa6|S|g2qKa^EIKY;5ur8q$A73SxgO=wz4q=*ctDr`zcbUt3}%#JpS*@G*RLmWULibpMd%mu<{sQuYlV_ka8Ea?gzBqrIgQMC#a4A z#Th7_fX1A@F*9j#ax+XZ$WOdjHn(G9Wv1b_>LRNA*>;&7z$eHcK z$PfaO1Er7G3=AP4aS*$Qfg$8RD}&)V!EUK%%-mX#@Ueu$_LeT!mN-n3sAZKf?0SKXsy!k|Nq5Vp=N{2ENC132q$DN30!U=jhlkf z;X`hQpOe`feuCy?KywLSIU!+nSfA)Qiq(wPgc;nTmy%n zkTFrwRiH9~ixE@?iLFv`)as7m0maQBjJb@@;Qq@laQh16zb(QHKNl)9{9Gi@@N=;= z!_Ot+3_n40AzRcLelF5x_<0FrKL@031?wMx%ASSFj1wD}9Cm{0@r}+56Yc-a?*Oe$ zS|IGO^KbPrcpo1W#~=)`7n1)LIx|={urO?S$-*GP!2qcn89{9d35T8Xf((TVnHfSj z6dZPPg5()Fy+QMN93U|Xho2{y7`AY-I_!MOz+l25vb5mbgKFvwp6yC0># zVp!F~$uNae2fXeVv}flhXgmfq7pTeV@U!#(fABmVIR2q^7N{KzTI->qe8tSUDuaQ+#6$Lg#f$&{O~V*DPaj}on0S{BGS>_mpKD@r_<4|xVPXqE!xT^+ z0`>V41j&Qkj@-9FF9$M|94tY0Connu+|9-? zrCy1_vYrWl`OyJd$8iug=45{jv<66+!Qtm>@EHTbt2Tq@Kv2ssc?QPUpmPpD;R)(@ zDylF{WKdz4=)lh)0*XgieVM}#8K(gC9YJbA{mIiD2(c=DhAH^^ld!(%9S(*m`TUsu zN|-%YI8fza;x9PBeSPqHMNrs*+y;tIm^^6AU6m76FGwDSk;50X&j6GrFN6A?3=9(> zV+N4E7bq`va)8$-Y+w*|2hVGQ?9#Ad2?Hg^>NOb|1vP3NE_d>J zbSpSAT&!SV5E0{L^5cC|Gid|k0b5QU1|c@Sh9J;bjS$G)ePww;TnT>0TnT>eb`pL$ zb`pM_j1uM`_j}rL_<5he1&!&Q5OL>k zle2sndAi&g*}J$I8ZPlMG+c6LVAy&Fv=&YP;@)fqhAo-Uu;_q>MLZ*Cb`oUH{*n&^ zgNTkD2RJOV*euMjsXxKM>AjxUqk9AIK^x(|vOJMl34R4~Tl@sAHspcA&g1|8Ek#@j zep9&;{JiZr{MOlV`1#mL_~kJ$Yyr6$l;&4J!%K^iQ4pIQAU7#9F@)sUarkB1N%)=m zZEvm#@)HxoRu4wTKn=wcvp889E^0Ayqr@-FPbV2Ty+P~S9x(H-0?}Z-puLicr=a?H zy1YUDXKM)3WaRb+g(ETMa_}_-aWZmxgW`AruLro?g{61!T+TsJ(74D2jZo&Fp#Byp z9mC{d`39tp;i1vQ4NTB9?`S-6EfZ!wf~nWSGA0Bv6FGl@%mlS9KxJQs7-a2O7ihgd zv+$}ZP=1a$M0^glJC}iCZ$WO31hnWL1zg7UE z51afu0sQ5xf*`71GOvVEw!+#fps`UaJ&4q?J*xZ%g zJ3(mz6egg#P0;$UAm}<)&^Qig4i}`~7c!o`f#D*OJHYK3NM9Wk){Kn;6G7(yb%NG< zEriU6g4Xdqa)!*ug8Fr!^~qqh4+SQI&O!m#&y0|D4pJYZx90nL?g7&`pq-0QGYOOYeki;=+;Y*wQ^ zbY9B-8rV&Wko5_mbw42ULGuVl{{Np2R-0%GRtpjX$#pO=NPzl^55(t7fx;2qt^&6& zA>*DPcRXrm(oA9o+xLOvAS8T1bu`Ef(78yUI&`IHH)u^rHfWrP!v-?P%5?y3jukpD z1)gICt%0#*C|t?F5aRLEVJE141ajBR|Np0h=9K?CGgyN5=D!SPnE1k(Vd6_==9QrJ zf}RWwK`$3GYd$V!nD}Th!$k1@Wp{>&z6=agKi_@gpnMAM z?|{c?AY~0Gjc;XO*sx+#p5+TR22*f*542Bhq25H!zw#uh||iLpzu&*Vg(b!6i_@eE`*9TYECQ$ ziLp6=_7v{~=>e_PT(L>d610~9JxW^RU` z3JeZA_4z^hP6X7>oSwksuoJWn89A*&^uyZUkiHaX{eCGogUJf$+Ps$x3?a7S3{y@p zH3V@mFzmb}!Z77BQ$tWN1B1wOL53-ya=h`7-oz$_h9FRSa+3m;<9d*KPLvrmXMDj} z)%j;J1H+aKrURB93=F1|59xvTy#N2txDqr*4h`Q+p!z8ev~R54aitOiXbrO1Dmw;- zDWEtOVPx1UEzU5dgAw8mkX`;F3{xgEHUt?kFo-nqiFJea(Syu`jlFm?FihFc#sEGu z4K#nfnt|a$i7fL^kX}%|w2Fb@f`=j7PB{h!5m0{@RDOWU#A0!9e?kki&JUF5O+jah zFpI1L$s36mUu1rI=ogh7+ zI)V#ouaXGE6p$Fm9(fUlDWJ82p!5yuFXHNda4`It1ga;Km>5DpV^&Vkbypmmhi2I` zaJ*i`$Pl7g!!-K^zrrecM$Xroj0_V+Ni7#xRkSnc?ST28JyipYB^^FfmvbvoTDZ z`su#K6eiF(k*JoV6lA=g16@7S0ZW+rDQpZALFe2}|MTB;e-mWA?0z+dLdHM;LqKNN zf0DNV)n`-K7%qx}+{JXj610X{z7e8UUKQd-(EhD2%p9vY7!O#2=6PRmfaeak!2G1a z?C^6scS8^-E5k%hW`>^~Ob0Br8NhAyAW)y7L+*fu7b}Ax=zO{b|Nn=8{0>@k>cz-l zewBg2q=W5%B}fd^HV3&G)V>AnU;8RPUkWr%=T*xXti{M+;>F4k2+AYn(C|R^yVn2z zrVUI7EESj;Or|n0n94UW6tYNoRxMy+2=QiOFah~Dfr-Hqqy`k0A0-jt2eK37c6gX0 zg(0#XAay7I{}%_jp&pAHHvIoD9>&11waPvN2q==VjO!qI+(Z2OC4kPiCG~ z-qr^>z)JG zE1>!WREL~oa`*|dQ=1WDR|ccQPcBBDQyHudKYex2&Dzf>{u;#h);%{XfidFOgFpX6 zzBBW#`pV3^>IXCTsxQpks~-LTFTS6RVI!#h44P};7G{_NG85!S(D=I!Bg4;AOrW(i z4nKKV8GeH7)M9k_>B9*Lb5Pvjn#X~(BO&c8P(BBZD{g_-D>HdP^@{K+&^kg;+X6Ih zHxDAFg^C0m6n*S7DXbj#P1uEYYlo%!kF@W2V6NDSxeuCPnpnU^hn1w;> ze71njKDi>qFr}l<;m3;q|F?qbi3>td^|jd5pFmT8L@!3uq4`X#ac%7sHeUW(L!%OyIPA2~;1s3xW2ch;+aB|6d$EJvpHH z*+vL-27ALLD5dKA_hKOH_l1YUOl2`A9p zrv`)QX--*&iCTZ1FYjk!eEqGtYZhocvW$^o3uvFt7U#CS&T*Dsm5R)Nl&(qMJmAh&U}6aAgt9^D&=blAjhS;o*aq8L{11a1YHqm z2vTBT5Xle#ok0seM^?l`pdlzkpdko!{$z(hL(mj~h9J;c3@6!;?1Qqw_CeWT`=D%) zec-*Bf(=1i1RH`tWArBk8-lI~g64D>L{ll&Mf%?FpG*iyT@N*e-Jp?Gdpr^-)3=9W) z85j=qF)$qHXJ9xmfq~(`BnE~9lNlHeY++(Ju$74cybhHGyp|btf8av~hOMCXF{pnb z%)qd7yCCQs%7!3NdECUvu%$!B;j%pgLnWx~5zoN+x`TlsL`;NXN-zt=&lwyHfuOb) zsLvt*?WcguSt`gd1=Pj{rQH@8hG153n*nv)9X1}*A;S>-j+t>4XdV?b$GU>GAxMLP zp;C{7VWKX$Pr~5+nwf7EJ6l80Gp>f9H_UvioEaEQLHi&$I1Wp3HZn_t^2d2jhKXxI zWtS>L;fo1vQk;sK+$R|sDjOIWOx`i`uiDSZ^ji7f{}2!j+WP_W*JELZDIP44{!N7- z=*&S#y#8losO)?iUy-5eP|?B4P+8B&^E&gPd`0qq@cxh>P&|P0A}GJY`~hxbU3A-- z!N_3x05r}kjOfE93WCbI4ML!CD#!o-xA-$a&NTs*WuUXakj+DsFOdErsC)s<&3tBH z*t#9bOdqJ3<_ruXq5uDH0qsu%?U@9f-SC><;b+EN@cBzyA2N%A*HIWTFiZip4M6k# zVvX_>6Vx0k2wp%yKPOZ_CnWwwK>9_Y`Z;YFf*Y7Py+P~yuKfOQ`eLzzRCus52Fj;06nZu?2xhP{2KqF1N@X@O z2!g~i8at&L7&*Xp^!!7d1%@_Ww5mRd!LpHoVT*=}!^(_h3@fFfV_zH>-FBXUta+Wl zp(s6(Q`2E(<|>AjpgmjF+zeAd`-2mh7=ChiIQ#_7M{~M3{LJKH_{k#yI`75dXQC6s zL|F-jDVas8KwyHIQ#^Sp@GIwU}XrXoB_3YLG!s{OptkN*qFrw zcE**C3=CTo7#Mzn&btBi!$EZ^BppK59E03}**}G(M^Ie{8gBuuvnZ8e2tL8UuvJi) zVain|aJjK_nE=C-d`1S5X$%Y|C%7Qx1IPdWArC=k0)oz{{QrOYOeTk)puVdyvqPl@ zHv_ni0GTPQ>QDhHH$dxc7#SOaJS7;WIQ;)_x`IjGsD2wm;SQk=sf=|Dfh+&d2aTI$ zf%f~r^nvu;uaYhTxua2pA*B8gL*ZdQhLHMK427Wil#D|Rfdvc)Q2kdwOSMoLBz{O0B0fts z5LExw&r&Z;<_6iR4i#4q37f4(aDy|vm4;I%he9Q?F*M^E~2YQ0Vbqkfj z;<`|A-9TrsxM5*32S~jkRNOGo7A$UDxR@OzZVVMS4g{44^|MS1AG3kPO`+nZfrcRU zPL_qBb#nDtmJo3#%Rp_gxOHJND?>4)DAd$DgJkP#c2d z-yD!yZcbZuIOu!=(0K=-Iyi$3 zlJ7Iy7z06Lq4uc^g_)qWYYYuSpt35Xi6IaqmeJH9#c`J*5LC9@XJRPyU~CAwCe$GX zZU-A6HPzllpQqRc*vaeGL^0LFp{_|9^3i7$+ygMbH{R&^Rh&&x>$2XslwTAS9jI^D|7j!6;!4s&7H# zB%pkOUgvhQIsD87jTM6GEkjqQyvimLc^vXnq3GH@))z|AYo6hKZLT>t;dgd4oXfC_0!J zCMGg*oCe8(*6BjW4}(B$R1Ot~oiFP%v=kT_z-w$77#hHBUgYr@N0W&ipfxIvko}FIbFe^a7celGXfQMgWmGYM&#D0RH9-9gxLcv~ zp2+r2W?=Y`Am;!!AGFpBY%U|jT#%Wdayml}Vjglq5l~+g>>gBm!24f8c7WQe5r4t+q8m64Le}qs`l%pyfW|{X zVTL}QfjsU8a?2D3h7S#(aA9FE1oiVl{Ti^HiimgssROA2i$mibwhtH7)&->t(3!IJ zOdPL4<0K$=8U2NjlZT-ph>wZEq@%X>GUq}4ZmrDR9jgy& zb^mAJehu2|*Tc#nIG>RZeD3`j&^!cajj^vrx7I=ZZqPn(kiDSsl7IjIiyQv`FaC;| zX%%RU-c#0LC&S6i9r7FuhM@K=$XySZxmMl!4{@uejKfZlI;NAFJ3wYY!V@x1{DqlW z3$$(?G+ylS<^S{yQ2JqT_^EYJqZ_m*6jY9Y_7eCqFocA#GVDYiD~99?h&eDb%#q9h z>DN4{(XGG=S`T_?1+0&P-Y@tq4_cGA8@wJBwEty?Jos#*Rhxwwer}d#_z7AMyH%Xw z=XYjit?j}LJD+^{Km9i|!>Zljb>X7mbL~L;N%s8zKOK|@)IfXo4IumaLF*jnvoRR< z358eraxjE|*k`#ILRPRr_9$d=F@#L3tDSuQ%m3*sxEywJ9?FeIuGR(l9(2w zShqK;!%lBT29qOb;=!yAJNJM2Kb_-%arb6n&>DRP5zrcA(A^7a%q$GP zF9R|*A-2l<|NrTrdIx3}$m|Hn`4gafw7_#5nB@x6ehz7dpOAD2IsX7uc5YQ?_$dZG z7iPaW!_NJXb#0Jhcd%Ykbflw9DeSUXZX1V6u0~gKXCgKIQ(Q3b@;j9 zFyln;FaM{5_9bkWX85^T-Qj139{B8(E#P$q;tV@;LFz3Wey$K^_{pr$5R_yExC z)dFpYpD!MQ&(vA9Ssc_qXAlAD0jw@ZW0UKd}b`Q`ugGA0JoOcumCX3(1Y4k^gGZ_qq! zhmyn2PG$xP4(Ph?7Yqy`4Pp*I7kv3Yy#aI|H{|T5RXJb&PuKqUf4Zaq!%t0coG|>% zly}&>mi3H_IX`MnE<*M z33Og{I2!}#4CbAZ450M}pnZ%Cg=<+DLaIOipY9>;@RO6*VJFuC&F)}9hKXfJViG4Z zcgQm{6rN>b2)SM7FggG8|LG-e4m&{k_A@ub&tPeXpHZLxPk+JYuyf%dlWx%dE>PLt z!PIamL7ijvb_VdCbW;g-hCtBXLy%c-{{9aE`NjzA&;3sd-gzQ9gD64 zg*V&3|I@u07(_sB1>M2WEa&jEo`u0MWr1haDo#kA2AypHQVS`^#aD5E`aj(cH21;> zK0m}1 zf<0LoOhA6=gwDf&_LhLl8_-=Gp!t6#&>WIj_Dd#)kPaz_pPZZyJ3E;eOm2PpKOM#w zJD}P9jS+Ik4rGo+47@-7IkU9ZGiIq(PnjjOKjawL1l4z-vs1Z2>#mrk zRy|{u(0a-&ja3~lBVtV`t~9pg&;RM5`~}*R0^47#$-vN{#=y{^#5!40k#({psN6z~ z|3k_SP+J%jPoTONbcS38JA=s=W)7`MpFnLElkOL63|qD^Fqo9EIqd9(ih=q zZk)sMfaM8R1`|;DW-wTotz>f8>B*{K4${*IiUT%>ogxP`zj{XW}yBvdY=M5-UubO~c0G4{$JS*}}oF1vEZ+l0m}kftbTj2M&fUCL9b~8kiVl_BC&>@ptQ*I;Q#a$Vh%gy6&VT>Ss6k=XP1NSZdjj0{^>urO?y!osj+vslAUkQtygA16P7 z+Hjz|L_vFbMOMAP|9?6t{xX;uwuCS973z9zXMFVLNB z3=KgMf}K)3z-RJFXo1v0>Y76sdl29K{y+Wg@Bh=^{Qf`v_3!`FU;X|+{pD{^c?>&O z5|R(Vbptc=Dh~$Gy4N3Op!f#OiFyU=)`EN!XZX28h9USDGn>|r zb_PpOS^UeGVJECS=KTx4(@x8tox$+6GNil*-Obje%n$-9Q!`Z=B&t;*bKnm-!R04- z{~l=m9@LKGV3Y>8K{z0CKTmKlY~A$k0DkkFa z^F=d*WrLizc}k#m4#bWO2C)4- z;lgyLhD)349432w{68IZZUQKOXQ_$L2KCpp85vBR(8NLgHQSG%GSwJd7J|x8#>W~H z859{NmVf#`T|tV$1Z2-vHU`1{OdQ!=k_;iBbuQn;9e%E0bNKmrG1tl$QVbHEOrY}} zIIR!d_@H3l{t2;y0VP%$}!_E_`3@c9wGVFYj3^GqLn}?Gj z~K76-TgwI;iv6C@OkE@-`N-fL2Fxk{{0UDxdYU;1Nj@&zI(vL5b{#r z;pgrD|HWUlJ6O6Mw(fr3%sBD8vcu1(kC`Su5_k9stJ_~BGg!W8cCZBHYfv5k0<>Np z)aPPn`1!&Ze8&~2UYY_j8&qb2%y_Hr@DmgV66_3upm3IF=E;8i<$uVJb_YvPoz=yS zXx})qGlYQJG@x=})dxiTMibP&QFGV{YR_o0f$o%rlvC^9L(*^uD}yPly~D}DU~1m>5i-YdidW#w?}vlvxrfU5c#&g%`+f(E884 zzd-H=t#f49`rny(qUOE-(|?2RhRk+Z`90Zr<=1GZm7jwhSAzBtgT|~%fBl~x^yB|@ zSYP$+hyT+-aXtGFWGs>Kq1Z$aKmXnT>C1kB$`pp5OMd;I{zBa0Cx-~bPv;;1r-Sxc zfZ9%ob`rMsI;1@Sx-%PeCcq@+^w~jsB0=>Cs0@erS!`A8zyH%qxE*#DGdt`w`S5@Gb7m2(N7A5h64v^f z4hmPPRV(=%c0OhnU-e?KlO?E}VmYAM4YCK6#umT-KOKBGb@d^fXUAdhZ$Zu(h4_bI z73j>CU(AfFels(z`jyYT@+CK;5$FsW(D?$OGx>iqvub@|X4Cq{%)aUYA45nmD4sYR z!1s%R&+%4-jJ1Qtp+IA{pthwKR1IkVGpKI@vIBN53}_7gB`>7x2F-UqXO`4@#w@n# zDYJ;y6K2pIH{z=vF-xy{$Seg8)5s71rz>zXn7&|h`1y4)%Sup~tmFojameZ=wH_)n zPJD2faboBD|I=R_W}Nt@8(PLCL(8~oP?^M&eTai0&pxJxOTYCUett`K*a=$O zd$P{q^4nxs`Njt>-@MpS%eNJ(3@cZG%C~5cS(4drSQ$cI#6!xr9#)2sm)QHBWLF1d^s~*0CjOi=|>F0CU`8?TS=Tm0URiOPk z&!R!;MtIeic!rgaNmj&JSSo78x>-{Vv+2azYv>vVUaNI!yLtLYW7}Z+5+U}1#L?|U9xnv@?;+GaMisbypmPE*kYZmWKKoG91K3VSh+Uw*6^PH6 zs4@}c&jSn%L7SjwGJ(#JMZ_6oZ8M}jA*=;juL>Gx2K#j(#BP`z%)iKeAxJo*&YObP zm4WPLS_pQ_D$w~=AU@+kh+7<(8iM+vZULR$itZNBz3HGewhx$vSE0BEbZ^Dq`zK&> zaQ7gcISp|Swsr+19e~#6f#$P7?qPCN1;q=(eTk|QzcDjwfx@eSsUhe)Gs`OY_#iX; zsw4)6DLEJ}RUV`ed}7t9PlA?*;*IsL+` zK=;~!+H0V_ks$vGGeGa}U}Of*p+m;8AbMf?K>h@+BLt;yTw_xZe`84x3n6~|%FL(* z@-yQ>RY-bZY6#MUrb82ydK=(6y{JnnyG!_9G&j5`ff!b=DnHjc% z%4v;6hKU@|^MK`J7z+!lQ^O0zJkU?U-5~6&!Z0hi#U%OyeISj z{S%=02AN~b%&_&Pw&O}rm?ZxA9|8+Iu(?bOpt}t|a4<4X1l^kmTK53b2THF87#X&7 zu{r$Y=4c4=goLvOuQAIdo6W;%4MNr47{wYX5@P0};#*Nc%iMX+xyZej;cLZ7Ku91u@o!OBr}kk3N;uSg@Kj_*Q3q>(f$IWA#GZdp`-p*;@h7NV2s;-L)J6e`%kwhA z&*^~a2d@=6s5g<}AEd9ypa@wX1YJ`T#LmDV(g-@Q7qY()w0;TeIXuYilF1AV8xlbC z1}qGQp!IRAp!rzPS|TOL{1~|GfUO?_&4(lHe+T;qY5fkUEijdVVZ#Ebd7$+=y#K&! z8CGp!VAwLBjbYZ*g9z4DM%f7?G9*cb8pt~AD>OgAv{(;sIh^+b!zRyi$)iy}Fy7YtvS~tMg z=?H6q^41mb9f+Va0uQc0E{l7$j(7r%wSdwgavVX*1w?&`96zA`c|J6LKy6=G zShj)f6$ZCIK;>&33#1-~g&oLD5Jt`)pt=SW$Dzkbhn* zXV&CoZ~&cmGl9cVaH2gUc_}pm;G7sub1y_fk4WN4|{=|2H&a~k8gE(smv|k94#v$h{IWRDUG%jlzK0Q zpP+RNM}X2Es4jc4+@W#>D}%`keTSbJtPER3Kx?HLT7pCc879u>awwd@}rZ^ieSqn4-O{;U5eBz(mhD?_abOimi>^DWY`HhAA3F@Lm?Mu!=;Bm zAm`)bYQw|YkD&dI9E>REJ#Ao6Wd@x+uz^DnOQI;(kUB_yhKv({>gA40k)X3vK<7rn8ZvLZ|2k;inBgMm zJnlJ={<)Tj5O_>-f*7L^=uV0tZnlO?p|uW|SJZLO=FBYHVb3U%?ZCwl0y9*7J!hMo07j6dt87pi|V4?BvKltn_O|ZI53;Vy! zg&d5sMk~BDEkOHx6WAPfsxmT60i6exAjJ3+l(sn;8iF#p7Y!_=4`HV}-(T?>$U(EW8F^(X)R z56RMXuz2mlt&$T$k9PXsEXL2Y@JkN>B4GB9kgFJ#+U&&6N}I#WP{p&>}4kZors1H%Q4hYaAg zsr7sehM+r4kmNRK9E7A5P?`go3F_A1UViZ0-UyNa=M`p2wCM!c= zh8Tmz%K!gOJJVPuW~8!AHZ@H-?{?|KdA9c_H&3;_g6@ zJuH9zPY2D3g4Cn;NB)0;uG0aJlR(JCT9fM9a7mdHa^A>iX3K^f0+L1Tnfg{5*9H zv<^gc)qW;W*&?E~57O7x0}Fh@|%(+2IyJi);* z1!O*#EBG!YaGMVK{7eo;22+qcgR8^OP6mbv8V3<=J8o$Cyn=~gCrAxwTuaoI;pa z9kW2^Q-H)69Mva+<{!XpMs@IBYcTtu8u$(y(7tfcnp@DiBmHZjd1{%9p#C4I`~#Ko z@(di=2e`oXzy=Oj+3gIuql|%z!Gr_c-(r{uO6MG)bGaB<3K#$XAHvPj5cDG2!SeND z2FsVx3==yT8BE?RW|*kO>R<_)f01WoDO|+B5Yp|bVFA&{m7V$je+Z~-e(~?WX(}7| z%>JM!i+Lu3*2sg-r2?%V0F48rax+Xx2gxfm1SJYN{(QQaW#WHkhMg=54MCv37Zdbs zywe!!I8fC&K+e!R$jvY%KaFLg4nsrGyTv@9dh!ylLPOB=#Viw_E#{bbQq`g2B?E(5 zrjt&$H>eCw1ht)Hj5HD%EJ5M?6127vESF}X0hW^n%Yo_)(3xZ2nfex>{XwAebuBAH zVDDehoF9V-s7?Td6UeTNR>+=a(3RkW4(?e5ov!pnC*Bbpy!$wSWGb{%@9< zxcln=>7ez~puQEXE%O;Pjsnilh(6mlX69Afpl4Bi`vqRp1v)zs+-Gx4WB|2eHi#xl zPF%p`@Kb@2Vaq}WhAp6a{QlMd(?Ms8fcBLsDKuOH&0DOx_J2AnGvrJ|VFresvl!s# zH-gRcNoAS1n$6*7HzUKAHw+A0x)@m|c0li=n9s-sp4SAKm%+#~vA(u(MLi?O>x2LQ zhkRfHog>7svkhb(wC@Kxd&}c5q&!5<)1WhPLHF>1@|FT4G_NA%Yta28pf#SLbIU;c zVL|3(fXW9(hM%DG(LsD~SBIaO(Ee&BQh)UTlf%yKzaaff zXQer?Fob+&7Fji&f#E|Llf%z%4B)lEb(juJHQ3+e+ED=}QmXo~;A!N{I=$xY$Naq}Z+y6}V*NUAOE@mi!?z<9s z-S`i3ZVD((g2uo>?na;MMx;AP7=hdlYRArJ5`GOjrwFv4va~54<6I?V`#^4d_z%&q zL=Jz@x+nDWqd?^lI1X%?5$El~&Q$`hFGjcpR5yd>g1$2|Yk|&aeDdr6bO$DeEy8yk ze+on55_--LWKQY{v&5>$%;H+md%ahI#`8e)Q((U*JFSGc4RVeisICB==iAM|upz_N z`KOjBgAnNMMq}Mmvx5Kr--^wwM^7N*wIKI%FiK5iU}RXyz{t1~mXAT@I;czs*DcP7 zF`Eof8x}Nfwwy^5w2uOo_tE>^ko{DU_8h3b2JQcpW@rckjRk=2y9b@~q{GM%0!kb6 zxflu;FfxS97h)&`rIGnk427U^a1{myk@5*M^#6ja%{65N-<2o?YPaFqueK7jKOK}mI-P!M337C^GBAjM?s^8DYXxdE zLC%}vdY$p3sDopqEtov*X9}`#@LauQzYytTbbgw#x zQezN@>J_ODMh3GTYz{wn2s8ZL&&Kc*6kectx;H=nPnQ;O*tuJrVdu-A|EG5dHUx19 zFo4g^0^P%2aRrhC`7`71{}7lzIsUSn?ST4k;h+B@TfqKf*aRjZzk$xr2DPm`Je|SkXNTyX zo&_3jbpHvOe*n#qAjSy6W(Ok52~ar(IX^m1r&ac3=AQhOc7=oT;OqO%a;rcp#2|^b=5Gvtc<}YK=*VpIs9Z`bof~h*>7M7 z%9kMfKzs8*^S+>az(HeZ8GH^uIT;#+I2jp0`!0XFgU84bX$urii24t5w-0EY3D__4 zp!4?}cFy<#8A}k3b%yjqHn#07%s6r3VupzeoEaw0{{MgayZ`^iL1WJ)KR|7vV<`PD zkbg5kYhWCq>roGY`V)}(W$+l0A~SeB3j>lkO8u10yb?ApH<^K9LdGUH&{^oF91aaZ zpzsEbFJ^+q7&dlDfzH6p*u=Jzq1IvYS_XzGGeBog#6!-co()<@9q;^e1taLr@P;6m z+60D%ON&5b9#C}?q3SXqbId}ZGmt=Kh;XAccwEoCkz*pLeiUP9xKzT>5G2LfaLE#U zKV3r*Xq{ogA%=;^zWtxh5%2tS{Y;948pBbDC6XiJ> zK6)@Pgj7l~>;#V&D=|zgPGX!mg^eL_%U|$aeBg69u-)y3NI#G^%Z-2krz`V<=YS`G z)**uWrXaUXV_=wYBF_0|LRQ9)KwgF^Aa-U}#*bD1?w?RN$S~1?(f%4J4S?*t0y;M> z&iQBH-~ZF^$1#KN27|O)5a)!!+8Lm;_Wuhr?Bq0b_^Bo6@Y9>qVdraxALgKOAolP7 zr-SYU2bB-NzHW#vFyUgc%ujg6^RPja}p+tApCl(ZDbfqz2>$SeXp! zLvtTw1oahzd}hj;H!C1j@TI6oU4+EMNqkWz8VM z@qsB&-jbn^i?Jc-BvV6>!^BQ0P}=SMSbI4`kYS=iW(M@U2h?#Q(0vFmm>VW>a2}W? z&&c??8Fa5!4dZOkohnlq7$z*>bNngK$nepau>*7_>;{g9kU1039s$sqYM{PF0uv~` zGi(rf$T*RUmtjf*BZCR3F7kc;e>wvrg9*qCkot~)_fLTIfZ7KK{{08t);LTC zwL`(>5mFy4>;M1hq5nZ^7#wzj_Sbo;YFs|9|=i@LCy%o$3q>BDms29_m)m znmR5VZp9WS4oGnVb0;irVD5Xygc&zCK#m#qqho8v#1^aqL$XF`q+zrq^mLCiZ zTX+2XKm7#sP6*#W|EGh_TPg(Y&t_)$2`bx9Fgg7EU(d7>R1f`^X87sB%&;YxwIS#$ zdqWWDjK|N;pz|g9}MVCe@c`Q8~s zY-HwG^{AO);tA+{QV9!#>4`pv9~poDZ~YwZv~ner@M(>|&XYx0876ATGE98UEWC>I zuk+=4M$y-An>%MoGBjKQjdQJKWZ06`>hQyZ@qi`h9AePAehuioavF?Wr#ToUyFueq zlB^69=QHxYUij~S2RWqLdpAHI-Z43Gz|whd}dx(EB4mVRV8C)PQHg-_11G})OZ%4$h2VX( zp!s(Oj@O_wA|5k~t%9Wy&^S}&|Nqn1fW||R%wE9&I#b~Us7+u7n$rZet3dOa91J3- z|JSpxv}a@}{9n(p@&Pl$#Q)w5KS5=||70f1pX?p8j9>kq{({}%r{>=IK^)M#ut9Tm zFOs3>_A)#C^guedS84D3AVCHOky_9h9?1@t42%xL-fC1fum zhW{T!{V$B&|F$6iKSuIDx;kY4qsf8&&&)XSfid$$eo%hXb^xuJEqow6brvYy$nS*g zq2^#YUV7AtI@x} z=h%GUI0y;9hs{hAL3$Qnz6_MbVrm4a{C*6P9dnx#{_MEL)+^f zpu6oCF<4Ih^M5+*+;j()h9IzBK8By5vxK4TYfDi7AJ$gF-lh}Nn#sU0g|o(CGI)P9 zXgmNZ+$a3`KfM|p_MpA}3?iU@0I1$L@%w)Wq^E+koC^g6_Qpr7uwW2knOdwS#y4_&*)S2ep^Mer$xS`vKKapmG_M7D4@5^f^ON zK7frcbJ#Ehzx+Qx=!G&vC1^i9s4jf)e?ItLkO#>O6PaH8pZ-AEp%QfGK@%fGhz6+L z&?!HWTgKrsXJvN9N(Kfq&>9YoPKTcinb{VgvEHus z-8`u63o7qGYka};z<=F$a;|U&uL%PA?HeO#T`{Onk9w~LR`X1qe-bk9*w_ElLH8Me z!WlNk1#({oD4ZOnCxY6Hu=^cBZU@z`pt==(ei5{09kj+CbXOQNbetQc9$b!s%PUAZ z3Oc80t1x72`{Aem(?RoZAiG2sN=*c%sWJwJ3!C{Fes+M@3v+<)i#&NqbRuYs8+5N3 zXs+nsAyM$1R_CE%0UEdb{QtlB0?_$ypFnN$!zg7E$UiW5bAA3l9n>!d-QVzno8c!Y zeZJs^jOQbdOM=}EF8?9rtb7B*#tdeL5YTv&21COoVa5hfn|cChoUN3B;R9&w478UG zG=2t3`=Im-9dDZe8gJ9%K#aE)KEg8I23m{FXnzeh-nI+0-U82f8zjCV^IV{NHD3Im zA7szSk!@_l5Dc1|wP$201eO2bH1yN?Cue15g#x267icXB=={!?>I{{jyI=n+GgLnG zW|#=7hpuvg*MFP5PQ5a8MbgS zI8<_h<|`N+D&rYBvO(+p7&sUvDsnJP)MRD2$oc>OR!#uODA-_ODEEtpGRXHcrA!e zWBdHCger%hpfegc7#u+BMNMCP`#(LQ&f%vFC&QG4GE}*TP`N~qT#>`iyHNh^ zZ~v!fG(qMHLFRUV=BV2oelq-IzIX*B*99sMnJ!)gvHKwGb0ED<4nNO;=t&MgLG#?8 z@Dopzo>;bsWn#%AhKX0f_kV)Yk2pB}fX=EzcI)16pz%wGpS!>PpWe|F_u~Wu!U;*epdGKB> zb@2W&(7ZNR0qaEQ`Y%D`^;W77{Qhaq(YC?1QE+yh#3 z3mT`%h;szb|93Djm@09C)}#urs)G6lR<1(kvmxdreuV5#1g!}Mg)wYRFsN-g*~c@G=v_7SR3F zA`A{cL2Iu-Z4FSkgW5yF3=BU(?8~6@kpBPQ0&17>f#!pRK<7CA2d!7zz;RG?;(R8K z*PymJNZt)JHV?VK>=LN_`wU$h0Gr1HoqG%vNCK`U}gxZ;Dp>u4myw3n32Jxo(;0z zrJjqS5Y$h^w%-Qa7JdjhXCE~70BTEs?BQZ)m;|a%PAZAd))Hm-$CKN&3TMHvc{|NjqJaR_uKzsPIF zzu>ilmo|I_^)n&+e$neth<{M$8$o#xv@Q?X-Jp98K;;7Hd}lF6+leRsfzB#`oMEz6 ziE-k7CK2#@F;E(x@)c6fpwD-sh8v{a1-ip~KbJ#cG9yEXA5uI#{t7w|05q z&lYG;ozjQ@(?MappPS)l1p~u{at4MAFO}SO?q}l6)@Eb~5o_j{c%rKKhX(`07SLLp zN&o*(KTu^1I-h6j6wrJnLqm`>=sY!M5iQU>+6yJOot%t}f-jZWKxYt41l>*k_Wyrz ze0fGek$bi`1H*+(N5o!#BGiA#MB4L@?>x(yr$FOx3>SYfGfeym8$V%|TJ@coY1I#A zX06}MEUUgSvub^2X49JSq{wgVt4QJq6FhFld!AFqneE)tZ4pEN^1EZ^Oz@cI|3BdI;#Hu1 z5G!`i4$5F+*a=!A3#vmvarc>tVauXl^_M~IeNfsdJpF$oNEoHQ`mDv#LS)9JJ;VWIo70pFww>GsW*%xqCL~-m`2_nVjIn zaPc+h9CGLwycgQoA;_+H&{%#m!$ikZ_|NBqLgV(0Oy8nc20pp8TKwqS;~Rb7oJd1F)FbjjA@Pf%w<)A$?pnK|g z9d>#YJM7eA1dRcM#<(GC20&+xItq45LGCgD-FYCc<^22q^dHO&S{2Z7y=Ddm5sv!$ z$;fH2bLPw-Lg{ej8Av+(;><9ygppxOClkX?&>oK1KalnS=nMx?I_zL#*g3_C0lY>A zG@f#W8#E3BI?Ea~{sOvVK@>D!7X+F=m-+pF`T;Hm6VMpXe`bcC$aC$Gyac+tK~n1h zv-GO{Z^83>TA`c_CYDSAW@elWCi|Jhvd?fZgt#y}{6sbbl+MxhuZQX{WoIx2?TcGc zhZ+Wi{GSQ+|7T~^d?-sGA6{l=*n;XdQRo?#pgf51U;Eqt(-$y8!U7ZykC{caVEuJa zSbbw=Fol&fA0TUzwYGxRqF~8`TwnfA2c10&nhWhflW%ZhxXAPcRBwrD#XB=x1f}h` zllb!@D11R-3R*v#fn*-z-~S9rflJ_XQSC=3nYHQgZhLE5>H`V)Qsdnk1O zI|FDxca6hjP#X`{-UGGuKh>S>RyJOiAe4gW@r!sty^?}?{!CCr@04l-#z@^5tu(1v^EPf?1YZPYk~GV zg4(vh-yrQzcO-js7#Ku0vmnAB)V5TDwk^f~x`Er5pnd6*q7IX!IU6o3=KjkatsXSx=8kzKdg%I{yY#Ux3=m z8c_8zNM>yO3~nn6fyRGut;fe#F3&vifBJuB#*5#W8MHusjIYd0T35vwOpF;Bw(>yj zWB7(x-!c_y-#XCzETpZy!Mc%SqSRlv$>O38lQOESen@aOT>37~@bi_D#O#o#2P`}O zF$;p{(ODS^L2D>O|FWBVJOquuYM42J?>+{N^@wRLVFUHM#I$sn8Kx}YU@!rh^-@V< zw${S~mRcM?%vj$2pAH%m1daEu1kI0CSN#CXKRsZn#ST&b5Oj8klEiG#xDtn>{X_*( zho7J^KTy5Rz{X$_!pdL*T6f)W%BgA%FGEPBlWF&VZU*qW5zyK5|D_pr)-y@I{?07C zs)?B)36`2@9elUw@iEuLregWNGqs34Nnr{cK9aLgxm;xH> zmN#W61f?wzeg;9%`Ji8JGim;3l6?J$fguER78aT2z1B1vT zW>GEBePEz9Z=iD?K>aOHc!0vx^Wg!@lT1I%zA!R?&jbLC1A+E=D6%tzAnUup2-;VS zYL++?Wc?7bx(e_fOopFQ3=ASK4l_)20N-cA@DntbFVD%a6XIUT{KwAKfQw)a%XhxS4h4N1@&(k8NEU6HBi6oKQrURC&%%Z^Z4@1+2f!! zBTV4@asrzEtr|HdNb87t#zrJsB7_Xe1)$j6nU!2g(dPA3SE9xc4DsUB!QPNZJIg-v!lWpP8jsae><2 z%o49(sWa?kl4l5kxkIy&V3}6@?`1qAcXl2F!vqUZUgKs6 z(XPz+!OPGP#LwAqDdV7S_e&-I*;+pjSavZmn1J@J?-yk#^#1=pi_>uLH$qAU97r{3?ZO(X>UOKL=RYaGV*eR*XJ^d zWp|v^w8#eSS7m6p1hN~nKa!J?yZe9eL;po z(0qu6V22b_y~AbDS<(+dYc-e|CSG6#_wzR_6Yj)082g?pdIU$f)&5R5oFVwhZXE7bHbYf_@1X|C*`SXBfhI~U%2O|g9 zt9B;KjIRuqFPoVxLG!(5UJ3!Xxf%+{B6HmkBc^N_;C_C%~wZ%Z~tEHehv&Bpk zA?-v4@EV(~GOhjcKCaKGSZ*a_PA2FfQOGjjj`hnoS)BcSxH&B)d5mHF8Mq<;M1aAiF?qp_fYBv$cLQSb9}g{^(?55PZqcu=BMR_w0y$wE zfPm&x{h(o{K|z?Ai8}lQtxbo8)kTc3a;PlkVwi{&R+Wkz41ye-3==t387g35^)i`Z zA}Fjl7&%Xi{&k!TNk2&W$eCf{qAK}dNInw78fNyaqS>HugN0c#31KFD?EiGcIU|t0 zviR!F|408%_t$8+bQ9Fxgr+xGTEmvk%AjfN1v7Xo=qG3&6{sy@DeCZ3i5+~V>II2J zwu!%z87AfA(Cto1sXVd5)h>4`6xrB;E|JAu<4B0NE3Gt!If%av9)2Oh+P7y{C?)glj+0Fm{hh#E|d%t7{wK2uO?ZL~SvI4YM7P&nL zO`o8&3JNn&8r^;re;$X7zd+_DKmbk^Ne3H);0j@eogg`oe$f6V zF9wDU9*mInh@koeBnQ$b@!|h;5L^DH@sBOS4m&~Tx84J{>l%U%zXJ8)LFb1Y!dOp$ zKJNqHD+zKJ=v*Jz-bqQeV9@%U1U84CpnEq!dnmaz8ic^}yNuji$n&4|bqt_=Fgrov z2b&jy_4i?Y`7NIi?O0JzUmh|~0zTsm+?QvB_vJTmV3{WYm93z@yaS_@5U6js0LeU4 zNL+&Vnt}T2p!fsjBZj+f;4lY?;me1zM?vjZe$aR?c)c_D4h}|!tp^zywzPdhq#4k- z_5Z{C6D0|xyRv`(w?zK?zr~(|;Ug%0Yp^g}1l1$IlNlyTWQxuHs?0I*>wAWk+zbtu z%0cT@n59m0a$cJSTJIFE$nepFg&{;<(Y-Y|=;dd)1dDxO&cJcpXaD115t+;%-+*~7|k(Swn}GV`Onh0p*0TVduw z%#v93fEm>+n7iYdCBSC+FynSNrdc8=?t+;`Oc;D-mRj`{9A3h&S2BXa9u$@$uR&!d zsy!mBki-4#zyBeiF&kLegU&i3q`sPg;lg)j(N$ZS#7=|eaX{getCQ+R63fc=YMQHLY&^*nl|Nq5*bA#qd#b1Nw zCBHL?o&L`x@*2E85LDhGo$(HdV{x$k2mbvx;RT(!2XZr5j}&+h2Bv!<>L2|3ZvwK1 zlUexm>u`saFPNlGgVsQuW@HG7XBG#S@#V}6KeJgGCRQsmOx)GR@B@?|UW3QKC0>Kv z%EZJF@{3t`mF55c;-K^o8Yieg(z6*!56Dc=+Ug(7;;VH2{}%`82c_|?N(>iYhcm3K zR%W>Po15XM_M`vXcQHBqtYCKdsr(mx}Jq$ zBWUcSBlERIhA4x@3PuJK(7K?`|Npmw&j^5tGeE>M85p*Bu`*or`u~5c7X!oAdQjf^ z{eLUS9MHHZ2Lofb{6~2U2Cjyn$DlKo7#J*LJ|fmQe|-0UI%u8q9i(yBCx;<(TA=ff zK;sXbwGNZ*8yP-2u`q;y&NH&l)UuFog!FMW85}G#LFXSaGfdQFXb95&>wH;*lR+pm zGsj|;;t44aMoulrohmvOn*aZsazfQ>Gc*LfVP=>JQmgsb`Er)x2`P=t91GBSQlPuS zIb|Hc>Ot$4|2H#CJboB5X9)_k2u6k}pmH0sFN8q^GTsVVdk2~i0kyM1>%Wzd!hQQY za2WdOb4Fhu0BUFa{D7!4 z`XFwc1Uh#KbdC;ay)Wnt9q>4ZBNKRh2-JT7)$OqK0}2O3`vcN`frY^o28OMmvWM;4 z|LLIfNLXeo5!_N*ggxDOAn3coN4l9J%bdZ>x!_N*o zgxDmIn3KcL4kv_IFG$SI;b(^%LaYNM=H>7cbXFhC&CPEi`4N_;A?Xl#y$!>v$;?RM z#pLi4bnX;Pe=*2RHiw^}v#MZXc_1+^ho2o>2)i>uVtNigJM<7@DIhT;ho2or2(fr< z?m;>S7#x4B3|k&DG+YAR?*XC{9x+VRW?-1o$k=cx;Sl3Q4H(;rd7>%Op%3zczQw0*z80@Zq=I}sv z!Rk3s|K!E^w$SKf3pC&QL{CWcDTz0BaV6`dI-`rP?H9ds_a*53I+8oZ!0Qn<1~ z>xn?+BD15;M9><3NZUggboSR2&^aWawyna(1}V_kg~nX)J@Q+N89?@c?lfem1g!xE zmC+t-3?{F*QOAUI85l$wm>eu0CNoS7294=6F_?htSLSrsS9BMEA&u9MLHk754p@Tfas^I@oex0w zIr2OFtVhxhT6539>#!4MPWtEn(--{uZ(8{N|8x&l$e286&C^BD7(N5T1o=+ZpP=!0 z(0T&oI0dDXx6BNnGx0(DM1w$g+^$k}sL)n%sPJHgoWtkY$RL=(${6U=*eR9S$RH@6 z%21fm*eTV($l=|nHF!b4dRfG(QPV2U@0}IWiW8ji9qr z&E6yWeGCi@lR$MfIBhM2tP=yzWrNQ9Vip09$2^KvAD}yV%s3dfd|?(_HI|YrCAIOmwx}B9|W4S$pEdhWN5eqn%B%= zI{?~qXbKw72A#8!!F9kAG-s~FJZsitW{Fkcc`#>&iJ<#4Kw$zpM=60BeD>&0c}D4M zQ2%8=8^cFWCWa6$M~6TThS@<|*%&TzXnJYA5@y)h!NgGcf~_HlD^$$5OOK%f6t5t$ z4lag?Q@B89j0tyx)QA55zx4|<$Epq{vD2SHd!7F}P6oAQgc%wx&1Yh$1ht7l;(Okq zr0GeZFv7J@9JKbMl%e6$G=_#t#QJ*?(=@ohL20xC6jv+^8y)`q4*|8)LGcFKQ#FMR z;&u@I5|n0`MONJfw}T;Z@<5rP@;2zK97YC{N5Kpe!Rwry876)JmE8;sCh+|*|K|sR z`~XVxkn|3!2O(yF$~@3IHPC!;-8)2EPxuYEJqn(8hSj0)@fAa!U{Ko%w9jcJBg2$$ z|No1>ehV6>5eCgmOaZN*0?EGti-~BxhxSj<+bf?L7`7%N+4=1?#7^*BsF=e}&>6Cz zdz!%GOiYk-Qe@wP*WrNX&Q~=+_LHx&`u%_UU$CEln1S?w_QHbNHK4Qa8(;sQUM~h& zJ6i`TGnqkSNoeN*gX>{<9iRouKUZ)4pPs?SAP71u^#o|08ovYN9IBhe6$*@k;Jsy_ z@(om0gU9dD%4$%#2g_Hm`fA$&a9a+#7glFtJp;qXEP;+$9H9Pcr^!Tn28NG%0v)qJ zG-!W|JCw~YFn?A$1H)DYhK5Peps@^Ihsqbs45p_U9W2kWg7yqpnENv@Yxf-bc{El2?`?*qhN|XU9+I+&?En z;ewftRfky_LiRKAWH*6n_SY{JdS@MHWIPQj2abszuz1eGF!2P7l#o0lQ(+*8Q`C|r# z5ae)*X9T5--dUhAI1qc^Thx3HYHtJ{K(sF)oqCPtg4Y2O)dfE-*Ya zo~X&d@Im9D4Y)4^YS)9-GNmvy1cBNdNuc>zh85tuFB2}YfXn{}?2vUsu(SfnpP1)~ zg3dhRaAcbZYEy+XFkEI@bU^Hq9)y3Nr5xseeHA*kl$4Q?Op7I!IoE zp%8R0637gB9)^u8Kzk=aV|NE3?gsVWKxZM6;vcXbj%*V_?s#yC1?)D+K6ubt0)%@& zYiB@xD{SkcL4F5e&|C+@MVFu0-6nqxR*r$@Z$R@luyt0Taf$G^pgtDEPVcvfx*Bw5 z7z6VUbMQJOMYo;cF5YYJ(9*jKIV`fXeBH|Nk#AC>VqL+aR$-28Jsj@xRQBs}?vrSWZ9pe>&(+Ly&*5$@k-t zH#m=5F9(CePZmbd-NX#5I{yFv!0gC1aS^}6&xPU+I~NE${Je?BT##N)Mu(lJ7#Jk% z8M(5N*CK-4&&t4X;4`?61Eo90RSWbPer`-=n5gh?{)v^h|4&~b?C_Jr0wSjI@BRr+ zMu(rqvJO8N-Tpsa*aRW2&d?A9E7O*UJN#TM?eKGvyu;6h%Aoy84nO(s{hvPd_W$Yf z77RZ@cLZ#7W|*k)Z+-_Tor1y(R>pzcgyJ4?hMyaoA?{h>>|l9$kWMz;5otp@1&w}a@kT_Vaq{B{oK}gvK6I;o`Ai<#s>YH(9gZ8z<#5s|~ zLHmPX;+f0{^^J@SA&IyDPlw5I2teGa`S1P-V^)WsQK0Ytsn-+5+VvjwcXvK>E2H4yW3KLMASK>2A7@R+M7T{3>+OL*@M;?~`B0uAH%K~ACoq>4dLE|<4 zcKzCeO0+K|9mhNBzuepG;?2`)oez+K0@7s}vX*J}?~6oY;N(|MU;c z46B~acU}8ry35)}{myG2v^%YRChxNHiMaF1NBmAJAFzYYb~(F(fl2-v*uFzZc0VH1 zZU?Q2IV9Q*s?+dc1~dRFXP6im7}iW@WME`qVAuntUrc9Y`0)S#e~@xk1_p+VHpT{! zJcB(0n0{afp+obs^YY8{6jCdaQwvHm^YcI&7#J8H;835Gn4*xFlarsE2vMBSj@?|a zx}u`QN`<`Ca)q4Ky!4U`kkK!o>Khy&_JhPg*qgzXA&9|`!Ii;>!I;5_L65-52Ft(gYX@eLuiH-5ZVAr!_0L^g@`*q#V0`N1?wT=AE0!@CI}y9 z{s$-@W)6&o$;0>upytE)2~a*v-36$>7C>p3crHURLo!1?LlHwNLn?zFLkdF09t?tt=P`j0^QY*76dpnRD812p~zC?Dp&A5cEbehyuT ze_(Mc0p-KYQ-boL)-k9+`LH-QfbwDHTR{1+V$=r82h}+sGaS(PE>J#9y$6&JQ}2Vu z4?yEbK>4unPJ!}a`ZJ(>nE5$SK1{vfbwDTOQ3w1{0cPw8Z`a}C?BSO3mSh18h;NO{{R~Q z2pazc8vhKG4-2mgX#6WsKFmEg(D--I_z$3bSbF_{#%Iujq;FXI2;59N12`D#%91}Gn<{{oZ`t8X7b`LOVR0_DS+86Tj0n0f{ShD4!4No&YEx=AHs5ALjoFP`)Zu{SGK!1QiC$hNK;>cT zE1-Os`7@w=So+!k<-@|~0+cTawGZ8V^zse8d_vFP=;Z-=`GlVSKS1plh1wqx^@hpLn|4ywHX+6br~3R85kHq=@XPEb?vkm z^cff!KgAM}&gN7ypLmdMHLmUGGLk$B1gPIxxLro0>gO)7= zgSIULgRU(DgT5^TgDOa$oh^fnjV*(kEdxW1EdxWGEdxVBSz1YAQckKm$RP|Mei9lV z6r$=32_=;UsrhLzWef?RE?JI3aYptO)!gj+w< zd}QsJC6F)&IRRlm+;n7V2ADj=`M690g;!=#Noit^LP}3ce>JVY2fN&C$JYFXyBcNl@ z6cXYIb_D}0Ug4<%8qZKZc7s9bAC|5m5t0hyG9={Z=4C2?(ok_GC{-jN0tp=TsmPHE zav!>UbS#RBgxtiu#Prk@LV=2|4r`!->_db*M#v#Tp8+|3VBwDz&d9167!pz{^AdA2 zlNB=aGD|WOb26(^ixkrGixgn#0w$kWl3I~jf|UG`Re{nMxL8xb>o|}z|sXYzn5ebr6#5zWqSr#d8VMG1g<*a{N()j#PY;UXfX;`XJZR0#TXbALMjVV z6|6 z215p2C}vngJiD}gDwNC?j=Tl4nsaeGD9Lm4nrnG z71%GC4EbO`Li_)MPL`FG88iu zGn6o7fJaIa8B)-~4;BW5%mbNG1di2ol<yb^sZa>IA*eI1QLmop3Ln%Ws zI2FV4ND4zfLpc^VVK)z?H<_W70TdG@43!MJ43KaErITESG=@@e7=!W{C~czV6og+v z2`H7J0vr~o`4!cLDGZt56razK&XB~A&rpHIoglM7m>BaQaRBi#C_RBf6EznhLKKuz z%b=wKXq+5m2MA|_LobgZl_3W_ehv}?VUWvVV}Kw&_V5FV7BJ*8SZaKw{ zplJoDGGuYLqSRDmzI$p(SYl3TDp)Ba1H^2%oZ?_)anSex$Xri&b?;o1S(2HYm=m0u z44S%dtpMu>^_xNJe4Kp~3xZ3EGV{{GGH~(yn8j@O+o0$im7x7Ik$;bzHOtKgf8FU%E7y>{V85kI(A|JvK4&`sKfz&fwp!5zXy$4DkfYL{x^a&_^21;Ln(hs2Y3n={qO0(EP%ol*t zGEiCpN~=I=4JfSxr469836!>g(l$`q0ZO|-X%8qJ0Hq_KbPANtfzmMZOQ8H3DBS|3 zCqU^1PfC0HrOUv;&k5 zfYJ$2x&TUdKN+&>RnE3@zegl-A0Hqf|=^aq|1eAUNrN2PwKTw*(0pczNDD45I6QFc(X&!@b zejY^fnG>5^lG@T(h zwSd7txrD(lzl^~pH5shmD>1J$v8WQHuL#UwU;yb)22EBv78GTIhBv%Q^T36TS7}Zq zNRwk}dTBAV0UexLP?DOPlnNd=U|;~5pAX{s<(DA~gY1Lz9eo)X0(?OxF);Z0>ZhdW zSAxw2iKL{Yr06L4`uh4RfEbmPP$>@&tK3{G#LP`FxO`?{@CCQF7#KnrN*O?o3};AX z02MqT3>gfips)hhi3|+E;I* z)cJ$m32MWF+Ug7p5cj4s(6}m0 z4rDG!FNg+>PlL<_)x{t&(D*8-o&{l$IB3icByI|Iiz5RA*j{HSA5_1B^nmJ7kUEh2 zK{Tiy1(_eoz`y{q8@WK`bOo*zZkpTfgYifwW$R;!~ARrS1aS)~-JXABH(?COG zQ*%peTYE=mS9ecuU;l)OlO|7@I&J!lnX_iknLBU(f`y9~FIl>5`HGdRRKIRx^4T8ox67L*}HH5frEz*A31vL_=%IJPM`HPpYUcY(!?)`_4pFV&2`tAFVpTBzmLg7{P@0T~ngdJuFT@Bk+W;;j!XUyRzyJ{yU=V?`K&puJ zFjScU1C#-!i1RH%l>h^R4Pi0Dx~AZI0LC$hfb_FKZ6T0^1(XkJkAe6OP(G+#2I6}_ z`LJ~W5l}v;od%Lmfbv0YG7vul$_KU0K>PwIAJp~%@hhNwP}>N^Z-DYaZ7LAI1ImZB zWhOxRptcrBeg>2eTSu?}$_KUkK=Lb~d{Fxj#NPnrgW66Y{thS~)E)%!4?y|CAPxfq z!wD!Kw(jEsln(KCH&qfbv1@T#yz6C?B@Y!2-&Mt=n*b@?q;L zJfM8gyfjFE0F)1!vj*`apnUM83uwLx$_KS!LGl?;K5X4Y0hAA#_Xf#VK>46KZV!^ZUlpnQL*yabdF>ZgE&6rlVt5C^nw0LlmTS3p7rP<|AM16s!n z<%9b8ARz}RzaGS4U|{fo@)@B8Kme4_1m!0{`OHv$0hG@IY(B=ZEqcq9N`Rfbs>P zd_gFG1JwPX3&cP{askR0hRQ2I)r&y+22j2zlk1~`m z0OhMd`3g|JDwJ;k<*PyY4p6>2lpg@)YeM-6P`(zFUjXH6L-`F*z7CW>0m|2f@>f9l z`cVE3DBlRmKLO>NK>0VId{Zd@1(a_F<^O>4&7pjbScv~EpnM4^-xA8#fby-Nd0LpKK@-IO7;QOdS0jSz6X>q1?5LT`PNW=0hFH&c%3lEGvqSkCpnOg! z{{WQF1?69W@_C^A2T;Bgl>Y(Bw}$c=5+VL&gf{R5pnMi6UjfQzhw=@ed`>9e0m|os z@&llJ9w!D8B>BXM{EwXF&O!Q2q)ip9{+00p;^R`6r-!DJcI2ly42? ze}M8CVGYV8h<`bud;ut*3(8l3@};1B11R4b%J+cs8KDi#2q>Qu%FlrExuEtU^aqUZ0dXHk3dH|h z&@FHhFg~;asR8A)fEJm8+J{iS6qN4)<%4EBKqe-EXH6KuYjr?;$UL(%g9mh^KbZlt zDF`%61Cj@=0|3#W^#l+aG+P6j*N3PBtvdpVr-5f}7#K3ZvrixzH0#8`kO?&}6FfV^ zzyO*D2dM|mcZ29W=nP99Lq3ShPypo@K-Gg*>3}3aGd3U^v`z;^7c*poD28H&LMRQI z^HET*BBUbq2?wsq=Ch=q543paXjleojzH-OTOE`u8btX~C6KOjD6-Ug%vl#X;6JmEV(L9>{;3?2-j zAV~&Dx&q0A=666sp!5aehk!T?3=E)jrOV(4*Pq9b!~o*M`eC4Srppijmj|UckbhzJ zgVLQYLl6T@Jt+Nw_%QoH=@8@|n0iop1ce{W|DbfK%ist%znGy69KNvd0IfLFWe8z_ zW^)EmdIj-e=7G{J$bB&LK7)ca&lm;wM+JCY41!<9P|BdofZ&7j7cw7|&vY5w z8DRbbyPJxS9SR^!2AhXF@~HjK=~8oK3F({@~JL^H$0t#@+*iB z%NL-03*y7<2jyQ-yr72zC_f{opCquqJ>lUA%IC=L1m$;RJ}BR#@%o8Js|gi2+iMAjc!5JVBTMDOW%#4ia*Z@&#lf zB!v|+Ktjd|nxpc->nsuRnhRbX>jw{KP<;h5JrHU?q&xxDQxE~j{4~OSpmm%e+ae&+ z43P4~37#$>07^H=`e5Pa$^aR`f`p4Jyj+IV-yZP%1PLccxVs_Y zo85$06b549|bX31GN4b zVK2m8?r?X*+yyHiA?2+Tk~?!5vXDx2i2W|`^aHWq7apH5`w`_K$bLk6gV^tkR6l{j z0pVWInqyG?;D{0b5O=_07UB+HxH}=??+FbhNV^GCuEXkCh(CRyvCF^!34f43QOnU{ zhFtIpLRbog*b@RzKM;Em`3d457r6hC%|(q@h`Ffl_lK`Aftc%s#0S;;VQ~L|+yxSW zr3{F>BH{87{m$@m1mZ4dBzHkd9#s9o@N@*x?*xxmh<;eA1JygAc=Cdq2T>maPe%~- zj_`PexX%a4J)m?D1z%?gQ4h;)F!Q~Uurer9!Ti`q}~tSu7b!1!2J)&7oc(wQUik01*ph`jT^(t zd)PQVw422+p$O6sfwZ<67+~{IAiW^G04je2#9?4y*Z}3#Uz0#N=XC|?1}UkT+KK>0hNdKR32VFL*-%fiV;xxMNs`2P(EnA6iBE7%7>N59Z>#ekR)iH2+Cg# z<-_JVVCCitsC+k69yU)2o5$P%m50sKz~(KX!)gpCpz@2M`fot_XQBKTQ2rVy{|A(R z63XW&g@pGcC|?4~-v#AsK>0_Zd8odK1<2$f#}<==(!cR=}|b!Z@=6Hxvs5Ql+*;Rcky70Q1B!{$k0^QtGH^00X}*t{leUi1c39<+`S zWCU#96gJQL0xAz$KMazG&5Oh4&3{1Up~E^1uz62CkYWY~299z_ctS>57#Lvl=&*Tq z38?%OsCo@3e<_r20p+iQ@;#t@Sbr@7%HIZ+&w%pxK=~Tbc{kX+YXwxk11b-j7lqB^ zc0lD}^N_H4e(105m;V8khm8I(Fu>L&z}78rR6ybfIt<4E zTc-e9#~=Zfp9(c!1ImZ>XJG3XV8hxLPL& z@~1=PVe436>s&gZ^1V=b*t!MyIt!>g=nMjo64<&I=rjhy3aC7!ch0~7TL%MMC$j@8 z4_k+D0?MBOG7MBdK>0mT{tGC7K9v6h%3lHH!`9Wn*4=PaLBbo>Ux%%;5r?XmfXYKg z6Brm^>n5PX>I@oC`BtcU3n(A7-Wnw20p-KSI3u9^IUq?8hNe&0I-d-vd^AW7w2lHQ z4_kLr0hI^ssQ@YIfb#c&IH2|llz$k?UjgNBfbw@h`8%Ne6HxwXDE|hOe;mq(ts{c1 zJ9+_?kAcd=#`PaV`9GlYhoF3cYDoC*h4M9^{AEzS1C&1#%7?8}f~{+cfXdH;%4b0N z&|@+fVC!mN=h;<2!_g9Tnsy)@}ToJK=LP`e8?yy0|RWG6>MGB4XAuPNHJ)h85-Z9eFY$) z7f^ZVGztT3-4%3NjNu1V9<*l#q#m|z3%1USqXrWG2_Q*Oeu0_~omOIyfXajR4S5`m4ro6DR6T5+mIqWGG7G`L5CP>wW=$9vGN63eI=~7j{}I%@4k&*Dls^N?2kln? z39W$gH-R{yc`PV@6_kGh%7?9!x&h^b_TGS$K*nW3JHJ6ZSidOrHN$b8V~H8Q^v$-kiSaL8yNXe<>r4hRu}kU8MJSdbJ7nvc?D zNP^A=F)%>pUqB?pe8_k)=+pohAJorJ0*?tHn**7r0rmPJ>Ok{(pmPRb`4Z$7UGRQo zh&*K8CIvbh#Q@&-s|$7)Odd4O4BD5D%m-1I;6X?1!~u zAmcTO(Ah1}_y%ZvB?+D`Ao3tzLClBoVfhZi2kpN`md}L814KRx9?uYd9-8?D@N@~0 z2aVPvn+Mw0h0I5!bBOvXcsc}yJShAS{)5C5ET2N;lcA%+Ape5oL3`j~=0o_X`ayfb zk>w$K+dv`^^FSns2Qx1nI(rD?XFz8IVfBn0i>d55fnHii2cf_LaiZHAKD)$vn_FJLrr`n0nBB4@eb+51EI`gwAdhHpQXd&Bbyfk=ovWL_Ay`T#a>j7UF_c_I)AQxCEqSv|;n zM0o(pIiUD}lL0=4oIy!1&1Wpb&+*2qX^*Q3Ssboc>|sETHjfP(2B<15}s6>Q!WM zS#4iWu57@X6s6_xV2~q+==4lb> zu>^dk4l+N3K^MMC1+-oT z$l(JKfsn}lh0N=h!RrUe{5!%ukof{oc>)=ULhvCYH84Iby+imJaQ8s?pc6$P?uGD+ z;pGE_UjnZ`A@ltR`yU*Gw4)o2Luk;<5oiu9lp%xxHg*6q`G79ueB}Z?2t5HxGw4J3 zAD}cyEePXMKOqsKKEMD%yD~U2fcCy8F@!OIS{1PVKBjmKc#nB5gBgPfLkxo}bVoO6 z4>o8gz7zPop>pWyHmD{dPG<(W41%i}+!%}*3>XX<%o&Urj2O%qK&u*D8H^Y}Gms_> zMhun=rVP3a77R`dE(~rAx(o&k1`N&&#te=OmJE&z<_xY3CJfFDrVNl7f@%gM24@Br z1`7s9uu5|V&}_aTg9U>ngD!&!g8_pjg9~^C2S}X-gD%(|$P`d`I5U7`%^6G>3>nNAT*0mc%?TPZ7{JXl zV=x7~-;}|L!H~g(L6^ad!I{Aj>?)8xP$+3_cYL)KV;A z2xb745D;-lOhZUejRTT_@F4AQ(AWj2<&pso91Ex4+L?EWJ{=9z)5>K4wbDT80222KXsOSN0W!)1nyZ1$$GE4KIF}X`rRJ3cBqnDk zrl*3k7y|ap~b01 zzWFJsIi9fLMFwwhegd610y)PE*-Vg^oxr&dR-d>sRDjPrDFv4<5MQ~0&&UJy)In|Y za0XC~6~+Ksi4x9W#1PNm1YX@3&H!5Z5yTMB;K~pIF2_MNt0RLGgAao%Lp*~UgFk~0 zgA4dp4v@W}&>GAIJVubnfNBc^1ExKoGekgldc-rhFo4!2Ibt!DfguRILNt{j5p2FQ zLk2j`ApQrHG^q?};1B_oqRH^y3dltejA?HW_zn?Q21l?D;~79}9vm6`pm&SJGl14a zfa*4o+gus^7@WatHj2S3m_c_XfKD_+ggPSLpjRijR)C@}v&6BW01UnML_|pd)U>GfOi3 z!56p`d*+p-7Ue;YZg$DZaZbz&&CAJ8O!3PvXJGgMX-{!L=^MKse1k3s4YGrQ!2o>j z3xv(UaAPMU!-O_Q&>b=`Aq*O{USUNWh=fS(Kw^VLKxTkw5dIInmj*OO3^Era2Ezyw z7#KF}WMtrIXJmMQW)@5>hz1o03hfA87VV4-=yrqDfy{!bLbe}dK1d#hVQRqqU5pGJ z?TicwNalmZkqFSZ>jEVC1MQ3qxZD8Nwu=#bmJW!G><*AUATbz5c1Of6Mh1ZnMurzi z_Q2G^Xpnl14iE_uu|Q&jL_lVMXb?uW7i2C-42BUVFfbT^{NKUIkbq_uOf858h5rI1 z`5hhD!yjZ8%xq-)JCO8(%uB8C0uPaZ%++ULVEEC&$nc|rks&D9CHPbI<^_h|ugLlM zxF`g;IO&1RgXRPypZvs>)FQomTSdhZNa3O_(;X?`ogF`9#K6Ff3Tl!0=%`14F|m28Iut7#ISMF)$Py zXJAOU!ocw0HUmS#TLy*$LLg6q0tN?8cnj&T1RR6VIF!MKAKZqhJ0Jwf?*+#pe7FKM z2FUu7ZbpU*P+Hi<$Z(+xB!W-`;x%?NGBoUBWZ1Bak>LlLJVGUQmOwYi1O^5CQR%#i`z@pq6q_YPvi097u43Hz+mTzaTZwJGIia0wfTW znvQ7yLWCHc^FtDgvwc%@;U`eSMchDVPdd7UIRSknk)y>F&nMA=lVM!5|G(UASGH~`VGN|`3G6eL1P90)mU}j)p03DE= zSd{8ilwV$)S_EzA7c)RA0_Xf9SY=>@R2$%zMXD=6{RGFd#LOJfne)hop;`wy7?WW| z4j z^b9Dy1xlZQ(pRALJt+MKO8eNO+B=KS(&xJN+>* z;JUG}lL1^^c_ikg~Ax0PQbtPzL6*K5Fy5=S4r=$ktXM!5{491ME zAR1j6Ljoi6C2!@7Zkc&0VA~jK!ECq8qGIrP5xC~-1B>~kR)B@V8Rjq|PGO!4VuNeH zc_0?7PGy)6;=xZ^UdZT{Q(Bw>a=cS%T3TvRF$2RIMvyk7$_P?<6o)gc1wd)Lf7jhL;F_ zNM>%TV=>6jAQpoQGsqT5Q_2I(2BilE25&GsC>0{(3+92wDj68!m_2cw((Ra+5?qj( z=bT@fSHcjFTb*kKLlTl~uuo=jiAQQ;3PTz*xI3JapPZeV0#2-8Ifhnd&*HGeoXiww zP_{};Pi0umjC2NgI0M6WW}no=vQ&&bwuc$i*MO#C*9u1lhP|jF;S3D>kVV277+x^@ zmgbaXI#rgWhUAB5rldM&Bo;9Uut3tPOKMVSIwY5bGcdTYfE%a*sYPk|MY)N2$*Ex9 zrxr0pvIHe&7N@!*u4-M$g6sa%vn)X+IX?OM*`)<;rFqFEnfZCHc_l@a3=HQ%G6BgU z`JfmBg;8n|!zGYdXkK|{UW#i4gEDI{WK5Hw1|xrCDzfKez;*V(M9gb5c_a zob&TiGC`KXazt=YI71IB>}d2$NQGQ7(=pLwZFcENoF)-X`4NuGlr7sLuFfjaMg#~*^K0GcM1lhuiGD}jOAtgsR zgAjxd3K<4(*C0PvA1rNsSQ7(<=3)roU}tb(c-Z{p@r@V;1_1>|23S8AM#D6KY9tW8 zFrASBGzJ0_w-5!1LU;$D3m(}R0yscp42@47!_75ia1hV|+0}TVN#)7o$3hGa0^DH! z6~-rzA3x?`VBmPz`sA?>Lx6xQNWA$X%ZVnnCnrK6=lFhcU|>jbWMBw@+V{Ybf#C%b zpM$}H1JscL*{Q)0AixDS17a7*3{VHh#EF3+#EF5S0BVMY69YpDsKX59H#jjcbRfyY z_!FS=>X#FF|EFK01frlW*V^BO7z}Yar$D}hbRHQR7tPuyfih)4}Nj)f?7=Y|* zhq%L;Awa+m#D}IEm>GXE85nZ17#Kc?GcsJrVqoB8aNq##=K+NuKgi$B2)F(KEu7D0 zU^oM{PY_K$ppbzfrVt_T#o!=d54IDM23Z*tI6#S%mq7r-F9p>M3?0>wGp9kcJ_7^C z69xtbb0{qdva1o{mX2lyhBM6!3?dSYU>X$fpnX0dcZ1RwD?@)%?`3)oLj9#=2~NaTaqotM}zf{oMwrx8$| zZ2(;a-^swhA<4*K(#gQ!(ZRqF(aFG|A_U~rIN1k)h?g>D9h3<-$2TuA9(gTa9VwAT!jglrfbBuqeNHeZ5z zU+c+21_z0WAhAY-SQSHn0N78>pddn&8&4)NFmOzP#E;Ds1_q5O3=AL|WGjd^X9y55 z0-J>>D?oB3Qy3UHrb6^dOl4s3XADp{B>VFr>sxEw&ze_d4K0MtBdkbApP-5YY0fq~^11H%)jnhb^nfrpJ3 znL(k`%iti<0CHbsPLQ`TVq&`^j|Nnm{P`I5y z4L2{a9TyIP>Rm;Uo6zblgF6fiHFp>oIHW)+A9O~%gM}i41M?}KlU*k{PPCn1abkah z!eL+#f|gH~P+AyDdq8PO+IL_8C3bF58PxoQL7E`|TCX9>!-B^Q3@wit7<8a^>oEif zfa@W&e5~`Ffg$5LBE3~SXJD9s#Ls6iP{5Tp4>1HNfc7@vl23-ZSr;un9o{i8?0Lt) z-~)A=8$*G_!)DZU1PZa7_Y4dx-ZL;1K-HbW;}#P}-0t+lk%xT1aoTc%sTC5>C;tEc zACJclQ&1eESRA+cD~T0_Jj#cK7Opl z&>$hq(7-6h(7*`M2hkhG;Ght|;K0Q52xIB2LdG%y`de#Gi}$>o{GlLN{S`tf5$h6Vuv z1_wqt1_w}`qVmK^<%uLHJfLA?$>1Pi%5Z>@1>$KIkgvr-@=Q*kV&Sn6LxTVx!vO{X zB>VIj93-?D8W@=$ffO-=6}m7qNLVl&V6!9hX>><6%gVB#!; zgT_>b1}3&g?Cuxao;}lg!Um-uKXzwmP|#;^V6ta$U}A)YIU^*@^%)#AG(rAUg8Nem z=1+c*o57|(eyq*lAfXJ3M{rPrLhbQm0gyb%xsM+|Rt2#k(f?Qt#0IN-{8$#mhKegN zG)RauG%(7bnPbPWKmzXU$B$uKml!gjn+{(r0p)y1zXwKw+BpnM85uN|qRN5xO@iif zLF!=rD$rih3aD8iaTva_6QUPc-2%`AA4~z1hPk5v%`T8Ms2w)}B#y-`AbBv}g=xhVzS_ERte)y6D9s*e-5}nIIBwe%(T_jzCrh zhQM2Kw-gxSZ)M$ronin|3Biq*Z`^zElYzmo4x;mc6J(tXq=tu#VL()(vSDJl=o{N0 z<_uPO40r9o?%o7fi1-6H2>k(iE;ojL0s;kFA^HtAKxo+cOW3r*&M?L%M~N7d0%>tb ztX&{;LG>}Q>anQ@G9S4^!l!fw1H-@n|NqZ`#>*Ax{uoN>dMKC!HTMS8TvBP! zIyw->=9i%)2EE1yC&h#Yn4tjXM^GGr+F-Eq;)DVu{$TQY_Ksmmi7D}kpv#UOic3-) zATvPN)TP2E`Ut24n^#nnSQ(#}S{|R1nwMUZ0n>ubT#$Nnv$3fwsVqp1&&*59hq@8w z2M~Qh3gWLjQ2GUw{sN^zYCt$e8ltWMN`u5kF$EzYz`*ck79#^_aqE{^j0`gb85lHX zGcs%uWMD9v&B$;-kb%KwHY0AJxC5d^7#N<+XJl{?Wng$SpOGO!jDg|Hd`5-}&;c$B z7#R+TF)%Dxz{rpw!N723AtQK!?VW{;;6=7i7BVtCkY!+avyhQNLXLqUW)UMph8zP! z#v(=r3wZ{Hl0}RR9SRH#J&PE@3v!o$_(}{6dloT*7w2AC#K>?*m4V^IB1Z5+U7p2^ z3^TMC7!(#WGPGzjFqkZ6WVoWuz~Hf%k-QOcgs)@8 zz|gXUk>Q9H1H%N6erpDXIZGHBc33koY+1s{u)&6bVa9Yuh7UFj3@kGk8BW+TFid1f zVvMk3U=W$X$N(CTaAZhiWUyyo@MK701dU_(G9)sB#t%TWg#!bF$_z$^2q+C&m~6?A z$hgCSfk9^mBY57nUBdh-F|nFq4sC0%)FgCL;qwJOjg)nT!lG;u#obGCW~4NC5dKkuf6y;+_*= z`T+w+BFOv)3^~Wpatb0W-@{ol}Iqp%7$WE(1d# z({rX3`5^y2V0@9!z~IT4$!t)_z%XGJBSS+WB>e~!f#N%faY7LTLnuQM;|nP5P|U!v zVHP7pMhVEgRHhpxp!D*DF`<-!fs-kfX+}8%Lo3Lh3I>Lw3=bGyRDkxbJz%h?WMGhG ze8M!Nih*G+Ln5O^H3P$eS&R%3)eH)PDUtC)3j;&TY(|C;Ees5zj87Oj+CcJ2j1ldieDa8K zK|3ftKV-bo&cHBXHY3B1P6mdh3@J>YMg1>kGcth2-9Yie(96KE6%-%63=B4N7#TM7 zF)#$oVPvqF$iSe;_=GWH5(7iZ97YC*DGUsA<}flSOl4p=GKY~NVHN|!MTVEm2D2F$ zp3Grn0L^(?GCTlZB;3gGfT3X?DBK<}+?WSSqHO$4b7j~Rc=XJCkANMsCH01{7P zJg@*1j!BFL3nBD^g`n_z%&4&llz*Qv?pVaY@RcExdBbAR-3N~uHI{(#Q4-^fB@7Iz zOqnd8jR}mC0B=z61(l~OK;e+ccwz+ugUVb+h8-&z7)<6e zG8C+0V0g;#m@#5CBwcM-4GRB6#s{k*?h04~DpwvbNvvgHc*~H$#IcTn!C@{VL&7=+ zhJ?9{3>(%lFf`0%WKdYoz_4I0BX|?Ufw_#}jS#L3NsJa77#RLCq_bIUgrqOf<_K4Y z2Mi}RF)%2C%C}7r|0Zl^V0Z%3x0QimB|{?9jBOzQCow8)XJGgVLvDw5*Rn^ zXJDuS@j>&H^B5Uk90G-3B4fZ|NW60#0qIL%$~eNnaAO`LgTYY-h9C17!J9Y~8DB7g zHgc3QJYjrs9F*=77!6K<<^mruL_q0=6CnMGj2}5z`(zp%EM~RFTP#Uzc#E>C@QQ!^(L(hChh8cH2@t44O z;tojvW5$fTp#1QVvEUv9!%l`YCWVI#41tWPOdlSB@<$@0#bX8rjs=ViD;|T?B{3>I z0p%(+;yaaT!BYl?vkYlW1b63hx*gRxDs-xbcpG;RHzEdj^IN3m6#`J~J@zEM#Q(@STA{ zV<97h#!m(YhlPv`5x*E1LKZSI-1rSDe;+Ui{9#}ySjfom;t%LdltjjWzo7Ey0mFm8 z3=C5iGBW&NWMtR^QqRQ5a9|-L!vtnVhK&qKOb#rJ4B&Ln!pLxx;R#~|DqXHiz1IHpph8cW}3{x4B7!CLt z84?*1nI`ZvGUzN~WQY)CWJqO5WIQ0q$ncdRmFa~L$h{93X9zPgyk&UI*dfBmU;}Dj zi83;Ln9c}Z)0HxV5xg!7M1$5_otVK0UPtu<)Lsx}WKfyO2wt}|Vaf#>>qx_K+0*nlxNfikO2DJ15+C2!`#f>Qrx}Ozvc6$N?6N3h5 zkuO?sX|S3wFffEM1T(}lfNpyTVhCpNWbkM3V~A$}-8ut07XYMXFU$LXkkL~{1{sD2 zpyhX98aC|>S|f};2HL>_(g8XN1=o2a3=An?HK5Z*Kqu3H=p+WvS-d_BVhoH7&J3WF z8$qWy=G>X9| zx`0lO0G$p2ImranZUXJv2c5A6JLyG%!Ic4W(hG={%K$pP1$NSp0t4#V3<_vF`4v#k zssM$d83Q+xJJ3&30kuQ*7z`Nn7%Ukq8H^b87>pPor>43w2s40M6L}2Cr)VHT1ND?4 zBNTfPCmS#@Okgl$U}W%N0G+;>$dCgLuLAJhHJJ?Q3>o0F1VJH=DyD$t1RPvpt;e9i z;K%?vRY8FP6z33Aiy1&X&{=w*Q#(K>yQDCH#*Y2K{_=;a1f6&Tauw`M8qm2nkk}^H ze|6w^2Av|2&j35G1`$fMk6$Zr{G!^A9?OOd*yGrSfeRzO2Qy@V({c$?%EwIiu=I^; zFL8Q7shWD}JC8vVoW4M3dz3K1&h|(L=U4-9YPMtmFM& z(35ylz^Xu}gMiLtN@7T6Fk?t!NMkTzFl9($uwXD?NClrQ1)0awU|?ckWbkK51D_U| z%#g_dNqHfx%*d!vc>584C&)R4kaVV8((43l1zev7lq&f`uCv zCM=RztgzT%vBP4I#Q}>W7AGvuSX{8UVsXdf35#beUa)w@;th*;EIzRK#^M)?e=KHL z!m&hPiNq3(r3OnamIf?MSX!{OVd;dW3zlwJdSK~=r4N>VSjwjNxCahYpYQw4nt1hg1 zuOpc32&-I$?Fe>W0-5Rxen+VfBI47gj%5{b4o38i6$mYYf&ntYI)< z1dX;Z2rLGLk;YARSK&#RvE0aSmm(FV^zSah*b%z zGFBC=s#w*qs$WbA3t2}+LE@NHAx{h@-)~#5#W8H~$H`cva_hTK$dWrQK>n+xMtdCfqvA$w`$NCxTSFGQ$ z{>1tl>tC$@0lM%ZfRRA}w0UEJ!~%^477IKUL@dZyP_dw6!Hfkf7VKDXV!@3CFBbe* zz_Czbp~gasg&qqd7G^B0SlF>}#=;c~cPu=y@W#Ry3x6!+SR}DXW0A!ok3|uSG8R=V z>R2>m(TYVo7M)mhW6_I6KNfK;mRPK@*kZBA;)ul=;CwP;@ruPe7N3CT5Drl8SYoln zV@br4j3pIII+n~>vSP`OB`22LSn^`Yk0l&SC6;O|wOH!0G-7GS(u$=WOJ^)yv2@4M z6H9L_eX;b%QjTR3%QTi*Eb~|vu`FX*#j=iNGnTDbwqx0eWjB_+SoUKX$8w3~8p|z~ zdn}Jwp0T`QdB^e@%U3MlvHZmH8_QoT|FN87g~SRC(1H31jNr~+z>M-o{aKM^`H3e%L)=XHlV9ka#2i9Cz^I*+~H4JM7 z)+($uSnIGhU~R(Mg0&56C#+qtcEj2OYcH&Qu=c}RhIIn#6xJE6b66L!E@554x`uTV z)-71KVcmgs7uG#k_hB8wdV%!{>kZaBtPfb9u)bh@!}mRHK9n`{5 zzzA*=F)R>Rps>JTfy07;1qllZ7BnoFuwcQ04GRt|xUk^Cf)5KA778p>SZJ`&VPU|+ zgoOnQ8x~Fgm&*qhURd~G;fI9`iv$)aEHYT+uqa?r!lHsj4U1l^`LIS{t;AY|wHja_ zc&rUr8?iP4bcs#_sC~`A;IPbNS-`T0WuS5hQvQH0+hPPwUoaFb-Ldq>(jQADmRT&z zSk|ztW7&jdCzf4U1}b+sRtT(+SfQ{&V}-#AixmzlJXS=kNLZ1vqF_bEiiQ;(D<-Vi zu=2)AhE)cuBH*PMs0?Fxz{mhvgTSzWVH6Ca5Llti09rxMV9=yIn~hVe&7egj@M&V)7(##Ck&CPr2UgBUh0Z8k<0#wK$nMwSJB20jMjNFw|O zoXm_23s@F0H82<$qUmK(2;z!=vB)Oh`_|F4xh+SwJPUJ@ao)ah)sDSuRcE}}%KCXh z6K|tI6YGD2Cg$f0n3))vn1qc%d$B&&PGaKo`~kifi187~Sg2zexmg(u>I}IJIN6v( zS=fY`LW2#34Fo|P4q>kF#Nv$1y!4X%JVOBkK9C^0FndsHN^X8$ilLl=3`m4aSkyN& zxhTIlKdnT;IlrhNzbFy3=h#rgKn*0%EG&;KpOUH&oSB}NnU}5*;OwYiWMF7$AScdi zWMF7yXli6=Y-nO0CC+PPXlP_$1mzl((8PUE_cP;gzd;kD5^_K>vNA9?G4eAQG%<29 zH8Cb29_ zlOHUY6e)a1(Z#pH*=_R4Lkp`9=SO5m81ZNC{(0#Uqsfu?wvs`NR;7HZUu=(F0`!1^pYX7`=ytJfX;1@#}y5q|!E!Hp>%|6~H+y$ICVW~|UZH*K zvgXq3-K-f#eyblF?mk@n$VGJb$CQ`PDcVcbsB=?BsH}CSN-A{-l{xo)iXTaNI(jkBjPdg%VO{0bqQ2YX_N{%VlM{8dWPO<4-AQ{) zD>Tdh9DTC)Dx?1bTg}AG$3B}*dr7JXZppNG^6~b9EemTtd?<)i^jcBoVIMh9Y?5># zM`gf;o=q94%-;{}7qNI2+hFx**SxcT5B#|CU4NMr&!0_4%WOOBPdWYUpLjzi?MTX; zu4dJyDc6lYPTrV1E9aM~LfO}o`5X2+{5`_{VeVtc!mRi8b2N4uym{90VDX$+@9frb z?bx5NIc$T@55a(xMlQGHCvUBiFIh^t&wCfy`?0buVMWTxx{dRV_GB6LZC`Xo*v2(b zRlhwtJiA%5CV64lmlEsT`_Gqq^Y8!q#63eU^v6yAjYe{RA4=pFEBn5!`l|lac)~q7 z{@GrP(PkdIcjm00V9>-~WzfW$1gQeJ68R=TZs=r2ODqPB9W*IgjSLJxS&~^;6Ons^ z^7Bg+oKuTRGSff@uBIwDmX>7X7iE@I!YctoLj!XI3nK$lO9M+#C13{T8XADO171lr zF=18*OrYw3iHoU;iIHLThhIekGJ0!oXN(yohLTmtlm`JCVkUxV^8dhPX89EPYd-UpG>gUU1uC|bi3U@qsyC_ zZ8vUOKgpu*(%c4}uYO?@6-`wSTjr(I2k)B0zgAMY<@A?b%x%5j<3C&o+TSy!ea`{K z64iJKjcsStH7rzTSbCYAuh}?hos9DGm1%Dh<+C1Yc+QRQc%&M8S<%}r=*ZS^dllvn z7ptQ6uPQ$-h~*D-E8qNs;o+V&Oil5(4~TBwD}5!@`?=*p{+G(0dn9(a)VMx5c(|zQ zLD6%S`}^Hy9({jECj54D?;BrFgXOFH?!Sqizy8nN4QY=KPH(J!d+n|Fb5G6X!Wzq# z*QPf->q@GK-=yDiJ$z2g{&EeCk8g7iYxL{%JDB?)eAw#Jd4$vF=#{0;`Xy7p=l!Tq zh|m#^O_(~%&fmD@)`kx8d-MFhOxv)>Z9&eAOAoGf^l-zf!?y-aj4urY*f^oBJW)m# zW+p}kr1}qQWh4pLAi~7LBge%M%uvdZ#Nf=}Xuu6B?)h0j#r?x!67CDxdfa*DLWfyN?9B*UF}6eV$e7r!UIW<*`Tr6z#e8D6Qh_hKI=f0cS?S8v3@~O zW^Q6pWpY8WUPei-fdkwCCIb^WBL!Kc0r+_EWCiF_CD0WP@eIY_W1T^R{Gfqv&~U$= zf-G8r$_y$A(m%B=o$(-~QcCagjgoYw+1%3vA0|(l=`^kOQYFuXgQ@X)I(9z}7hTM4 z{GastmI<}pZULb;cqY|clJb`MY~$1&bYa8a?8kQO zdYZGJ*-9_HvQ@Txishr1DJNZQE2@+~3)e22P}1D{<+K`;o7SN&f!#}1vhvJ+oAE0{ zZ|VXqd#&sU&t!Sd%)F=>)1EYcIne*vP5a&->kE5L-{+~Wd%9lz?S;Fa`PR?Wm_Eao z&zAcWN9Q&9!$uO1J{;9O7d>x_rzO`hu0zMxu6w%a=55iAK-UNhqe6A5`i)=If85it zQplXKDY7#oFMs*=lEV(HY|9w6H0+w}g?-bw4{Y}R`mn!VCSSDHb$QuS2d&h_hhu}1 z+78Pmn@w-Kf9vy)PhtyasXsisbozyNvB{2)quJ-Q+p(3iU1Zx>Dlf7xF>&jMJIAD1 z_T6_p&ZqJ2UaJ0^>E9N{OuNBwZK2!V$j{T4a(a6R%xsXqz@T|_6gb;`PIMOl^ed!`>{WJyZ7`*uS+YW-n=rOSt;TD|Jr8djM8W8fBorx&E4=S z(|Y|MgSRX`efRH|<|a?Hy*M|_&wqbIxYEK3K_kVg_l{f}?SHR0vn2N5!j9SDg<*ak zt_Pe>&Mu4QYVgSZTRH#W-rU@*lR?G8yj1~b4Vy%J4VpwdnHU)j8mA6)#f7s6h}0=v z(0Ii_65fI3WH#hsL+Yd&$RP2!4fza^Wkn725gJ(xl~@$ozDjj)^yQ#mQk;(Act;aJIl3Y&R`K6l2 zykDgA&hurJj&m2=<%EeQdd|o^8?mNi%hi-?t5!(7xjjvvGsWZEGU0TQ*K79AU$m-_ ztLtyjG51bEl@sPtd2jBhn*Zc?xE6Trv-fc z-Tz1PcrNQ^!NRL1Les?;r*%&I-jkjm&~kU>d=p0QUmS%moVfoQ&#M+RYmN0twS2o` zWvRtvz2{l+1$Xv^-Qvn?cCEUEn@C_ zq*6NL*@WimBJP61yFHT+OqW@^diU?6(HH977|2pbs~85&p` z85vj_nHrnu8JJl{8L%`kF@9Olcx6fBMT5q3G-`ROit&6FHL5QLQd46!J8VI1On7&%)+u*T?`$%F#r$U z7#bKFniyId7#W&@TJ1&#CWeMk?y!p^f}=tk_QuGB^R89rSocNte_NMa?@`Ip863qT z(=#R?dvjmP^YfN7w@)3ZsFY+}Xs5Z~t^2CJ-xTw68^unhtW@MQI`;osy*oz>Z<@-h zO}lf2%`0nP&VF#V>$CN*3sZjI*3A36fO*Hy#+)h_rfqx9d=t^|o)96;{O~K!uNTsj zj?@Pne6ztsM5oU+qszWRK^^uO=5w zJiBxEofj{seraH@==E|udzpJq!CK+9v-OkDU3OPvn60#Jh18<|+owd`FZbqW&=Hn+ zpL8nIbL!qTS$~vQYCe7{bL^pv+pDc+-P_mZl?X33slM~@jKot|Gg#W7iBTM>(VJ4N zYX4QHe^T8Aw$_`LCN>A|8K$GOU9Tov#dH}?`0QL=<0gI7I3ubxH`E{u)cliY@i*`_ z@Lu4#z#Tq=Lxm8DWqQR9ScoxL{T=bD(8mX3%IN14Hhcnh5D29gD_f(T~9!r*2~V zqr~H-uEcjqa?Yne4<7SA3W^J#bWd%6dxE&e@mcR8XYTm2c5jDd=l-QhF{k}MM@6Iu zvKsIG^0I%kPDlM#z3K!`*>?^K+b!|3+3cWtsGs-PQf zsZ8D?%eiUcokP_giG&n< zT#1~GTHt|xCbYmBJVO@X!q3paz#KGmZER+03M%|eAzTv>*I;0aWAHp9Gji)PF{1Z*dSc3X|XHsg;!tQ8_(`nNid2? zaQhVD-e%MySCW`MF}^WmakhC%OZ@Ikfhw#!hd%K)`9Re@%&tbDmum75MfO(or-TMpPfAgNsI<;}drz$Nj z!whR;G|1zoY)*jR(~a5 zSV{HFpo#Gj-VQs~qKPUU_N(8*PWQi96qA&3(RRv&=y1U`s$4awy^S#iBZfDXAv9V?Wqs$s5=J)>!+lq zC6?xt=n?LzBd+xUU6KV_)R+ifjz^%U&i?g<1eLGdfkne5aqM~GT{w?#;Y5kF!d$#>$c~~&t$V>fi=z9Hs+n)9r?@o%J zbvxYQ<;Qa~(%vQ2c*sA(8<<0jm`|FY;Rr#y*EW^td6|Q3I z;_npOmAG8+^sF0v?z0+>UO2n_!u#6h4-c&iIq%1o%uwP;ytN@fE`RUGhYa_h8?rB% zZ1p|Wz2e1>6&|a<-z%z1%+4=g*?4+6=Nil1Z;qY5(X^%Ltn8N^t&DOFzok31LM%5$ z-#Wn?Ici_nePl)qBsoAi(t2drozktDEag( zpliSdH2^gH%EiRUz{DiAhl%mO0Xvv2@E@Y!+r**6PnKx`mjMSz z8#DVtg@rISW7`7c<_Rk+19M{|L%iS?w*1ztfE^;Wx7OeHICSNE(xRIl`$F6;b35q7WIjQLu5zZh!twy5|D! zZDT&-nsZF`hSnW@vw%qC1j!8<^qLmX6?JH;NVb~EY>m<)y(4GV`^FY?e_`rg zmn^gNid{VMx! zLeP@u%F>&yX8XGPzl^D^*~2pH*Se~V99~zxxiMX5MM4kUe0f-TdGof8f6w=*Wco|< o`pvQqD@a_)bZ+vx=kI;LecM{_tv|j!;g|SB`;1R(tkNVI0FNB{r; diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create.go deleted file mode 100644 index 892189a4..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create.go +++ /dev/null @@ -1,176 +0,0 @@ -//go:build windows && !native_webview2loader - -package webviewloader - -import ( - "fmt" - "os" - "path/filepath" - "syscall" - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge" - "golang.org/x/sys/windows" -) - -func init() { - fmt.Println("DEB | Using go webview2loader") - preventEnvAndRegistryOverrides() -} - -type webView2RunTimeType int32 - -const ( - webView2RunTimeTypeInstalled webView2RunTimeType = 0x00 - webView2RunTimeTypeRedistributable webView2RunTimeType = 0x01 -) - -// CreateCoreWebView2Environment creates an evergreen WebView2 Environment using the installed WebView2 Runtime version. -// -// This is equivalent to running CreateCoreWebView2EnvironmentWithOptions without any options. -// For more information, see CreateCoreWebView2EnvironmentWithOptions. -func CreateCoreWebView2Environment(environmentCompletedHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) error { - return CreateCoreWebView2EnvironmentWithOptions(environmentCompletedHandler) -} - -// CreateCoreWebView2EnvironmentWithOptions creates an environment with a custom version of WebView2 Runtime, -// user data folder, and with or without additional options. -// -// See https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?#createcorewebview2environmentwithoptions -func CreateCoreWebView2EnvironmentWithOptions(environmentCompletedHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, opts ...option) error { - var params environmentOptions - for _, opt := range opts { - opt(¶ms) - } - - var err error - var dllPath string - var runtimeType webView2RunTimeType - if browserExecutableFolder := params.browserExecutableFolder; browserExecutableFolder != "" { - runtimeType = webView2RunTimeTypeRedistributable - dllPath, err = findEmbeddedClientDll(browserExecutableFolder) - } else { - runtimeType = webView2RunTimeTypeInstalled - dllPath, _, err = findInstalledClientDll(params.preferCanary) - } - - if err != nil { - return err - } - - return createWebViewEnvironmentWithClientDll(dllPath, runtimeType, params.userDataFolder, - ¶ms, environmentCompletedHandler) -} - -func createWebViewEnvironmentWithClientDll(lpLibFileName string, runtimeType webView2RunTimeType, userDataFolder string, - envOptions *environmentOptions, envCompletedHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) error { - - if !filepath.IsAbs(lpLibFileName) { - return fmt.Errorf("lpLibFileName must be absolute") - } - - dll, err := windows.LoadDLL(lpLibFileName) - if err != nil { - return fmt.Errorf("Loading DLL failed: %w", err) - } - - defer func() { - canUnloadProc, err := dll.FindProc("DllCanUnloadNow") - if err != nil { - return - } - - if r1, _, _ := canUnloadProc.Call(); r1 != windows.NO_ERROR { - return - } - - dll.Release() - }() - - createProc, err := dll.FindProc("CreateWebViewEnvironmentWithOptionsInternal") - if err != nil { - return fmt.Errorf("Unable to find CreateWebViewEnvironmentWithOptionsInternal entrypoint: %w", err) - } - - userDataPtr, err := windows.UTF16PtrFromString(userDataFolder) - if err != nil { - return err - } - - envOptionsCom := combridge.New2[iCoreWebView2EnvironmentOptions, iCoreWebView2EnvironmentOptions2]( - envOptions, envOptions) - - defer envOptionsCom.Close() - - envCompletedHandler = &environmentCreatedHandler{envCompletedHandler} - envCompletedCom := combridge.New[iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler](envCompletedHandler) - defer envCompletedCom.Close() - - preventEnvAndRegistryOverrides() - - const unknown = 1 - hr, _, err := createProc.Call( - uintptr(unknown), - uintptr(runtimeType), - uintptr(unsafe.Pointer(userDataPtr)), - uintptr(envOptionsCom.Ref()), - uintptr(envCompletedCom.Ref())) - - if hr != 0 { - if err == nil || err == windows.ERROR_SUCCESS { - err = syscall.Errno(hr) - } - return err - } - - return nil -} - -type environmentCreatedHandler struct { - originalHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler -} - -func (r *environmentCreatedHandler) EnvironmentCompleted(errorCode HRESULT, createdEnvironment *ICoreWebView2Environment) HRESULT { - // The OpenWebview2Loader has some retry logic and retries once, didn't encounter any case when this would have been - // needed during the development: https://github.com/jchv/OpenWebView2Loader/blob/master/Source/WebView2Loader.cpp#L202 - - if createdEnvironment != nil { - // May or may not be necessary, but the official WebView2Loader seems to do it. - iidICoreWebView2Environment := windows.GUID{ - Data1: 0xb96d755e, - Data2: 0x0319, - Data3: 0x4e92, - Data4: [8]byte{0xa2, 0x96, 0x23, 0x43, 0x6f, 0x46, 0xa1, 0xfc}, - } - - if err := createdEnvironment.QueryInterface(&iidICoreWebView2Environment, &createdEnvironment); err != nil { - createdEnvironment = nil - errNo, ok := err.(syscall.Errno) - if !ok { - errNo = syscall.Errno(windows.E_FAIL) - } - errorCode = HRESULT(errNo) - } - } - - r.originalHandler.EnvironmentCompleted(errorCode, createdEnvironment) - - if createdEnvironment != nil { - createdEnvironment.Release() - } - - return HRESULT(windows.S_OK) -} - -func preventEnvAndRegistryOverrides() { - // Setting these env variables to empty string also prevents registry overrides because webview2 - // checks for existence and not for empty value - os.Setenv("WEBVIEW2_PIPE_FOR_SCRIPT_DEBUGGER", "") - os.Setenv("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "") - os.Setenv("WEBVIEW2_RELEASE_CHANNEL_PREFERENCE", "0") - - // The following seems not be be required because those are only used by the webview2loader which - // in this case is implemented on our own. But nevertheless set them to empty to be consistent. - os.Setenv("WEBVIEW2_BROWSER_EXECUTABLE_FOLDER", "") - os.Setenv("WEBVIEW2_USER_DATA_FOLDER", "") -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_completed.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_completed.go deleted file mode 100644 index 223c77e8..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_completed.go +++ /dev/null @@ -1,42 +0,0 @@ -//go:build windows && !native_webview2loader - -package webviewloader - -import ( - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge" -) - -// HRESULT -// -// See https://docs.microsoft.com/en-us/windows/win32/seccrypto/common-hresult-values -type HRESULT int32 - -// ICoreWebView2Environment Represents the WebView2 Environment -// -// See https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2environment -type ICoreWebView2Environment = combridge.IUnknownImpl - -// ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler receives the WebView2Environment created using CreateCoreWebView2Environment. -type ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler interface { - // EnvironmentCompleted is invoked to receive the created WebView2Environment - // - // See https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2createcorewebview2environmentcompletedhandler?#invoke - EnvironmentCompleted(errorCode HRESULT, createdEnvironment *ICoreWebView2Environment) HRESULT -} - -type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler interface { - combridge.IUnknown - ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler -} - -func init() { - combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler]( - "{4e8a3389-c9d8-4bd2-b6b5-124fee6cc14d}", - _iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke, - ) -} - -func _iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke(this uintptr, errorCode HRESULT, env *combridge.IUnknownImpl) uintptr { - res := combridge.Resolve[iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler](this).EnvironmentCompleted(errorCode, env) - return uintptr(res) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_options.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_options.go deleted file mode 100644 index 4bae6064..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create_options.go +++ /dev/null @@ -1,276 +0,0 @@ -//go:build windows && !native_webview2loader - -package webviewloader - -import ( - "unicode/utf16" - "unsafe" - - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge" - "golang.org/x/sys/windows" -) - -// WithBrowserExecutableFolder to specify whether WebView2 controls use a fixed or installed version -// of the WebView2 Runtime that exists on a user machine. -// -// To use a fixed version of the WebView2 Runtime, -// pass the folder path that contains the fixed version of the WebView2 Runtime. -// BrowserExecutableFolder supports both relative (to the application's executable) and absolute files paths. -// To create WebView2 controls that use the installed version of the WebView2 Runtime that exists on user -// machines, pass a empty string to WithBrowserExecutableFolder. In this scenario, the API tries to find a -// compatible version of the WebView2 Runtime that is installed on the user machine (first at the machine level, -// and then per user) using the selected channel preference. The path of fixed version of the WebView2 Runtime -// should not contain \Edge\Application\. When such a path is used, the API fails with HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED). -func WithBrowserExecutableFolder(folder string) option { - return func(wvep *environmentOptions) { - wvep.browserExecutableFolder = folder - } -} - -// WithUserDataFolder specifies to user data folder location for WebView2 -// -// You may specify the userDataFolder to change the default user data folder location for WebView2. -// The path is either an absolute file path or a relative file path that is interpreted as relative -// to the compiled code for the current process. -// Dhe default user data ({Executable File Name}.WebView2) folder is created in the same directory -// next to the compiled code for the app. WebView2 creation fails if the compiled code is running -// in a directory in which the process does not have permission to create a new directory. -// The app is responsible to clean up the associated user data folder when it is done. -func WithUserDataFolder(folder string) option { - return func(wvep *environmentOptions) { - wvep.userDataFolder = folder - } -} - -// WithAdditionalBrowserArguments changes the behavior of the WebView. -// -// The arguments are passed to the -// browser process as part of the command. For more information about -// using command-line switches with Chromium browser processes, navigate to -// [Run Chromium with Flags][ChromiumDevelopersHowTosRunWithFlags]. -// The value appended to a switch is appended to the browser process, for -// example, in `--edge-webview-switches=xxx` the value is `xxx`. If you -// specify a switch that is important to WebView functionality, it is -// ignored, for example, `--user-data-dir`. Specific features are disabled -// internally and blocked from being enabled. If a switch is specified -// multiple times, only the last instance is used. -// -// \> [!NOTE]\n\> A merge of the different values of the same switch is not attempted, -// except for disabled and enabled features. The features specified by -// `--enable-features` and `--disable-features` are merged with simple -// logic.\n\> * The features is the union of the specified features -// and built-in features. If a feature is disabled, it is removed from the -// enabled features list. -// -// If you specify command-line switches and use the -// `additionalBrowserArguments` parameter, the `--edge-webview-switches` -// value takes precedence and is processed last. If a switch fails to -// parse, the switch is ignored. The default state for the operation is -// to run the browser process with no extra flags. -// -// [ChromiumDevelopersHowTosRunWithFlags]: https://www.chromium.org/developers/how-tos/run-chromium-with-flags "Run Chromium with flags | The Chromium Projects" -func WithAdditionalBrowserArguments(args string) option { - return func(wvep *environmentOptions) { - wvep.additionalBrowserArguments = args - } -} - -// WithLanguage sets the default display language for WebView. -// -// It applies to browser UI such as -// context menu and dialogs. It also applies to the `accept-languages` HTTP -// header that WebView sends to websites. It is in the format of -// -// `language[-country]` where `language` is the 2-letter code from -// [ISO 639][ISO639LanguageCodesHtml] -// and `country` is the -// 2-letter code from -// [ISO 3166][ISOStandard72482Html]. -// -// [ISO639LanguageCodesHtml]: https://www.iso.org/iso-639-language-codes.html "ISO 639 | ISO" -// [ISOStandard72482Html]: https://www.iso.org/standard/72482.html "ISO 3166-1:2020 | ISO" -func WithLanguage(lang string) option { - return func(wvep *environmentOptions) { - wvep.language = lang - } -} - -// WithTargetCompatibleBrowserVersion secifies the version of the WebView2 Runtime binaries required to be -// compatible with your app. -// -// This defaults to the WebView2 Runtime version -// that corresponds with the version of the SDK the app is using. The -// format of this value is the same as the format of the -// `BrowserVersionString` property and other `BrowserVersion` values. Only -// the version part of the `BrowserVersion` value is respected. The channel -// suffix, if it exists, is ignored. The version of the WebView2 Runtime -// binaries actually used may be different from the specified -// `TargetCompatibleBrowserVersion`. The binaries are only guaranteed to be -// compatible. Verify the actual version on the `BrowserVersionString` -// property on the `ICoreWebView2Environment`. -func WithTargetCompatibleBrowserVersion(version string) option { - return func(wvep *environmentOptions) { - wvep.targetCompatibleBrowserVersion = version - } -} - -// WithAllowSingleSignOnUsingOSPrimaryAccount is used to enable -// single sign on with Azure Active Directory (AAD) and personal Microsoft -// Account (MSA) resources inside WebView. All AAD accounts, connected to -// Windows and shared for all apps, are supported. For MSA, SSO is only enabled -// for the account associated for Windows account login, if any. -// Default is disabled. Universal Windows Platform apps must also declare -// `enterpriseCloudSSO` -// [Restricted capabilities][WindowsUwpPackagingAppCapabilityDeclarationsRestrictedCapabilities] -// for the single sign on (SSO) to work. -// -// [WindowsUwpPackagingAppCapabilityDeclarationsRestrictedCapabilities]: /windows/uwp/packaging/app-capability-declarations\#restricted-capabilities "Restricted capabilities - App capability declarations | Microsoft Docs" -func WithAllowSingleSignOnUsingOSPrimaryAccount(allow bool) option { - return func(wvep *environmentOptions) { - wvep.allowSingleSignOnUsingOSPrimaryAccount = allow - } -} - -// WithExclusiveUserDataFolderAccess specifies that the WebView environment -// obtains exclusive access to the user data folder. -// -// If the user data folder is already being used by another WebView environment with a -// different value for `ExclusiveUserDataFolderAccess` property, the creation of a WebView2Controller -// using the environment object will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. -// When set as TRUE, no other WebView can be created from other processes using WebView2Environment -// objects with the same UserDataFolder. This prevents other processes from creating WebViews -// which share the same browser process instance, since sharing is performed among -// WebViews that have the same UserDataFolder. When another process tries to create a -// WebView2Controller from an WebView2Environment object created with the same user data folder, -// it will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`. -func WithExclusiveUserDataFolderAccess(exclusive bool) option { - return func(wvep *environmentOptions) { - wvep.exclusiveUserDataFolderAccess = exclusive - } -} - -type option func(*environmentOptions) - -var _ iCoreWebView2EnvironmentOptions = &environmentOptions{} -var _ iCoreWebView2EnvironmentOptions2 = &environmentOptions{} - -type environmentOptions struct { - browserExecutableFolder string - userDataFolder string - preferCanary bool - - additionalBrowserArguments string - language string - targetCompatibleBrowserVersion string - allowSingleSignOnUsingOSPrimaryAccount bool - exclusiveUserDataFolderAccess bool -} - -func (o *environmentOptions) AdditionalBrowserArguments() string { - return o.additionalBrowserArguments -} - -func (o *environmentOptions) Language() string { - return o.language -} - -func (o *environmentOptions) TargetCompatibleBrowserVersion() string { - v := o.targetCompatibleBrowserVersion - if v == "" { - v = kMinimumCompatibleVersion - } - return v -} - -func (o *environmentOptions) AllowSingleSignOnUsingOSPrimaryAccount() bool { - return o.allowSingleSignOnUsingOSPrimaryAccount -} - -func (o *environmentOptions) ExclusiveUserDataFolderAccess() bool { - return o.exclusiveUserDataFolderAccess -} - -type iCoreWebView2EnvironmentOptions interface { - combridge.IUnknown - - AdditionalBrowserArguments() string - Language() string - TargetCompatibleBrowserVersion() string - AllowSingleSignOnUsingOSPrimaryAccount() bool -} - -type iCoreWebView2EnvironmentOptions2 interface { - combridge.IUnknown - - ExclusiveUserDataFolderAccess() bool -} - -func init() { - combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2EnvironmentOptions]( - "{2fde08a8-1e9a-4766-8c05-95a9ceb9d1c5}", - _iCoreWebView2EnvironmentOptionsAdditionalBrowserArguments, - _iCoreWebView2EnvironmentOptionsNOP, - _iCoreWebView2EnvironmentOptionsLanguage, - _iCoreWebView2EnvironmentOptionsNOP, - _iCoreWebView2EnvironmentTargetCompatibleBrowserVersion, - _iCoreWebView2EnvironmentOptionsNOP, - _iCoreWebView2EnvironmentOptionsAllowSingleSignOnUsingOSPrimaryAccount, - _iCoreWebView2EnvironmentOptionsNOP, - ) - - combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2EnvironmentOptions2]( - "{ff85c98a-1ba7-4a6b-90c8-2b752c89e9e2}", - _iCoreWebView2EnvironmentOptions2ExclusiveUserDataFolderAccess, - _iCoreWebView2EnvironmentOptionsNOP, - ) -} -func _iCoreWebView2EnvironmentOptionsNOP(this uintptr) uintptr { - return uintptr(windows.S_FALSE) -} - -func _iCoreWebView2EnvironmentOptionsAdditionalBrowserArguments(this uintptr, value **uint16) uintptr { - v := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).AdditionalBrowserArguments() - *value = stringToOleString(v) - return uintptr(windows.S_OK) -} - -func _iCoreWebView2EnvironmentOptionsLanguage(this uintptr, value **uint16) uintptr { - args := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).Language() - *value = stringToOleString(args) - return uintptr(windows.S_OK) -} - -func _iCoreWebView2EnvironmentTargetCompatibleBrowserVersion(this uintptr, value **uint16) uintptr { - args := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).TargetCompatibleBrowserVersion() - *value = stringToOleString(args) - return uintptr(windows.S_OK) -} - -func _iCoreWebView2EnvironmentOptionsAllowSingleSignOnUsingOSPrimaryAccount(this uintptr, value *int32) uintptr { - v := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).AllowSingleSignOnUsingOSPrimaryAccount() - *value = boolToInt(v) - return uintptr(windows.S_OK) -} - -func _iCoreWebView2EnvironmentOptions2ExclusiveUserDataFolderAccess(this uintptr, value *int32) uintptr { - v := combridge.Resolve[iCoreWebView2EnvironmentOptions2](this).ExclusiveUserDataFolderAccess() - *value = boolToInt(v) - return uintptr(windows.S_OK) -} - -func stringToOleString(v string) *uint16 { - wstr := utf16.Encode([]rune(v + "\x00")) - lwstr := len(wstr) - ptr := (*uint16)(coTaskMemAlloc(2 * lwstr)) - - copy(unsafe.Slice(ptr, lwstr), wstr) - - return ptr -} - -func boolToInt(v bool) int32 { - if v { - return 1 - } - return 0 -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll.go deleted file mode 100644 index da9472ff..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll.go +++ /dev/null @@ -1,74 +0,0 @@ -//go:build windows - -package webviewloader - -import ( - "errors" - "fmt" - "os" - "path/filepath" - "runtime" - - "golang.org/x/sys/windows/registry" -) - -var ( - errNoClientDLLFound = errors.New("no webview2 found") -) - -func findEmbeddedBrowserVersion(filename string) (string, error) { - block, err := getFileVersionInfo(filename) - if err != nil { - return "", err - } - - info, err := verQueryValueString(block, "\\StringFileInfo\\040904B0\\ProductVersion") - if err != nil { - return "", err - } - - return info, nil -} - -func findEmbeddedClientDll(embeddedEdgeSubFolder string) (outClientPath string, err error) { - if !filepath.IsAbs(embeddedEdgeSubFolder) { - exe, err := os.Executable() - if err != nil { - return "", err - } - - embeddedEdgeSubFolder = filepath.Join(filepath.Dir(exe), embeddedEdgeSubFolder) - } - - return findClientDllInFolder(embeddedEdgeSubFolder) -} - -func findClientDllInFolder(folder string) (string, error) { - arch := "" - switch runtime.GOARCH { - case "arm64": - arch = "arm64" - case "amd64": - arch = "x64" - case "386": - arch = "x86" - default: - return "", fmt.Errorf("Unsupported architecture") - } - - dllPath := filepath.Join(folder, "EBWebView", arch, "EmbeddedBrowserWebView.dll") - if _, err := os.Stat(dllPath); err != nil { - return "", mapFindErr(err) - } - return dllPath, nil -} - -func mapFindErr(err error) error { - if errors.Is(err, registry.ErrNotExist) { - return errNoClientDLLFound - } - if errors.Is(err, os.ErrNotExist) { - return errNoClientDLLFound - } - return err -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll_installed.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll_installed.go deleted file mode 100644 index 7ee171b2..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/find_dll_installed.go +++ /dev/null @@ -1,94 +0,0 @@ -//go:build windows && !native_webview2loader - -package webviewloader - -import ( - "path/filepath" - - "golang.org/x/sys/windows/registry" -) - -const ( - kNumChannels = 4 - kInstallKeyPath = "Software\\Microsoft\\EdgeUpdate\\ClientState\\" - kMinimumCompatibleVersion = "86.0.616.0" -) - -var ( - kChannelName = [kNumChannels]string{ - "", "beta", "dev", "canary", // "internal" - } - - kChannelUuid = [kNumChannels]string{ - "{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}", - "{2CD8A007-E189-409D-A2C8-9AF4EF3C72AA}", - "{0D50BFEC-CD6A-4F9A-964C-C7416E3ACB10}", - "{65C35B14-6C1D-4122-AC46-7148CC9D6497}", - //"{BE59E8FD-089A-411B-A3B0-051D9E417818}", - } - - minimumCompatibleVersion, _ = parseVersion(kMinimumCompatibleVersion) -) - -func findInstalledClientDll(preferCanary bool) (clientPath string, version *version, err error) { - for i := 0; i < kNumChannels; i++ { - channel := i - if preferCanary { - channel = (kNumChannels - 1) - i - } - - key := kInstallKeyPath + kChannelUuid[channel] - for _, checkSystem := range []bool{true, false} { - clientPath, version, err := findInstalledClientDllForChannel(key, checkSystem) - if err == errNoClientDLLFound { - continue - } - if err != nil { - return "", nil, err - } - - version.channel = kChannelName[channel] - return clientPath, version, nil - } - } - return "", nil, errNoClientDLLFound -} - -func findInstalledClientDllForChannel(subKey string, system bool) (clientPath string, clientVersion *version, err error) { - key := registry.LOCAL_MACHINE - if !system { - key = registry.CURRENT_USER - } - - regKey, err := registry.OpenKey(key, subKey, registry.READ|registry.WOW64_32KEY) - if err != nil { - return "", nil, mapFindErr(err) - } - defer regKey.Close() - - embeddedEdgeSubFolder, _, err := regKey.GetStringValue("EBWebView") - if err != nil { - return "", nil, mapFindErr(err) - } - - if embeddedEdgeSubFolder == "" { - return "", nil, errNoClientDLLFound - } - - versionString := filepath.Base(embeddedEdgeSubFolder) - version, err := parseVersion(versionString) - if err != nil { - return "", nil, errNoClientDLLFound - } - - if version.compare(minimumCompatibleVersion) < 0 { - return "", nil, errNoClientDLLFound - } - - dllPath, err := findEmbeddedClientDll(embeddedEdgeSubFolder) - if err != nil { - return "", nil, mapFindErr(err) - } - - return dllPath, &version, nil -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module.go deleted file mode 100644 index 3e02fe98..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module.go +++ /dev/null @@ -1,173 +0,0 @@ -//go:build windows && native_webview2loader - -package webviewloader - -import ( - "errors" - "fmt" - "os" - "sync" - "unsafe" - - "github.com/jchv/go-winloader" - - "golang.org/x/sys/windows" -) - -func init() { - preventEnvAndRegistryOverrides(nil, nil, "") -} - -var ( - memOnce sync.Once - memModule winloader.Module - memCreate winloader.Proc - memCompareBrowserVersions winloader.Proc - memGetAvailableCoreWebView2BrowserVersionString winloader.Proc - memErr error -) - -const ( - // https://referencesource.microsoft.com/#system.web/Util/hresults.cs,20 - E_FILENOTFOUND = 0x80070002 -) - -// CompareBrowserVersions will compare the 2 given versions and return: -// -// Less than zero: v1 < v2 -// zero: v1 == v2 -// Greater than zero: v1 > v2 -func CompareBrowserVersions(v1 string, v2 string) (int, error) { - _v1, err := windows.UTF16PtrFromString(v1) - if err != nil { - return 0, err - } - _v2, err := windows.UTF16PtrFromString(v2) - if err != nil { - return 0, err - } - - err = loadFromMemory() - if err != nil { - return 0, err - } - - var result int32 - _, _, err = memCompareBrowserVersions.Call( - uint64(uintptr(unsafe.Pointer(_v1))), - uint64(uintptr(unsafe.Pointer(_v2))), - uint64(uintptr(unsafe.Pointer(&result)))) - - if err != windows.ERROR_SUCCESS { - return 0, err - } - return int(result), nil -} - -// GetAvailableCoreWebView2BrowserVersionString returns version of the webview2 runtime. -// If path is empty, it will try to find installed webview2 is the system. -// If there is no version installed, a blank string is returned. -func GetAvailableCoreWebView2BrowserVersionString(path string) (string, error) { - if path != "" { - // The default implementation fails if CGO and a fixed browser path is used. It's caused by the go-winloader - // which loads the native DLL from memory. - // Use the new GoWebView2Loader in this case, in the future we will make GoWebView2Loader - // feature-complete and remove the use of the native DLL and go-winloader. - version, err := goGetAvailableCoreWebView2BrowserVersionString(path) - if errors.Is(err, errNoClientDLLFound) { - // WebView2 is not found - return "", nil - } else if err != nil { - return "", err - } - - return version, nil - } - - err := loadFromMemory() - if err != nil { - return "", err - } - - var browserPath *uint16 = nil - if path != "" { - browserPath, err = windows.UTF16PtrFromString(path) - if err != nil { - return "", fmt.Errorf("error calling UTF16PtrFromString for %s: %v", path, err) - } - } - - preventEnvAndRegistryOverrides(browserPath, nil, "") - var result *uint16 - res, _, err := memGetAvailableCoreWebView2BrowserVersionString.Call( - uint64(uintptr(unsafe.Pointer(browserPath))), - uint64(uintptr(unsafe.Pointer(&result)))) - - if res != 0 { - if res == E_FILENOTFOUND { - // WebView2 is not installed - return "", nil - } - - return "", fmt.Errorf("Unable to call GetAvailableCoreWebView2BrowserVersionString (%x): %w", res, err) - } - - version := windows.UTF16PtrToString(result) - windows.CoTaskMemFree(unsafe.Pointer(result)) - return version, nil -} - -// CreateCoreWebView2EnvironmentWithOptions tries to load WebviewLoader2 and -// call the CreateCoreWebView2EnvironmentWithOptions routine. -func CreateCoreWebView2EnvironmentWithOptions(browserExecutableFolder, userDataFolder *uint16, environmentCompletedHandle uintptr, additionalBrowserArgs string) (uintptr, error) { - err := loadFromMemory() - if err != nil { - return 0, err - } - - preventEnvAndRegistryOverrides(browserExecutableFolder, userDataFolder, additionalBrowserArgs) - res, _, _ := memCreate.Call( - uint64(uintptr(unsafe.Pointer(browserExecutableFolder))), - uint64(uintptr(unsafe.Pointer(userDataFolder))), - 0, - uint64(environmentCompletedHandle), - ) - return uintptr(res), nil -} - -func loadFromMemory() error { - var err error - // DLL is not available natively. Try loading embedded copy. - memOnce.Do(func() { - memModule, memErr = winloader.LoadFromMemory(WebView2Loader) - if memErr != nil { - err = fmt.Errorf("Unable to load WebView2Loader.dll from memory: %w", memErr) - return - } - memCreate = memModule.Proc("CreateCoreWebView2EnvironmentWithOptions") - memCompareBrowserVersions = memModule.Proc("CompareBrowserVersions") - memGetAvailableCoreWebView2BrowserVersionString = memModule.Proc("GetAvailableCoreWebView2BrowserVersionString") - }) - return err -} - -func preventEnvAndRegistryOverrides(browserFolder, userDataFolder *uint16, additionalBrowserArgs string) { - // Setting these env variables to empty string also prevents registry overrides because webview2loader - // checks for existence and not for empty value - os.Setenv("WEBVIEW2_PIPE_FOR_SCRIPT_DEBUGGER", "") - - // Set these overrides to the values or empty to prevent registry and external env overrides - os.Setenv("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", additionalBrowserArgs) - os.Setenv("WEBVIEW2_RELEASE_CHANNEL_PREFERENCE", "0") - os.Setenv("WEBVIEW2_BROWSER_EXECUTABLE_FOLDER", windows.UTF16PtrToString(browserFolder)) - os.Setenv("WEBVIEW2_USER_DATA_FOLDER", windows.UTF16PtrToString(userDataFolder)) -} - -func goGetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder string) (string, error) { - clientPath, err := findEmbeddedClientDll(browserExecutableFolder) - if err != nil { - return "", err - } - - return findEmbeddedBrowserVersion(clientPath) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_386.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_386.go deleted file mode 100644 index e4ff44ff..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_386.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows && native_webview2loader - -package webviewloader - -import _ "embed" - -//go:embed x86/WebView2Loader.dll -var WebView2Loader []byte diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_amd64.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_amd64.go deleted file mode 100644 index 27423ae8..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_amd64.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows && native_webview2loader - -package webviewloader - -import _ "embed" - -//go:embed x64/WebView2Loader.dll -var WebView2Loader []byte diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_arm64.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_arm64.go deleted file mode 100644 index bba6a88c..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/native_module_arm64.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build windows && native_webview2loader - -package webviewloader - -import _ "embed" - -//go:embed arm64/WebView2Loader.dll -var WebView2Loader []byte diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/syscall.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/syscall.go deleted file mode 100644 index 24d0856a..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/syscall.go +++ /dev/null @@ -1,143 +0,0 @@ -//go:build windows - -package webviewloader - -import ( - "fmt" - "syscall" - "unicode/utf16" - "unsafe" - - "golang.org/x/sys/windows" -) - -var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - procGlobalAlloc = modkernel32.NewProc("GlobalAlloc") - procGlobalFree = modkernel32.NewProc("GlobalFree") - - modversion = windows.NewLazySystemDLL("version.dll") - procGetFileVersionInfoSize = modversion.NewProc("GetFileVersionInfoSizeW") - procGetFileVersionInfo = modversion.NewProc("GetFileVersionInfoW") - procVerQueryValue = modversion.NewProc("VerQueryValueW") - - modole32 = windows.NewLazySystemDLL("ole32.dll") - procCoTaskMemAlloc = modole32.NewProc("CoTaskMemAlloc") -) - -func getFileVersionInfo(path string) ([]byte, error) { - lptstrFilename, err := syscall.UTF16PtrFromString(path) - if err != nil { - return nil, err - } - - size, _, err := procGetFileVersionInfoSize.Call( - uintptr(unsafe.Pointer(lptstrFilename)), - 0, - ) - - err = maskErrorSuccess(err) - if size == 0 && err == nil { - err = fmt.Errorf("GetFileVersionInfoSize failed") - } - - if err != nil { - return nil, err - } - - data := make([]byte, size) - ret, _, err := procGetFileVersionInfo.Call( - uintptr(unsafe.Pointer(lptstrFilename)), - 0, - uintptr(size), - uintptr(unsafe.Pointer(&data[0])), - ) - - err = maskErrorSuccess(err) - if ret == 0 && err == nil { - err = fmt.Errorf("GetFileVersionInfo failed") - } - - if err != nil { - return nil, err - } - return data, nil -} - -func verQueryValueString(block []byte, subBlock string) (string, error) { - // Allocate memory from native side to make sure the block doesn't get moved - // because we get a pointer into that memory block from the native verQueryValue - // call back. - pBlock := globalAlloc(0, uint32(len(block))) - defer globalFree(unsafe.Pointer(pBlock)) - - // Copy the memory region into native side memory - copy(unsafe.Slice((*byte)(pBlock), len(block)), block) - - lpSubBlock, err := syscall.UTF16PtrFromString(subBlock) - if err != nil { - return "", err - } - - var lplpBuffer unsafe.Pointer - var puLen uint - ret, _, err := procVerQueryValue.Call( - uintptr(pBlock), - uintptr(unsafe.Pointer(lpSubBlock)), - uintptr(unsafe.Pointer(&lplpBuffer)), - uintptr(unsafe.Pointer(&puLen)), - ) - - err = maskErrorSuccess(err) - if ret == 0 && err == nil { - err = fmt.Errorf("VerQueryValue failed") - } - - if err != nil { - return "", err - } - - if puLen <= 1 { - return "", nil - } - puLen -= 1 // Remove Null-Terminator - - wchar := unsafe.Slice((*uint16)(lplpBuffer), puLen) - return string(utf16.Decode(wchar)), nil -} - -func globalAlloc(uFlags uint, dwBytes uint32) unsafe.Pointer { - ret, _, _ := procGlobalAlloc.Call( - uintptr(uFlags), - uintptr(dwBytes)) - - if ret == 0 { - panic("globalAlloc failed") - } - - return unsafe.Pointer(ret) -} - -func globalFree(data unsafe.Pointer) { - ret, _, _ := procGlobalFree.Call(uintptr(data)) - if ret != 0 { - panic("globalFree failed") - } -} - -func maskErrorSuccess(err error) error { - if err == windows.ERROR_SUCCESS { - return nil - } - return err -} - -func coTaskMemAlloc(size int) unsafe.Pointer { - ret, _, _ := procCoTaskMemAlloc.Call( - uintptr(size)) - - if ret == 0 { - panic("coTaskMemAlloc failed") - } - return unsafe.Pointer(ret) -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/version.go b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/version.go deleted file mode 100644 index cf278d95..00000000 --- a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/version.go +++ /dev/null @@ -1,147 +0,0 @@ -//go:build windows && !native_webview2loader - -package webviewloader - -import ( - "errors" - "fmt" - "strconv" - "strings" -) - -// CompareBrowserVersions will compare the 2 given versions and return: -// -// -1 = v1 < v2 -// 0 = v1 == v2 -// 1 = v1 > v2 -func CompareBrowserVersions(v1 string, v2 string) (int, error) { - v, err := parseVersion(v1) - if err != nil { - return 0, fmt.Errorf("v1 invalid: %w", err) - } - - w, err := parseVersion(v2) - if err != nil { - return 0, fmt.Errorf("v2 invalid: %w", err) - } - - return v.compare(w), nil -} - -// GetAvailableCoreWebView2BrowserVersionString get the browser version info including channel name -// if it is the WebView2 Runtime. -// Channel names are Beta, Dev, and Canary. -func GetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder string) (string, error) { - if browserExecutableFolder != "" { - clientPath, err := findEmbeddedClientDll(browserExecutableFolder) - if errors.Is(err, errNoClientDLLFound) { - // WebView2 is not found - return "", nil - } else if err != nil { - return "", err - } - - return findEmbeddedBrowserVersion(clientPath) - } - - _, version, err := findInstalledClientDll(false) - if errors.Is(err, errNoClientDLLFound) { - return "", nil - } else if err != nil { - return "", err - } - - return version.String(), nil -} - -type version struct { - major int - minor int - patch int - build int - - channel string -} - -func (v version) String() string { - vv := fmt.Sprintf("%d.%d.%d.%d", v.major, v.minor, v.patch, v.build) - if v.channel != "" { - vv += " " + v.channel - } - - return vv -} - -func (v version) compare(o version) int { - if c := compareInt(v.major, o.major); c != 0 { - return c - } - if c := compareInt(v.minor, o.minor); c != 0 { - return c - } - if c := compareInt(v.patch, o.patch); c != 0 { - return c - } - return compareInt(v.build, o.build) -} - -func parseVersion(v string) (version, error) { - var p version - - // Split away channel information... - if i := strings.Index(v, " "); i > 0 { - p.channel = v[i+1:] - v = v[:i] - } - - vv := strings.Split(v, ".") - if len(vv) > 4 { - return p, fmt.Errorf("too many version parts") - } - - var err error - vv, p.major, err = parseInt(vv) - if err != nil { - return p, fmt.Errorf("bad major version: %w", err) - } - - vv, p.minor, err = parseInt(vv) - if err != nil { - return p, fmt.Errorf("bad minor version: %w", err) - } - - vv, p.patch, err = parseInt(vv) - if err != nil { - return p, fmt.Errorf("bad patch version: %w", err) - } - - _, p.build, err = parseInt(vv) - if err != nil { - return p, fmt.Errorf("bad build version: %w", err) - } - - return p, nil -} - -func parseInt(v []string) ([]string, int, error) { - if len(v) == 0 { - return nil, 0, nil - } - - p, err := strconv.ParseInt(v[0], 10, 32) - if err != nil { - return nil, 0, err - } - return v[1:], int(p), nil -} - -func compareInt(v1, v2 int) int { - if v1 == v2 { - return 0 - } - if v1 < v2 { - return -1 - } else { - return +1 - } -} diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/x64/WebView2Loader.dll b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/x64/WebView2Loader.dll deleted file mode 100644 index ab15cffb45a9d3b243b35dbdda9252cae7dd183e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137640 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 diff --git a/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/x86/WebView2Loader.dll b/v2/internal/frontend/desktop/windows/go-webview2/webviewloader/x86/WebView2Loader.dll deleted file mode 100644 index 8609d58ee5655f32398d81cade8da650df7025eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 107416 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

V%m1za#if-l!kY$L?=l^$~GQQCKQ2z2M>+7IR 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[ZLoT@Yu?$v2Y%f6uD?u*=g+32Wwssmr<{KF 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 UH>mB@v=66Z+LA>Dmu*S~0BKM|o&W#< diff --git a/v2/internal/frontend/desktop/windows/window.go b/v2/internal/frontend/desktop/windows/window.go index 43ec57c7..a513e875 100644 --- a/v2/internal/frontend/desktop/windows/window.go +++ b/v2/internal/frontend/desktop/windows/window.go @@ -3,11 +3,10 @@ package windows import ( + "github.com/wailsapp/go-webview2/pkg/edge" "sync" "unsafe" - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge" - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/win32" "github.com/wailsapp/wails/v2/internal/system/operatingsystem" diff --git a/v2/internal/system/system_windows.go b/v2/internal/system/system_windows.go index 1ef076cd..40b8f034 100644 --- a/v2/internal/system/system_windows.go +++ b/v2/internal/system/system_windows.go @@ -4,7 +4,7 @@ package system import ( - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/webviewloader" + "github.com/wailsapp/go-webview2/webviewloader" "github.com/wailsapp/wails/v2/internal/system/operatingsystem" "github.com/wailsapp/wails/v2/internal/system/packagemanager" ) diff --git a/v2/internal/wv2installer/wv2installer.go b/v2/internal/wv2installer/wv2installer.go index ce754cee..c89ad196 100644 --- a/v2/internal/wv2installer/wv2installer.go +++ b/v2/internal/wv2installer/wv2installer.go @@ -5,7 +5,7 @@ package wv2installer import ( "fmt" - "github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/webviewloader" + "github.com/wailsapp/go-webview2/webviewloader" "github.com/wailsapp/wails/v2/pkg/options" "github.com/wailsapp/wails/v2/pkg/options/windows" ) diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 0ed111b6..921521e8 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Now uses new `go-webview2` module. Added by @leaanthony in [PR](https://github.com/wailsapp/wails/pull/2687). - Changed styling of `doctor` command. Changed by @MarvinJWendt in [PR](https://github.com/wailsapp/wails/pull/2660) - Enable HiDPI option by default in windows nsis installer by @5aaee9 in [PR](https://github.com/wailsapp/wails/pull/2694) From 31a5c906739bd077c1d3c9536bf03f2956a6e70d Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 13 Jun 2023 20:27:57 +1000 Subject: [PATCH 09/36] Update bug_report.yml --- .github/ISSUE_TEMPLATE/bug_report.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 180057d4..84b7cb6d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -7,7 +7,7 @@ body: - type: markdown attributes: value: | - ***Please note: No new bug reports are being accepted for Wails v1*** + ***Please note: No bug reports are currently being accepted for Wails v3*** Before submitting this issue, please do the following: - Do a web search for your error. This usually leads to a much better understanding of the issue. - Prove that the error is indeed a Wails bug and not an application bug, with a specific set of steps to reproduce. @@ -84,4 +84,4 @@ body: description: Add any other context about the problem here. placeholder: Add any other context about the problem here. validations: - required: false \ No newline at end of file + required: false From fa851f29c53c81733407178f3a55d0129cfd51c3 Mon Sep 17 00:00:00 2001 From: Mohamed Gharib Date: Sun, 18 Jun 2023 23:45:01 +0300 Subject: [PATCH 10/36] [v2] Add -devtools production build flag (#2725) * [v2] Add devtools production build flag * Update changelog * Fix changelog spacing --------- Co-authored-by: Lea Anthony --- v2/cmd/wails/build.go | 2 ++ v2/cmd/wails/flags/build.go | 1 + v2/cmd/wails/flags/dev.go | 1 + v2/internal/app/app.go | 4 ++++ v2/internal/app/app_dev.go | 5 ++++- v2/internal/app/app_devtools.go | 7 +++++++ v2/internal/app/app_devtools_not.go | 7 +++++++ v2/internal/app/app_production.go | 3 +++ v2/internal/frontend/desktop/darwin/Application.h | 2 +- v2/internal/frontend/desktop/darwin/Application.m | 4 ++-- v2/internal/frontend/desktop/darwin/WailsContext.h | 2 +- v2/internal/frontend/desktop/darwin/WailsContext.m | 2 +- v2/internal/frontend/desktop/darwin/frontend.go | 9 ++++++++- v2/internal/frontend/desktop/darwin/main.m | 4 ++-- v2/internal/frontend/desktop/darwin/window.go | 8 ++++---- v2/internal/frontend/desktop/linux/frontend.go | 9 ++++++++- v2/internal/frontend/desktop/linux/window.go | 8 +++++--- v2/internal/frontend/desktop/windows/frontend.go | 10 ++++++++-- v2/pkg/commands/build/base.go | 5 +++++ v2/pkg/commands/build/build.go | 1 + website/docs/reference/cli.mdx | 3 ++- website/docs/tutorials/helloworld.mdx | 1 + website/src/pages/changelog.mdx | 4 ++++ 23 files changed, 82 insertions(+), 20 deletions(-) create mode 100644 v2/internal/app/app_devtools.go create mode 100644 v2/internal/app/app_devtools_not.go diff --git a/v2/cmd/wails/build.go b/v2/cmd/wails/build.go index 5d284e9a..1c6b791e 100644 --- a/v2/cmd/wails/build.go +++ b/v2/cmd/wails/build.go @@ -57,6 +57,7 @@ func buildApplication(f *flags.Build) error { OutputFile: f.OutputFilename, CleanBinDirectory: f.Clean, Mode: f.GetBuildMode(), + Devtools: f.Debug || f.Devtools, Pack: !f.NoPackage, LDFlags: f.LdFlags, Compiler: f.Compiler, @@ -82,6 +83,7 @@ func buildApplication(f *flags.Build) error { {"Compiler", f.GetCompilerPath()}, {"Skip Bindings", bool2Str(f.SkipBindings)}, {"Build Mode", f.GetBuildModeAsString()}, + {"Devtools", bool2Str(buildOptions.Devtools)}, {"Frontend Directory", projectOptions.GetFrontendDir()}, {"Obfuscated", bool2Str(f.Obfuscated)}, } diff --git a/v2/cmd/wails/flags/build.go b/v2/cmd/wails/flags/build.go index d36ceef6..974d9c3a 100644 --- a/v2/cmd/wails/flags/build.go +++ b/v2/cmd/wails/flags/build.go @@ -35,6 +35,7 @@ type Build struct { ForceBuild bool `name:"f" description:"Force build of application"` UpdateWailsVersionGoMod bool `name:"u" description:"Updates go.mod to use the same Wails version as the CLI"` Debug bool `description:"Builds the application in debug mode"` + Devtools bool `description:"Enable Devtools in productions, Already enabled in debug mode (-debug)"` NSIS bool `description:"Generate NSIS installer for Windows"` TrimPath bool `description:"Remove all file system paths from the resulting executable"` WindowsConsole bool `description:"Keep the console when building for Windows"` diff --git a/v2/cmd/wails/flags/dev.go b/v2/cmd/wails/flags/dev.go index 885e0cea..6d4f02f9 100644 --- a/v2/cmd/wails/flags/dev.go +++ b/v2/cmd/wails/flags/dev.go @@ -120,6 +120,7 @@ func (d *Dev) GenerateBuildOptions() *build.Options { result := &build.Options{ OutputType: "dev", Mode: build.Dev, + Devtools: true, Arch: runtime.GOARCH, Pack: true, Platform: runtime.GOOS, diff --git a/v2/internal/app/app.go b/v2/internal/app/app.go index f2821aab..226b5a0b 100644 --- a/v2/internal/app/app.go +++ b/v2/internal/app/app.go @@ -2,6 +2,7 @@ package app import ( "context" + "github.com/wailsapp/wails/v2/internal/frontend" "github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/menumanager" @@ -20,6 +21,9 @@ type App struct { // Indicates if the app is in debug mode debug bool + // Indicates if the devtools is enabled + devtools bool + // OnStartup/OnShutdown startupCallback func(ctx context.Context) shutdownCallback func(ctx context.Context) diff --git a/v2/internal/app/app_dev.go b/v2/internal/app/app_dev.go index 38aada69..7cdc627f 100644 --- a/v2/internal/app/app_dev.go +++ b/v2/internal/app/app_dev.go @@ -42,7 +42,9 @@ func (a *App) Run() error { func CreateApp(appoptions *options.App) (*App, error) { var err error - ctx := context.WithValue(context.Background(), "debug", true) + ctx := context.Background() + ctx = context.WithValue(ctx, "debug", true) + ctx = context.WithValue(ctx, "devtools", true) // Set up logger myLogger := logger.New(appoptions.Logger) @@ -228,6 +230,7 @@ func CreateApp(appoptions *options.App) (*App, error) { startupCallback: appoptions.OnStartup, shutdownCallback: appoptions.OnShutdown, debug: true, + devtools: true, } result.options = appoptions diff --git a/v2/internal/app/app_devtools.go b/v2/internal/app/app_devtools.go new file mode 100644 index 00000000..e28a1e08 --- /dev/null +++ b/v2/internal/app/app_devtools.go @@ -0,0 +1,7 @@ +//go:build devtools + +package app + +func IsDevtoolsEnabled() bool { + return true +} diff --git a/v2/internal/app/app_devtools_not.go b/v2/internal/app/app_devtools_not.go new file mode 100644 index 00000000..a2cfd4e5 --- /dev/null +++ b/v2/internal/app/app_devtools_not.go @@ -0,0 +1,7 @@ +//go:build !devtools + +package app + +func IsDevtoolsEnabled() bool { + return false +} diff --git a/v2/internal/app/app_production.go b/v2/internal/app/app_production.go index afb67bdb..2dfad601 100644 --- a/v2/internal/app/app_production.go +++ b/v2/internal/app/app_production.go @@ -34,7 +34,9 @@ func CreateApp(appoptions *options.App) (*App, error) { options.MergeDefaults(appoptions) debug := IsDebug() + devtools := IsDevtoolsEnabled() ctx = context.WithValue(ctx, "debug", debug) + ctx = context.WithValue(ctx, "devtools", devtools) // Set up logger myLogger := logger.New(appoptions.Logger) @@ -93,6 +95,7 @@ func CreateApp(appoptions *options.App) (*App, error) { startupCallback: appoptions.OnStartup, shutdownCallback: appoptions.OnShutdown, debug: debug, + devtools: devtools, options: appoptions, } diff --git a/v2/internal/frontend/desktop/darwin/Application.h b/v2/internal/frontend/desktop/darwin/Application.h index e418168e..5e6aa065 100644 --- a/v2/internal/frontend/desktop/darwin/Application.h +++ b/v2/internal/frontend/desktop/darwin/Application.h @@ -17,7 +17,7 @@ #define WindowStartsMinimised 2 #define WindowStartsFullscreen 3 -WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled); +WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int devtools, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled); void Run(void*, const char* url); void SetTitle(void* ctx, const char *title); diff --git a/v2/internal/frontend/desktop/darwin/Application.m b/v2/internal/frontend/desktop/darwin/Application.m index ab951714..f79b0b8f 100644 --- a/v2/internal/frontend/desktop/darwin/Application.m +++ b/v2/internal/frontend/desktop/darwin/Application.m @@ -13,13 +13,13 @@ #import "WailsMenu.h" #import "WailsMenuItem.h" -WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled) { +WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int devtools, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled) { [NSApplication sharedApplication]; WailsContext *result = [WailsContext new]; - result.debug = debug; + result.devtools = devtools; if ( windowStartState == WindowStartsFullscreen ) { fullscreen = 1; diff --git a/v2/internal/frontend/desktop/darwin/WailsContext.h b/v2/internal/frontend/desktop/darwin/WailsContext.h index 1e48b218..f39514d9 100644 --- a/v2/internal/frontend/desktop/darwin/WailsContext.h +++ b/v2/internal/frontend/desktop/darwin/WailsContext.h @@ -44,7 +44,7 @@ @property bool alwaysOnTop; -@property bool debug; +@property bool devtools; @property (retain) WKUserContentController* userContentController; diff --git a/v2/internal/frontend/desktop/darwin/WailsContext.m b/v2/internal/frontend/desktop/darwin/WailsContext.m index 29fa9931..fffbe25c 100644 --- a/v2/internal/frontend/desktop/darwin/WailsContext.m +++ b/v2/internal/frontend/desktop/darwin/WailsContext.m @@ -225,7 +225,7 @@ typedef void (^schemeTaskCaller)(id); [userContentController addScriptMessageHandler:self name:@"external"]; config.userContentController = userContentController; self.userContentController = userContentController; - if (self.debug) { + if (self.devtools) { [config.preferences setValue:@YES forKey:@"developerExtrasEnabled"]; } else { // Disable default context menus diff --git a/v2/internal/frontend/desktop/darwin/frontend.go b/v2/internal/frontend/desktop/darwin/frontend.go index b714a2c3..c0dd2702 100644 --- a/v2/internal/frontend/desktop/darwin/frontend.go +++ b/v2/internal/frontend/desktop/darwin/frontend.go @@ -47,6 +47,7 @@ type Frontend struct { frontendOptions *options.App logger *logger.Logger debug bool + devtools bool // Assets assets *assetserver.AssetServer @@ -151,12 +152,18 @@ func (f *Frontend) WindowSetDarkTheme() { func (f *Frontend) Run(ctx context.Context) error { f.ctx = ctx + var _debug = ctx.Value("debug") + var _devtools = ctx.Value("devtools") + if _debug != nil { f.debug = _debug.(bool) } + if _devtools != nil { + f.devtools = _devtools.(bool) + } - mainWindow := NewWindow(f.frontendOptions, f.debug) + mainWindow := NewWindow(f.frontendOptions, f.debug, f.devtools) f.mainWindow = mainWindow f.mainWindow.Center() diff --git a/v2/internal/frontend/desktop/darwin/main.m b/v2/internal/frontend/desktop/darwin/main.m index d2f39bcc..48f4f66a 100644 --- a/v2/internal/frontend/desktop/darwin/main.m +++ b/v2/internal/frontend/desktop/darwin/main.m @@ -215,10 +215,10 @@ int main(int argc, const char * argv[]) { int hideWindowOnClose = 0; const char* appearance = "NSAppearanceNameDarkAqua"; int windowIsTranslucent = 1; - int debug = 1; + int devtools = 1; int windowStartState = 0; int startsHidden = 0; - WailsContext *result = Create("OI OI!",400,400, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug, windowStartState, + WailsContext *result = Create("OI OI!",400,400, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, devtools, windowStartState, startsHidden, 400, 400, 600, 600, false); SetBackgroundColour(result, 255, 0, 0, 255); void *m = NewMenu(""); diff --git a/v2/internal/frontend/desktop/darwin/window.go b/v2/internal/frontend/desktop/darwin/window.go index 8b4c7779..c4e9dcdb 100644 --- a/v2/internal/frontend/desktop/darwin/window.go +++ b/v2/internal/frontend/desktop/darwin/window.go @@ -40,7 +40,7 @@ func bool2Cint(value bool) C.int { return C.int(0) } -func NewWindow(frontendOptions *options.App, debugMode bool) *Window { +func NewWindow(frontendOptions *options.App, debug bool, devtools bool) *Window { c := NewCalloc() defer c.Free() @@ -51,7 +51,7 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window { alwaysOnTop := bool2Cint(frontendOptions.AlwaysOnTop) hideWindowOnClose := bool2Cint(frontendOptions.HideWindowOnClose) startsHidden := bool2Cint(frontendOptions.StartHidden) - debug := bool2Cint(debugMode) + devtoolsEnabled := bool2Cint(devtools) var fullSizeContent, hideTitleBar, hideTitle, useToolbar, webviewIsTransparent C.int var titlebarAppearsTransparent, hideToolbarSeparator, windowIsTranslucent C.int @@ -86,7 +86,7 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window { } var context *C.WailsContext = C.Create(title, width, height, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, - alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug, windowStartState, startsHidden, + alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, devtoolsEnabled, windowStartState, startsHidden, minWidth, minHeight, maxWidth, maxHeight, enableFraudulentWebsiteWarnings) // Create menu @@ -114,7 +114,7 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window { result.SetApplicationMenu(frontendOptions.Menu) } - if debugMode && frontendOptions.Debug.OpenInspectorOnStartup { + if debug && frontendOptions.Debug.OpenInspectorOnStartup { showInspector(result.context) } return result diff --git a/v2/internal/frontend/desktop/linux/frontend.go b/v2/internal/frontend/desktop/linux/frontend.go index 58b8d746..14c202d8 100644 --- a/v2/internal/frontend/desktop/linux/frontend.go +++ b/v2/internal/frontend/desktop/linux/frontend.go @@ -106,6 +106,7 @@ type Frontend struct { frontendOptions *options.App logger *logger.Logger debug bool + devtools bool // Assets assets *assetserver.AssetServer @@ -176,10 +177,16 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger. go result.startMessageProcessor() var _debug = ctx.Value("debug") + var _devtools = ctx.Value("devtools") + if _debug != nil { result.debug = _debug.(bool) } - result.mainWindow = NewWindow(appoptions, result.debug) + if _devtools != nil { + result.devtools = _devtools.(bool) + } + + result.mainWindow = NewWindow(appoptions, result.debug, result.devtools) C.install_signal_handlers() diff --git a/v2/internal/frontend/desktop/linux/window.go b/v2/internal/frontend/desktop/linux/window.go index 9cc86afb..79fc46b6 100644 --- a/v2/internal/frontend/desktop/linux/window.go +++ b/v2/internal/frontend/desktop/linux/window.go @@ -37,6 +37,7 @@ func gtkBool(input bool) C.gboolean { type Window struct { appoptions *options.App debug bool + devtools bool gtkWindow unsafe.Pointer contentManager unsafe.Pointer webview unsafe.Pointer @@ -54,12 +55,13 @@ func bool2Cint(value bool) C.int { return C.int(0) } -func NewWindow(appoptions *options.App, debug bool) *Window { +func NewWindow(appoptions *options.App, debug bool, devtools bool) *Window { validateWebKit2Version(appoptions) result := &Window{ appoptions: appoptions, debug: debug, + devtools: devtools, minHeight: appoptions.MinHeight, minWidth: appoptions.MinWidth, maxHeight: appoptions.MaxHeight, @@ -95,8 +97,8 @@ func NewWindow(appoptions *options.App, debug bool) *Window { defer C.free(unsafe.Pointer(buttonPressedName)) C.ConnectButtons(unsafe.Pointer(webview)) - if debug { - C.DevtoolsEnabled(unsafe.Pointer(webview), C.int(1), C.bool(appoptions.Debug.OpenInspectorOnStartup)) + if devtools { + C.DevtoolsEnabled(unsafe.Pointer(webview), C.int(1), C.bool(debug && appoptions.Debug.OpenInspectorOnStartup)) } else { C.DisableContextMenu(unsafe.Pointer(webview)) } diff --git a/v2/internal/frontend/desktop/windows/frontend.go b/v2/internal/frontend/desktop/windows/frontend.go index c4186eda..ef6b9d57 100644 --- a/v2/internal/frontend/desktop/windows/frontend.go +++ b/v2/internal/frontend/desktop/windows/frontend.go @@ -48,6 +48,7 @@ type Frontend struct { logger *logger.Logger chromium *edge.Chromium debug bool + devtools bool // Assets assets *assetserver.AssetServer @@ -142,9 +143,14 @@ func (f *Frontend) Run(ctx context.Context) error { f.mainWindow = mainWindow var _debug = ctx.Value("debug") + var _devtools = ctx.Value("devtools") + if _debug != nil { f.debug = _debug.(bool) } + if _devtools != nil { + f.devtools = _devtools.(bool) + } f.WindowCenter() f.setupChromium() @@ -489,11 +495,11 @@ func (f *Frontend) setupChromium() { if err != nil { log.Fatal(err) } - err = settings.PutAreDefaultContextMenusEnabled(f.debug) + err = settings.PutAreDefaultContextMenusEnabled(f.devtools) if err != nil { log.Fatal(err) } - err = settings.PutAreDevToolsEnabled(f.debug) + err = settings.PutAreDevToolsEnabled(f.devtools) if err != nil { log.Fatal(err) } diff --git a/v2/pkg/commands/build/base.go b/v2/pkg/commands/build/base.go index fbae6ce7..abfbafff 100644 --- a/v2/pkg/commands/build/base.go +++ b/v2/pkg/commands/build/base.go @@ -234,6 +234,11 @@ func (b *BaseBuilder) CompileProject(options *Options) error { tags.Add("debug") } + // This options allows you to enable devtools in production build (not dev build as it's always enabled there) + if options.Devtools { + tags.Add("devtools") + } + if options.Obfuscated { tags.Add("obfuscated") } diff --git a/v2/pkg/commands/build/build.go b/v2/pkg/commands/build/build.go index cad768fa..85b3e4f5 100644 --- a/v2/pkg/commands/build/build.go +++ b/v2/pkg/commands/build/build.go @@ -40,6 +40,7 @@ type Options struct { Logger *clilogger.CLILogger // All output to the logger OutputType string // EG: desktop, server.... Mode Mode // release or dev + Devtools bool // Enable devtools in production ProjectData *project.Project // The project data Pack bool // Create a package for the app after building Platform string // The platform to build for diff --git a/website/docs/reference/cli.mdx b/website/docs/reference/cli.mdx index 8b2f5b40..9dcc25bc 100644 --- a/website/docs/reference/cli.mdx +++ b/website/docs/reference/cli.mdx @@ -56,7 +56,8 @@ If you are unsure about a template, inspect `package.json` and `wails.json` for |:---------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------------------------------------------------------------------------------| | -clean | Cleans the `build/bin` directory | | | -compiler "compiler" | Use a different go compiler to build, eg go1.15beta1 | go | -| -debug | Retains debug information in the application. Allows the use of the devtools in the application window | | +| -debug | Retains debug information in the application and shows the debug console. Allows the use of the devtools in the application window | | +| -devtools | Allows the use of the devtools in the application window in production (when -debug is not used) | | | -dryrun | Prints the build command without executing it | | | -f | Force build application | | | -garbleargs | Arguments to pass to garble | `-literals -tiny -seed=random` | diff --git a/website/docs/tutorials/helloworld.mdx b/website/docs/tutorials/helloworld.mdx index c7d4d01c..f9e789bb 100644 --- a/website/docs/tutorials/helloworld.mdx +++ b/website/docs/tutorials/helloworld.mdx @@ -73,6 +73,7 @@ App Type: desktop Platforms: windows/amd64 Compiler: C:\Users\leaan\go\go1.18.3\bin\go.exe Build Mode: Production +Devtools: false Skip Frontend: false Compress: false Package: true diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 921521e8..4118bea9 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -18,6 +18,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Avoid app crashing when the Linux GTK key is empty by @aminya in [PR](https://github.com/wailsapp/wails/pull/2672) +### Added + +- Added `-devtools` production build flag. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2725) + ### Changed - Now uses new `go-webview2` module. Added by @leaanthony in [PR](https://github.com/wailsapp/wails/pull/2687). From 07c971476df6f299dfe8c4780cc9591894844d15 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 19 Jun 2023 20:54:20 +1000 Subject: [PATCH 11/36] chore: update sponsors.svg (#2729) Co-authored-by: leaanthony --- website/static/img/sponsors.svg | 44 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/website/static/img/sponsors.svg b/website/static/img/sponsors.svg index 4953896d..fba5ae18 100644 --- a/website/static/img/sponsors.svg +++ b/website/static/img/sponsors.svg @@ -59,77 +59,77 @@ text { Buying Coffee - + - + - + - + - - - - - + - + - + - + - + Helpers - + - + + + + + - + - + - + - + - + - + - + From 4162f097f1fa56698171c64aefeb10594971f2cd Mon Sep 17 00:00:00 2001 From: Mohamed Gharib Date: Mon, 19 Jun 2023 23:31:47 +0300 Subject: [PATCH 12/36] [v2, options] Add EnableDefaultContextMenu option (#2733) * [v2, options] Add EnableDefaultContextMenu option * Update changelog & docs * go mod tidy (./v2) --------- Co-authored-by: Lea Anthony --- v2/go.mod | 3 +- v2/go.sum | 63 ++----------------- .../frontend/desktop/darwin/Application.h | 2 +- .../frontend/desktop/darwin/Application.m | 3 +- .../frontend/desktop/darwin/WailsContext.h | 1 + .../frontend/desktop/darwin/WailsContext.m | 2 +- v2/internal/frontend/desktop/darwin/main.m | 3 +- v2/internal/frontend/desktop/darwin/window.go | 5 +- v2/internal/frontend/desktop/linux/window.go | 2 +- .../frontend/desktop/windows/frontend.go | 2 +- v2/pkg/options/options.go | 4 ++ website/docs/reference/options.mdx | 9 +++ website/src/pages/changelog.mdx | 1 + 13 files changed, 31 insertions(+), 69 deletions(-) diff --git a/v2/go.mod b/v2/go.mod index 5d45d171..a83fc12f 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -15,7 +15,6 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/uuid v1.3.0 github.com/jackmordaunt/icns v1.0.0 - github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e github.com/labstack/echo/v4 v4.10.2 github.com/labstack/gommon v0.4.0 github.com/leaanthony/clir v1.3.0 @@ -34,8 +33,8 @@ require ( github.com/tc-hib/winres v0.1.5 github.com/tidwall/sjson v1.1.7 github.com/tkrajina/go-reflector v0.5.6 + github.com/wailsapp/go-webview2 v1.0.1 github.com/wailsapp/mimetype v1.4.1 - github.com/wailsapp/go-webview2 v1.0.1 github.com/wzshiming/ctc v1.2.3 golang.org/x/mod v0.8.0 golang.org/x/net v0.10.0 diff --git a/v2/go.sum b/v2/go.sum index 0a312566..5c8c5a5c 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -28,11 +28,6 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU 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/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= -github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= -github.com/aymanbagabas/go-osc52 v1.2.2 h1:NT7wkhEhPTcKnBCdPi9djmyy9L3JOL4+3SsfJyqptCo= -github.com/aymanbagabas/go-osc52 v1.2.2/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= -github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= -github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= @@ -41,8 +36,6 @@ github.com/bitfield/script v0.19.0 h1:W24f+FQuPab9gXcW8bhcbo5qO8AtrXyu3XOnR4zhHN github.com/bitfield/script v0.19.0/go.mod h1:ana6F8YOSZ3ImT8SauIzuYSqXgFVkSUJ6kgja+WMmIY= github.com/charmbracelet/glamour v0.5.0 h1:wu15ykPdB7X6chxugG/NNfDUbyyrCLV9XBalj5wdu3g= github.com/charmbracelet/glamour v0.5.0/go.mod h1:9ZRtG19AUIzcTm7FGLGbq3D5WKQ5UyZBbQsMQN0XIqc= -github.com/charmbracelet/glamour v0.6.0 h1:wi8fse3Y7nfcabbbDuwolqTqMQPMnVPeZhDM273bISc= -github.com/charmbracelet/glamour v0.6.0/go.mod h1:taqWV4swIMMbWALc0m7AfE9JkPSU8om2538k9ITBxOc= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -51,8 +44,6 @@ 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/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E= github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= -github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= -github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= @@ -76,13 +67,10 @@ 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/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 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/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ= @@ -115,12 +103,8 @@ 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/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY= -github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M= github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k= -github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o= -github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/leaanthony/clir v1.0.4/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0= @@ -128,13 +112,10 @@ github.com/leaanthony/clir v1.3.0 h1:L9nPDWrmc/qU9UWZZvRaFajWYuO0np9V5p+5gxyYno0 github.com/leaanthony/clir v1.3.0/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0= github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc= github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA= -github.com/leaanthony/go-ansi-parser v1.0.1 h1:97v6c5kYppVsbScf4r/VZdXyQ21KQIfeQOk2DgKxGG4= -github.com/leaanthony/go-ansi-parser v1.0.1/go.mod h1:7arTzgVI47srICYhvgUV4CGd063sGEeoSlych5yeSPM= github.com/leaanthony/go-ansi-parser v1.6.0 h1:T8TuMhFB6TUMIUm0oRrSbgJudTFw9csT3ZK09w0t4Pg= github.com/leaanthony/go-ansi-parser v1.6.0/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU= github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ= github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRCSG7jGxs4= -github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0HtY= github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY= github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js= github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8= @@ -146,12 +127,10 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69 github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= 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.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 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.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= @@ -160,29 +139,19 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/microcosm-cc/bluemonday v1.0.17 h1:Z1a//hgsQ4yjC+8zEkV8IWySkXnsxmdSY642CTFQb5Y= github.com/microcosm-cc/bluemonday v1.0.17/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= -github.com/microcosm-cc/bluemonday v1.0.21/go.mod h1:ytNkv4RrDrLJ2pqlsSI46O6IVXmZOBBD4SaJyDwwTkM= -github.com/microcosm-cc/bluemonday v1.0.24 h1:NGQoPtwGVcbGkKfvyYk1yRqknzBuoMiUrO6R7uFTPlw= -github.com/microcosm-cc/bluemonday v1.0.24/go.mod h1:ArQySAMps0790cHSkdPEJ7bGkF2VePWH773hsJNSHf8= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.9.0 h1:wnbOaGz+LUR3jNT0zOzinPnyDaCZUQRZj9GxK8eRVl8= github.com/muesli/termenv v0.9.0/go.mod h1:R/LzAKf+suGs4IsO95y7+7DpFHO0KABgnZqtlyx2mBw= -github.com/muesli/termenv v0.13.0/go.mod h1:sP1+uffeLaEYpyOTb8pLCUctGcGLnoFjSn4YJK5e2bc= -github.com/muesli/termenv v0.15.1 h1:UzuTb/+hhlBugQz28rpzey4ZuKcZ03MeKsoG7IJZIxs= -github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 h1:acNfDZXmm28D2Yg/c3ALnZStzNaZMSagpbr96vY6Zjc= -github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= 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.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -200,7 +169,6 @@ github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkG github.com/pterm/pterm v0.12.49 h1:qeNm0wTWawy6WhKoY8ZKq6qTXFr0s2UtUyRW0yVztEg= github.com/pterm/pterm v0.12.49/go.mod h1:D4OBoWNqAfXkm5QLTjIgjNiMXPHemLJHnIreGUsWzWg= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -208,8 +176,6 @@ github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBO github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI= github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs= -github.com/samber/lo v1.27.1 h1:sTXwkRiIFIQG+G0HeAvOEnGjqWeWtI9cg5/n51KrxPg= -github.com/samber/lo v1.27.1/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+Rhg= 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.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= @@ -225,12 +191,11 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 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 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tc-hib/winres v0.1.5 h1:2dA5yfjdoEA3UyRaOC92HNMt3jap66pLzoW4MjpC/0M= github.com/tc-hib/winres v0.1.5/go.mod h1:pe6dOR40VOrGz8PkzreVKNvEKnlE8t4yR8A8naL+t7A= -github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M= github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk= github.com/tidwall/gjson v1.9.3 h1:hqzS9wAHMO+KVBBkLxYdkEeeFHuqr95GfClRLKlgK0E= github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -242,18 +207,15 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.1.7 h1:sgVPwu/yygHJ2m1pJDLgGM/h+1F5odx5Q9ljG3imRm8= github.com/tidwall/sjson v1.1.7/go.mod h1:w/yG+ezBeTdUxiKs5NcPicO9diP38nk96QBAbIIGeFs= -github.com/tkrajina/go-reflector v0.5.5 h1:gwoQFNye30Kk7NrExj8zm3zFtrGPqOkzFMLuQZg1DtQ= -github.com/tkrajina/go-reflector v0.5.5/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4= github.com/tkrajina/go-reflector v0.5.6 h1:hKQ0gyocG7vgMD2M3dRlYN6WBBOmdoOzJ6njQSepKdE= github.com/tkrajina/go-reflector v0.5.6/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/wailsapp/go-webview2 v1.0.1 h1:dEJIeEApW/MhO2tTMISZBFZPuW7kwrFA1NtgFB1z1II= -github.com/wailsapp/go-webview2 v1.0.1/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/wailsapp/go-webview2 v1.0.1 h1:dEJIeEApW/MhO2tTMISZBFZPuW7kwrFA1NtgFB1z1II= +github.com/wailsapp/go-webview2 v1.0.1/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/wzshiming/ctc v1.2.3 h1:q+hW3IQNsjIlOFBTGZZZeIXTElFM4grF4spW/errh/c= @@ -268,28 +230,20 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg= github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU= -github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os= github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM= -golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI= golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -299,13 +253,11 @@ golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5o golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= 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 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/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-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -330,10 +282,7 @@ golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -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.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -341,21 +290,17 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn 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= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= 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.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 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 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= diff --git a/v2/internal/frontend/desktop/darwin/Application.h b/v2/internal/frontend/desktop/darwin/Application.h index 5e6aa065..4239da93 100644 --- a/v2/internal/frontend/desktop/darwin/Application.h +++ b/v2/internal/frontend/desktop/darwin/Application.h @@ -17,7 +17,7 @@ #define WindowStartsMinimised 2 #define WindowStartsFullscreen 3 -WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int devtools, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled); +WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int devtools, int defaultContextMenu, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled); void Run(void*, const char* url); void SetTitle(void* ctx, const char *title); diff --git a/v2/internal/frontend/desktop/darwin/Application.m b/v2/internal/frontend/desktop/darwin/Application.m index f79b0b8f..2c08002d 100644 --- a/v2/internal/frontend/desktop/darwin/Application.m +++ b/v2/internal/frontend/desktop/darwin/Application.m @@ -13,13 +13,14 @@ #import "WailsMenu.h" #import "WailsMenuItem.h" -WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int devtools, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled) { +WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int devtools, int defaultContextMenu, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled) { [NSApplication sharedApplication]; WailsContext *result = [WailsContext new]; result.devtools = devtools; + result.defaultContextMenu = defaultContextMenu; if ( windowStartState == WindowStartsFullscreen ) { fullscreen = 1; diff --git a/v2/internal/frontend/desktop/darwin/WailsContext.h b/v2/internal/frontend/desktop/darwin/WailsContext.h index f39514d9..7cdf034b 100644 --- a/v2/internal/frontend/desktop/darwin/WailsContext.h +++ b/v2/internal/frontend/desktop/darwin/WailsContext.h @@ -45,6 +45,7 @@ @property bool alwaysOnTop; @property bool devtools; +@property bool defaultContextMenu; @property (retain) WKUserContentController* userContentController; diff --git a/v2/internal/frontend/desktop/darwin/WailsContext.m b/v2/internal/frontend/desktop/darwin/WailsContext.m index fffbe25c..15c9edff 100644 --- a/v2/internal/frontend/desktop/darwin/WailsContext.m +++ b/v2/internal/frontend/desktop/darwin/WailsContext.m @@ -227,7 +227,7 @@ typedef void (^schemeTaskCaller)(id); self.userContentController = userContentController; if (self.devtools) { [config.preferences setValue:@YES forKey:@"developerExtrasEnabled"]; - } else { + } else if (!self.defaultContextMenu) { // Disable default context menus WKUserScript *initScript = [WKUserScript new]; [initScript initWithSource:@"window.wails.flags.disableWailsDefaultContextMenu = true;" diff --git a/v2/internal/frontend/desktop/darwin/main.m b/v2/internal/frontend/desktop/darwin/main.m index 48f4f66a..45a7d268 100644 --- a/v2/internal/frontend/desktop/darwin/main.m +++ b/v2/internal/frontend/desktop/darwin/main.m @@ -216,9 +216,10 @@ int main(int argc, const char * argv[]) { const char* appearance = "NSAppearanceNameDarkAqua"; int windowIsTranslucent = 1; int devtools = 1; + int defaultContextMenu = 1; int windowStartState = 0; int startsHidden = 0; - WailsContext *result = Create("OI OI!",400,400, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, devtools, windowStartState, + WailsContext *result = Create("OI OI!",400,400, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, devtools, defaultContextMenu, windowStartState, startsHidden, 400, 400, 600, 600, false); SetBackgroundColour(result, 255, 0, 0, 255); void *m = NewMenu(""); diff --git a/v2/internal/frontend/desktop/darwin/window.go b/v2/internal/frontend/desktop/darwin/window.go index c4e9dcdb..c4fb9c0f 100644 --- a/v2/internal/frontend/desktop/darwin/window.go +++ b/v2/internal/frontend/desktop/darwin/window.go @@ -52,6 +52,7 @@ func NewWindow(frontendOptions *options.App, debug bool, devtools bool) *Window hideWindowOnClose := bool2Cint(frontendOptions.HideWindowOnClose) startsHidden := bool2Cint(frontendOptions.StartHidden) devtoolsEnabled := bool2Cint(devtools) + defaultContextMenu := bool2Cint(frontendOptions.EnableDefaultContextMenu) var fullSizeContent, hideTitleBar, hideTitle, useToolbar, webviewIsTransparent C.int var titlebarAppearsTransparent, hideToolbarSeparator, windowIsTranslucent C.int @@ -86,8 +87,8 @@ func NewWindow(frontendOptions *options.App, debug bool, devtools bool) *Window } var context *C.WailsContext = C.Create(title, width, height, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, - alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, devtoolsEnabled, windowStartState, startsHidden, - minWidth, minHeight, maxWidth, maxHeight, enableFraudulentWebsiteWarnings) + alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, devtoolsEnabled, defaultContextMenu, + windowStartState, startsHidden, minWidth, minHeight, maxWidth, maxHeight, enableFraudulentWebsiteWarnings) // Create menu result := &Window{ diff --git a/v2/internal/frontend/desktop/linux/window.go b/v2/internal/frontend/desktop/linux/window.go index 79fc46b6..dd087f57 100644 --- a/v2/internal/frontend/desktop/linux/window.go +++ b/v2/internal/frontend/desktop/linux/window.go @@ -99,7 +99,7 @@ func NewWindow(appoptions *options.App, debug bool, devtools bool) *Window { if devtools { C.DevtoolsEnabled(unsafe.Pointer(webview), C.int(1), C.bool(debug && appoptions.Debug.OpenInspectorOnStartup)) - } else { + } else if !appoptions.EnableDefaultContextMenu { C.DisableContextMenu(unsafe.Pointer(webview)) } diff --git a/v2/internal/frontend/desktop/windows/frontend.go b/v2/internal/frontend/desktop/windows/frontend.go index ef6b9d57..76cecbc9 100644 --- a/v2/internal/frontend/desktop/windows/frontend.go +++ b/v2/internal/frontend/desktop/windows/frontend.go @@ -495,7 +495,7 @@ func (f *Frontend) setupChromium() { if err != nil { log.Fatal(err) } - err = settings.PutAreDefaultContextMenusEnabled(f.devtools) + err = settings.PutAreDefaultContextMenusEnabled(f.devtools || f.frontendOptions.EnableDefaultContextMenu) if err != nil { log.Fatal(err) } diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go index 74b2aef7..1562a7df 100644 --- a/v2/pkg/options/options.go +++ b/v2/pkg/options/options.go @@ -70,6 +70,10 @@ type App struct { // The CSS Value that the CSSDragProperty must have to be draggable, EG: "drag" CSSDragValue string + // EnableDefaultContextMenu enables the browser's default context-menu in production + // This menu is already enabled in development, as well as in debug builds and production builds with the `-devtools` flag + EnableDefaultContextMenu bool + // EnableFraudulentWebsiteDetection enables scan services for fraudulent content, such as malware or phishing attempts. // These services might send information from your app like URLs navigated to and possibly other content to cloud // services of Apple and Microsoft. diff --git a/website/docs/reference/options.mdx b/website/docs/reference/options.mdx index 4bc0d0ff..2f977bde 100644 --- a/website/docs/reference/options.mdx +++ b/website/docs/reference/options.mdx @@ -51,6 +51,7 @@ func main() { OnBeforeClose: app.beforeClose, CSSDragProperty: "--wails-draggable", CSSDragValue: "drag", + EnableDefaultContextMenu: false, EnableFraudulentWebsiteDetection: false, ZoomFactor: 1.0, IsZoomControlEnabled: false, @@ -417,6 +418,14 @@ Indicates what value the `CSSDragProperty` style should have to drag the window. Name: CSSDragValue
Type: `string` +### EnableDefaultContextMenu + +EnableDefaultContextMenu enables the browser's default context-menu in production (Without the devtools inspector). +This menu is already enabled in development, as well as in debug builds and production builds with the `-devtools` flag. + +Name: EnableDefaultContextMenu
+Type: `bool` + ### EnableFraudulentWebsiteDetection EnableFraudulentWebsiteDetection enables scan services for fraudulent content, such as malware or phishing attempts. diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 4118bea9..a9ebdbd4 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added `-devtools` production build flag. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2725) +- Added `EnableDefaultContextMenu` option to allow enabling the browser's default context-menu in production . Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2733) ### Changed From 8fd16d4be3f830960583d9866a3bb2cdacce58f3 Mon Sep 17 00:00:00 2001 From: stffabi Date: Tue, 20 Jun 2023 08:06:42 +0200 Subject: [PATCH 13/36] [assetServer] Make WebView request URL and RequestURI RFC and Go docs compliant (#2722) * [v2 dev] Improve logging of external AssetHandler * [assetServer] Make WebView request URL and RequestURI RFC and Go docs conforme --- v2/pkg/assetserver/assethandler_external.go | 2 +- v2/pkg/assetserver/assetserver_webview.go | 16 ++++++++++++---- website/src/pages/changelog.mdx | 8 ++++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/v2/pkg/assetserver/assethandler_external.go b/v2/pkg/assetserver/assethandler_external.go index 588b350f..743f051e 100644 --- a/v2/pkg/assetserver/assethandler_external.go +++ b/v2/pkg/assetserver/assethandler_external.go @@ -46,7 +46,7 @@ func NewExternalAssetsHandler(logger Logger, options assetserver.Options, url *u proxy.ErrorHandler = func(rw http.ResponseWriter, r *http.Request, err error) { if baseHandler != nil && errors.Is(err, errSkipProxy) { if logger != nil { - logger.Debug("[ExternalAssetHandler] Loading '%s' failed, using original AssetHandler", r.URL) + logger.Debug("[ExternalAssetHandler] '%s' returned not found, using AssetHandler", r.URL) } baseHandler.ServeHTTP(rw, r) } else { diff --git a/v2/pkg/assetserver/assetserver_webview.go b/v2/pkg/assetserver/assetserver_webview.go index ae85f251..7fad1b01 100644 --- a/v2/pkg/assetserver/assetserver_webview.go +++ b/v2/pkg/assetserver/assetserver_webview.go @@ -96,6 +96,18 @@ func (d *AssetServer) processWebViewRequest(r webview.Request) { d.webviewRequestErrorHandler(uri, rw, fmt.Errorf("HTTP-Request: %w", err)) return } + + // For server requests, the URL is parsed from the URI supplied on the Request-Line as stored in RequestURI. For + // most requests, fields other than Path and RawQuery will be empty. (See RFC 7230, Section 5.3) + req.URL.Scheme = "" + req.URL.Host = "" + req.URL.Fragment = "" + req.URL.RawFragment = "" + + if url := req.URL; req.RequestURI == "" && url != nil { + req.RequestURI = url.String() + } + req.Header = header if req.RemoteAddr == "" { @@ -103,10 +115,6 @@ func (d *AssetServer) processWebViewRequest(r webview.Request) { req.RemoteAddr = "192.0.2.1:1234" } - if req.RequestURI == "" && req.URL != nil { - req.RequestURI = req.URL.String() - } - if req.ContentLength == 0 { req.ContentLength, _ = strconv.ParseInt(req.Header.Get(HeaderContentLength), 10, 64) } else { diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index a9ebdbd4..e6b243eb 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -14,9 +14,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Breaking Changes + +- AssetServer RequestURI and URL are now RFC and Go Docs compliant for server requests. This means Scheme, Host and Fragments are not provided anymore. Changed by @stffabi in [PR](https://github.com/wailsapp/wails/pull/2722) + ### Fixed -- Avoid app crashing when the Linux GTK key is empty by @aminya in [PR](https://github.com/wailsapp/wails/pull/2672) +- Avoid app crashing when the Linux GTK key is empty. Fixed by @aminya in [PR](https://github.com/wailsapp/wails/pull/2672) ### Added @@ -27,7 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Now uses new `go-webview2` module. Added by @leaanthony in [PR](https://github.com/wailsapp/wails/pull/2687). - Changed styling of `doctor` command. Changed by @MarvinJWendt in [PR](https://github.com/wailsapp/wails/pull/2660) -- Enable HiDPI option by default in windows nsis installer by @5aaee9 in [PR](https://github.com/wailsapp/wails/pull/2694) +- Enable HiDPI option by default in windows nsis installer. Changed by @5aaee9 in [PR](https://github.com/wailsapp/wails/pull/2694) ## v2.5.1 - 2023-05-16 From 4c7c3d9d82e8a193b986a91139eac1046dd46aa6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Jun 2023 21:52:55 +1000 Subject: [PATCH 14/36] chore: update sponsors.svg (#2738) Co-authored-by: leaanthony --- website/static/img/sponsors.svg | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/website/static/img/sponsors.svg b/website/static/img/sponsors.svg index fba5ae18..1a20e9c2 100644 --- a/website/static/img/sponsors.svg +++ b/website/static/img/sponsors.svg @@ -59,39 +59,35 @@ text { Buying Coffee - + - + - + - + - + - + - + - - - - - + Helpers From abbbf05a79631c585807875883935cd8ca1ab021 Mon Sep 17 00:00:00 2001 From: Mahcks Date: Sun, 25 Jun 2023 15:50:52 -0700 Subject: [PATCH 15/36] added shadcn-ui template (#2744) --- website/docs/community/templates.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/website/docs/community/templates.mdx b/website/docs/community/templates.mdx index e73bbec2..3543cbe9 100644 --- a/website/docs/community/templates.mdx +++ b/website/docs/community/templates.mdx @@ -41,6 +41,7 @@ If you are unsure about a template, inspect `package.json` and `wails.json` for - [wails-react-template](https://github.com/flin7/wails-react-template) - A minimal template for React that supports live development - [wails-template-nextjs](https://github.com/LGiki/wails-template-nextjs) - A template using Next.js and TypeScript - [wails-vite-react-ts-tailwind-template](https://github.com/hotafrika/wails-vite-react-ts-tailwind-template) - A template for React + TypeScript + Vite + TailwindCSS +- [wails-vite-react-ts-tailwind-shadcnui-template](https://github.com/Mahcks/wails-vite-react-tailwind-shadcnui-ts) - A template with Vite, React, TypeScript, TailwindCSS, and shadcn/ui ## Svelte From 5292ced7311395d3b89ea13da9b5aa3c08fd3e60 Mon Sep 17 00:00:00 2001 From: Mohamed Gharib Date: Tue, 27 Jun 2023 14:31:08 +0300 Subject: [PATCH 16/36] [v2, runtime] Separate runtime js debug build (#2745) --- v2/internal/frontend/runtime/desktop/main.js | 6 ++---- v2/internal/frontend/runtime/package.json | 4 ++-- v2/internal/frontend/runtime/runtime_debug_desktop.go | 8 ++++++++ .../{runtime_dev_desktop.js => runtime_debug_desktop.js} | 9 +-------- v2/internal/frontend/runtime/runtime_dev_desktop.go | 8 -------- v2/internal/frontend/runtime/runtime_prod_desktop.go | 2 +- v2/internal/frontend/runtime/runtime_prod_desktop.js | 2 +- website/src/pages/changelog.mdx | 1 + 8 files changed, 16 insertions(+), 24 deletions(-) create mode 100644 v2/internal/frontend/runtime/runtime_debug_desktop.go rename v2/internal/frontend/runtime/{runtime_dev_desktop.js => runtime_debug_desktop.js} (71%) delete mode 100644 v2/internal/frontend/runtime/runtime_dev_desktop.go diff --git a/v2/internal/frontend/runtime/desktop/main.js b/v2/internal/frontend/runtime/desktop/main.js index 9ec68acd..38c56069 100644 --- a/v2/internal/frontend/runtime/desktop/main.js +++ b/v2/internal/frontend/runtime/desktop/main.js @@ -78,10 +78,8 @@ if (window.wailsbindings) { delete window.wails.SetBindings; } -// This is evaluated at build time in package.json -// const dev = 0; -// const production = 1; -if (ENV === 1) { +// (bool) This is evaluated at build time in package.json +if (!DEBUG) { delete window.wailsbindings; } diff --git a/v2/internal/frontend/runtime/package.json b/v2/internal/frontend/runtime/package.json index aa6c3aad..09ff4d50 100644 --- a/v2/internal/frontend/runtime/package.json +++ b/v2/internal/frontend/runtime/package.json @@ -7,8 +7,8 @@ "build": "run-p build:*", "build:ipc-desktop": "npx esbuild desktop/ipc.js --bundle --minify --outfile=ipc.js", "build:ipc-dev": "cd dev && npm install && npm run build", - "build:runtime-desktop-prod": "npx esbuild desktop/main.js --bundle --minify --outfile=runtime_prod_desktop.js --define:ENV=1", - "build:runtime-desktop-dev": "npx esbuild desktop/main.js --bundle --sourcemap=inline --outfile=runtime_dev_desktop.js --define:ENV=0", + "build:runtime-desktop-prod": "npx esbuild desktop/main.js --bundle --minify --outfile=runtime_prod_desktop.js --define:DEBUG=false", + "build:runtime-desktop-debug": "npx esbuild desktop/main.js --bundle --sourcemap=inline --outfile=runtime_debug_desktop.js --define:DEBUG=true", "test": "vitest" }, "author": "Lea Anthony ", diff --git a/v2/internal/frontend/runtime/runtime_debug_desktop.go b/v2/internal/frontend/runtime/runtime_debug_desktop.go new file mode 100644 index 00000000..8dff343c --- /dev/null +++ b/v2/internal/frontend/runtime/runtime_debug_desktop.go @@ -0,0 +1,8 @@ +//go:build debug || !production + +package runtime + +import _ "embed" + +//go:embed runtime_debug_desktop.js +var RuntimeDesktopJS []byte diff --git a/v2/internal/frontend/runtime/runtime_dev_desktop.js b/v2/internal/frontend/runtime/runtime_debug_desktop.js similarity index 71% rename from v2/internal/frontend/runtime/runtime_dev_desktop.js rename to v2/internal/frontend/runtime/runtime_debug_desktop.js index 6bfce9f5..825ea589 100644 --- a/v2/internal/frontend/runtime/runtime_dev_desktop.js +++ b/v2/internal/frontend/runtime/runtime_debug_desktop.js @@ -55,13 +55,6 @@ // desktop/events.js var Listener = class { - /** - * Creates an instance of Listener. - * @param {string} eventName - * @param {function} callback - * @param {number} maxCallbacks - * @memberof Listener - */ constructor(eventName, callback, maxCallbacks) { this.eventName = eventName; this.maxCallbacks = maxCallbacks || -1; @@ -583,4 +576,4 @@ }); window.WailsInvoke("runtime:ready"); })(); -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiZGVza3RvcC9sb2cuanMiLCAiZGVza3RvcC9ldmVudHMuanMiLCAiZGVza3RvcC9jYWxscy5qcyIsICJkZXNrdG9wL2JpbmRpbmdzLmpzIiwgImRlc2t0b3Avd2luZG93LmpzIiwgImRlc2t0b3Avc2NyZWVuLmpzIiwgImRlc2t0b3AvYnJvd3Nlci5qcyIsICJkZXNrdG9wL2NsaXBib2FyZC5qcyIsICJkZXNrdG9wL21haW4uanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qXG4gXyAgICAgICBfXyAgICAgIF8gX19cbnwgfCAgICAgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA2ICovXG5cbi8qKlxuICogU2VuZHMgYSBsb2cgbWVzc2FnZSB0byB0aGUgYmFja2VuZCB3aXRoIHRoZSBnaXZlbiBsZXZlbCArIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbGV2ZWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmZ1bmN0aW9uIHNlbmRMb2dNZXNzYWdlKGxldmVsLCBtZXNzYWdlKSB7XG5cblx0Ly8gTG9nIE1lc3NhZ2UgZm9ybWF0OlxuXHQvLyBsW3R5cGVdW21lc3NhZ2VdXG5cdHdpbmRvdy5XYWlsc0ludm9rZSgnTCcgKyBsZXZlbCArIG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIExvZyB0aGUgZ2l2ZW4gdHJhY2UgbWVzc2FnZSB3aXRoIHRoZSBiYWNrZW5kXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIExvZ1RyYWNlKG1lc3NhZ2UpIHtcblx0c2VuZExvZ01lc3NhZ2UoJ1QnLCBtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBMb2cgdGhlIGdpdmVuIG1lc3NhZ2Ugd2l0aCB0aGUgYmFja2VuZFxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMb2dQcmludChtZXNzYWdlKSB7XG5cdHNlbmRMb2dNZXNzYWdlKCdQJywgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogTG9nIHRoZSBnaXZlbiBkZWJ1ZyBtZXNzYWdlIHdpdGggdGhlIGJhY2tlbmRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gTG9nRGVidWcobWVzc2FnZSkge1xuXHRzZW5kTG9nTWVzc2FnZSgnRCcsIG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIExvZyB0aGUgZ2l2ZW4gaW5mbyBtZXNzYWdlIHdpdGggdGhlIGJhY2tlbmRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gTG9nSW5mbyhtZXNzYWdlKSB7XG5cdHNlbmRMb2dNZXNzYWdlKCdJJywgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogTG9nIHRoZSBnaXZlbiB3YXJuaW5nIG1lc3NhZ2Ugd2l0aCB0aGUgYmFja2VuZFxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMb2dXYXJuaW5nKG1lc3NhZ2UpIHtcblx0c2VuZExvZ01lc3NhZ2UoJ1cnLCBtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBMb2cgdGhlIGdpdmVuIGVycm9yIG1lc3NhZ2Ugd2l0aCB0aGUgYmFja2VuZFxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMb2dFcnJvcihtZXNzYWdlKSB7XG5cdHNlbmRMb2dNZXNzYWdlKCdFJywgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogTG9nIHRoZSBnaXZlbiBmYXRhbCBtZXNzYWdlIHdpdGggdGhlIGJhY2tlbmRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gTG9nRmF0YWwobWVzc2FnZSkge1xuXHRzZW5kTG9nTWVzc2FnZSgnRicsIG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIFNldHMgdGhlIExvZyBsZXZlbCB0byB0aGUgZ2l2ZW4gbG9nIGxldmVsXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IGxvZ2xldmVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBTZXRMb2dMZXZlbChsb2dsZXZlbCkge1xuXHRzZW5kTG9nTWVzc2FnZSgnUycsIGxvZ2xldmVsKTtcbn1cblxuLy8gTG9nIGxldmVsc1xuZXhwb3J0IGNvbnN0IExvZ0xldmVsID0ge1xuXHRUUkFDRTogMSxcblx0REVCVUc6IDIsXG5cdElORk86IDMsXG5cdFdBUk5JTkc6IDQsXG5cdEVSUk9SOiA1LFxufTtcbiIsICIvKlxuIF8gICAgICAgX18gICAgICBfIF9fXG58IHwgICAgIC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cbi8qIGpzaGludCBlc3ZlcnNpb246IDYgKi9cblxuLy8gRGVmaW5lcyBhIHNpbmdsZSBsaXN0ZW5lciB3aXRoIGEgbWF4aW11bSBudW1iZXIgb2YgdGltZXMgdG8gY2FsbGJhY2tcblxuLyoqXG4gKiBUaGUgTGlzdGVuZXIgY2xhc3MgZGVmaW5lcyBhIGxpc3RlbmVyISA6LSlcbiAqXG4gKiBAY2xhc3MgTGlzdGVuZXJcbiAqL1xuY2xhc3MgTGlzdGVuZXIge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgTGlzdGVuZXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1heENhbGxiYWNrc1xuICAgICAqIEBtZW1iZXJvZiBMaXN0ZW5lclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGV2ZW50TmFtZSwgY2FsbGJhY2ssIG1heENhbGxiYWNrcykge1xuICAgICAgICB0aGlzLmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcbiAgICAgICAgLy8gRGVmYXVsdCBvZiAtMSBtZWFucyBpbmZpbml0ZVxuICAgICAgICB0aGlzLm1heENhbGxiYWNrcyA9IG1heENhbGxiYWNrcyB8fCAtMTtcbiAgICAgICAgLy8gQ2FsbGJhY2sgaW52b2tlcyB0aGUgY2FsbGJhY2sgd2l0aCB0aGUgZ2l2ZW4gZGF0YVxuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBsaXN0ZW5lciBzaG91bGQgYmUgZGVzdHJveWVkXG4gICAgICAgIHRoaXMuQ2FsbGJhY2sgPSAoZGF0YSkgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkobnVsbCwgZGF0YSk7XG4gICAgICAgICAgICAvLyBJZiBtYXhDYWxsYmFja3MgaXMgaW5maW5pdGUsIHJldHVybiBmYWxzZSAoZG8gbm90IGRlc3Ryb3kpXG4gICAgICAgICAgICBpZiAodGhpcy5tYXhDYWxsYmFja3MgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRGVjcmVtZW50IG1heENhbGxiYWNrcy4gUmV0dXJuIHRydWUgaWYgbm93IDAsIG90aGVyd2lzZSBmYWxzZVxuICAgICAgICAgICAgdGhpcy5tYXhDYWxsYmFja3MgLT0gMTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1heENhbGxiYWNrcyA9PT0gMDtcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmV4cG9ydCBjb25zdCBldmVudExpc3RlbmVycyA9IHt9O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBgbWF4Q2FsbGJhY2tzYCB0aW1lcyBiZWZvcmUgYmVpbmcgZGVzdHJveWVkXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhDYWxsYmFja3NcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGxpc3RlbmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIG1heENhbGxiYWNrcykge1xuICAgIGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0gPSBldmVudExpc3RlbmVyc1tldmVudE5hbWVdIHx8IFtdO1xuICAgIGNvbnN0IHRoaXNMaXN0ZW5lciA9IG5ldyBMaXN0ZW5lcihldmVudE5hbWUsIGNhbGxiYWNrLCBtYXhDYWxsYmFja3MpO1xuICAgIGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0ucHVzaCh0aGlzTGlzdGVuZXIpO1xuICAgIHJldHVybiAoKSA9PiBsaXN0ZW5lck9mZih0aGlzTGlzdGVuZXIpO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBldmVyeSB0aW1lIHRoZSBldmVudCBpcyBlbWl0dGVkXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGxpc3RlbmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNPbihldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIEV2ZW50c09uTXVsdGlwbGUoZXZlbnROYW1lLCBjYWxsYmFjaywgLTEpO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBvbmNlIHRoZW4gZGVzdHJveWVkXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGxpc3RlbmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNPbmNlKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gRXZlbnRzT25NdWx0aXBsZShldmVudE5hbWUsIGNhbGxiYWNrLCAxKTtcbn1cblxuZnVuY3Rpb24gbm90aWZ5TGlzdGVuZXJzKGV2ZW50RGF0YSkge1xuXG4gICAgLy8gR2V0IHRoZSBldmVudCBuYW1lXG4gICAgbGV0IGV2ZW50TmFtZSA9IGV2ZW50RGF0YS5uYW1lO1xuXG4gICAgLy8gQ2hlY2sgaWYgd2UgaGF2ZSBhbnkgbGlzdGVuZXJzIGZvciB0aGlzIGV2ZW50XG4gICAgaWYgKGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0pIHtcblxuICAgICAgICAvLyBLZWVwIGEgbGlzdCBvZiBsaXN0ZW5lciBpbmRleGVzIHRvIGRlc3Ryb3lcbiAgICAgICAgY29uc3QgbmV3RXZlbnRMaXN0ZW5lckxpc3QgPSBldmVudExpc3RlbmVyc1tldmVudE5hbWVdLnNsaWNlKCk7XG5cbiAgICAgICAgLy8gSXRlcmF0ZSBsaXN0ZW5lcnNcbiAgICAgICAgZm9yIChsZXQgY291bnQgPSBldmVudExpc3RlbmVyc1tldmVudE5hbWVdLmxlbmd0aCAtIDE7IGNvdW50ID49IDA7IGNvdW50IC09IDEpIHtcblxuICAgICAgICAgICAgLy8gR2V0IG5leHQgbGlzdGVuZXJcbiAgICAgICAgICAgIGNvbnN0IGxpc3RlbmVyID0gZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXVtjb3VudF07XG5cbiAgICAgICAgICAgIGxldCBkYXRhID0gZXZlbnREYXRhLmRhdGE7XG5cbiAgICAgICAgICAgIC8vIERvIHRoZSBjYWxsYmFja1xuICAgICAgICAgICAgY29uc3QgZGVzdHJveSA9IGxpc3RlbmVyLkNhbGxiYWNrKGRhdGEpO1xuICAgICAgICAgICAgaWYgKGRlc3Ryb3kpIHtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgbGlzdGVuZXIgaW5kaWNhdGVkIHRvIGRlc3Ryb3kgaXRzZWxmLCBhZGQgaXQgdG8gdGhlIGRlc3Ryb3kgbGlzdFxuICAgICAgICAgICAgICAgIG5ld0V2ZW50TGlzdGVuZXJMaXN0LnNwbGljZShjb3VudCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVcGRhdGUgY2FsbGJhY2tzIHdpdGggbmV3IGxpc3Qgb2YgbGlzdGVuZXJzXG4gICAgICAgIGlmIChuZXdFdmVudExpc3RlbmVyTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBldmVudExpc3RlbmVyc1tldmVudE5hbWVdID0gbmV3RXZlbnRMaXN0ZW5lckxpc3Q7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogTm90aWZ5IGluZm9ybXMgZnJvbnRlbmQgbGlzdGVuZXJzIHRoYXQgYW4gZXZlbnQgd2FzIGVtaXR0ZWQgd2l0aCB0aGUgZ2l2ZW4gZGF0YVxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBub3RpZnlNZXNzYWdlIC0gZW5jb2RlZCBub3RpZmljYXRpb24gbWVzc2FnZVxuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNOb3RpZnkobm90aWZ5TWVzc2FnZSkge1xuICAgIC8vIFBhcnNlIHRoZSBtZXNzYWdlXG4gICAgbGV0IG1lc3NhZ2U7XG4gICAgdHJ5IHtcbiAgICAgICAgbWVzc2FnZSA9IEpTT04ucGFyc2Uobm90aWZ5TWVzc2FnZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zdCBlcnJvciA9ICdJbnZhbGlkIEpTT04gcGFzc2VkIHRvIE5vdGlmeTogJyArIG5vdGlmeU1lc3NhZ2U7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG4gICAgfVxuICAgIG5vdGlmeUxpc3RlbmVycyhtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBFbWl0IGFuIGV2ZW50IHdpdGggdGhlIGdpdmVuIG5hbWUgYW5kIGRhdGFcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNFbWl0KGV2ZW50TmFtZSkge1xuXG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgbmFtZTogZXZlbnROYW1lLFxuICAgICAgICBkYXRhOiBbXS5zbGljZS5hcHBseShhcmd1bWVudHMpLnNsaWNlKDEpLFxuICAgIH07XG5cbiAgICAvLyBOb3RpZnkgSlMgbGlzdGVuZXJzXG4gICAgbm90aWZ5TGlzdGVuZXJzKHBheWxvYWQpO1xuXG4gICAgLy8gTm90aWZ5IEdvIGxpc3RlbmVyc1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnRUUnICsgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xufVxuXG5mdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihldmVudE5hbWUpIHtcbiAgICAvLyBSZW1vdmUgbG9jYWwgbGlzdGVuZXJzXG4gICAgZGVsZXRlIGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV07XG5cbiAgICAvLyBOb3RpZnkgR28gbGlzdGVuZXJzXG4gICAgd2luZG93LldhaWxzSW52b2tlKCdFWCcgKyBldmVudE5hbWUpO1xufVxuXG4vKipcbiAqIE9mZiB1bnJlZ2lzdGVycyBhIGxpc3RlbmVyIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCB3aXRoIE9uLFxuICogb3B0aW9uYWxseSBtdWx0aXBsZSBsaXN0ZW5lcmVzIGNhbiBiZSB1bnJlZ2lzdGVyZWQgdmlhIGBhZGRpdGlvbmFsRXZlbnROYW1lc2BcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gKiBAcGFyYW0gIHsuLi5zdHJpbmd9IGFkZGl0aW9uYWxFdmVudE5hbWVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNPZmYoZXZlbnROYW1lLCAuLi5hZGRpdGlvbmFsRXZlbnROYW1lcykge1xuICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSlcblxuICAgIGlmIChhZGRpdGlvbmFsRXZlbnROYW1lcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGFkZGl0aW9uYWxFdmVudE5hbWVzLmZvckVhY2goZXZlbnROYW1lID0+IHtcbiAgICAgICAgICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSlcbiAgICAgICAgfSlcbiAgICB9XG59XG5cbi8qKlxuICogT2ZmIHVucmVnaXN0ZXJzIGFsbCBldmVudCBsaXN0ZW5lcnMgcHJldmlvdXNseSByZWdpc3RlcmVkIHdpdGggT25cbiAqL1xuIGV4cG9ydCBmdW5jdGlvbiBFdmVudHNPZmZBbGwoKSB7XG4gICAgY29uc3QgZXZlbnROYW1lcyA9IE9iamVjdC5rZXlzKGV2ZW50TGlzdGVuZXJzKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSAhPT0gZXZlbnROYW1lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICByZW1vdmVMaXN0ZW5lcihldmVudE5hbWVzW2ldKTtcbiAgICB9XG59XG5cbi8qKlxuICogbGlzdGVuZXJPZmYgdW5yZWdpc3RlcnMgYSBsaXN0ZW5lciBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBFdmVudHNPblxuICpcbiAqIEBwYXJhbSB7TGlzdGVuZXJ9IGxpc3RlbmVyXG4gKi9cbiBmdW5jdGlvbiBsaXN0ZW5lck9mZihsaXN0ZW5lcikge1xuICAgIGNvbnN0IGV2ZW50TmFtZSA9IGxpc3RlbmVyLmV2ZW50TmFtZTtcbiAgICAvLyBSZW1vdmUgbG9jYWwgbGlzdGVuZXJcbiAgICBldmVudExpc3RlbmVyc1tldmVudE5hbWVdID0gZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXS5maWx0ZXIobCA9PiBsICE9PSBsaXN0ZW5lcik7XG5cbiAgICAvLyBDbGVhbiB1cCBpZiB0aGVyZSBhcmUgbm8gZXZlbnQgbGlzdGVuZXJzIGxlZnRcbiAgICBpZiAoZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmVtb3ZlTGlzdGVuZXIoZXZlbnROYW1lKTtcbiAgICB9XG59XG4iLCAiLypcbiBfICAgICAgIF9fICAgICAgXyBfX1xufCB8ICAgICAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA2ICovXG5cbmV4cG9ydCBjb25zdCBjYWxsYmFja3MgPSB7fTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgbnVtYmVyIGZyb20gdGhlIG5hdGl2ZSBicm93c2VyIHJhbmRvbSBmdW5jdGlvblxuICpcbiAqIEByZXR1cm5zIG51bWJlclxuICovXG5mdW5jdGlvbiBjcnlwdG9SYW5kb20oKSB7XG5cdHZhciBhcnJheSA9IG5ldyBVaW50MzJBcnJheSgxKTtcblx0cmV0dXJuIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycmF5KVswXTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbnVtYmVyIHVzaW5nIGRhIG9sZC1za29vbCBNYXRoLlJhbmRvbVxuICogSSBsaWtlcyB0byBjYWxsIGl0IExPTFJhbmRvbVxuICpcbiAqIEByZXR1cm5zIG51bWJlclxuICovXG5mdW5jdGlvbiBiYXNpY1JhbmRvbSgpIHtcblx0cmV0dXJuIE1hdGgucmFuZG9tKCkgKiA5MDA3MTk5MjU0NzQwOTkxO1xufVxuXG4vLyBQaWNrIGEgcmFuZG9tIG51bWJlciBmdW5jdGlvbiBiYXNlZCBvbiBicm93c2VyIGNhcGFiaWxpdHlcbnZhciByYW5kb21GdW5jO1xuaWYgKHdpbmRvdy5jcnlwdG8pIHtcblx0cmFuZG9tRnVuYyA9IGNyeXB0b1JhbmRvbTtcbn0gZWxzZSB7XG5cdHJhbmRvbUZ1bmMgPSBiYXNpY1JhbmRvbTtcbn1cblxuXG4vKipcbiAqIENhbGwgc2VuZHMgYSBtZXNzYWdlIHRvIHRoZSBiYWNrZW5kIHRvIGNhbGwgdGhlIGJpbmRpbmcgd2l0aCB0aGVcbiAqIGdpdmVuIGRhdGEuIEEgcHJvbWlzZSBpcyByZXR1cm5lZCBhbmQgd2lsbCBiZSBjb21wbGV0ZWQgd2hlbiB0aGVcbiAqIGJhY2tlbmQgcmVzcG9uZHMuIFRoaXMgd2lsbCBiZSByZXNvbHZlZCB3aGVuIHRoZSBjYWxsIHdhcyBzdWNjZXNzZnVsXG4gKiBvciByZWplY3RlZCBpZiBhbiBlcnJvciBpcyBwYXNzZWQgYmFjay5cbiAqIFRoZXJlIGlzIGEgdGltZW91dCBtZWNoYW5pc20uIElmIHRoZSBjYWxsIGRvZXNuJ3QgcmVzcG9uZCBpbiB0aGUgZ2l2ZW5cbiAqIHRpbWUgKGluIG1pbGxpc2Vjb25kcykgdGhlbiB0aGUgcHJvbWlzZSBpcyByZWplY3RlZC5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHBhcmFtIHthbnk9fSBhcmdzXG4gKiBAcGFyYW0ge251bWJlcj19IHRpbWVvdXRcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDYWxsKG5hbWUsIGFyZ3MsIHRpbWVvdXQpIHtcblxuXHQvLyBUaW1lb3V0IGluZmluaXRlIGJ5IGRlZmF1bHRcblx0aWYgKHRpbWVvdXQgPT0gbnVsbCkge1xuXHRcdHRpbWVvdXQgPSAwO1xuXHR9XG5cblx0Ly8gQ3JlYXRlIGEgcHJvbWlzZVxuXHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXG5cdFx0Ly8gQ3JlYXRlIGEgdW5pcXVlIGNhbGxiYWNrSURcblx0XHR2YXIgY2FsbGJhY2tJRDtcblx0XHRkbyB7XG5cdFx0XHRjYWxsYmFja0lEID0gbmFtZSArICctJyArIHJhbmRvbUZ1bmMoKTtcblx0XHR9IHdoaWxlIChjYWxsYmFja3NbY2FsbGJhY2tJRF0pO1xuXG5cdFx0dmFyIHRpbWVvdXRIYW5kbGU7XG5cdFx0Ly8gU2V0IHRpbWVvdXRcblx0XHRpZiAodGltZW91dCA+IDApIHtcblx0XHRcdHRpbWVvdXRIYW5kbGUgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0cmVqZWN0KEVycm9yKCdDYWxsIHRvICcgKyBuYW1lICsgJyB0aW1lZCBvdXQuIFJlcXVlc3QgSUQ6ICcgKyBjYWxsYmFja0lEKSk7XG5cdFx0XHR9LCB0aW1lb3V0KTtcblx0XHR9XG5cblx0XHQvLyBTdG9yZSBjYWxsYmFja1xuXHRcdGNhbGxiYWNrc1tjYWxsYmFja0lEXSA9IHtcblx0XHRcdHRpbWVvdXRIYW5kbGU6IHRpbWVvdXRIYW5kbGUsXG5cdFx0XHRyZWplY3Q6IHJlamVjdCxcblx0XHRcdHJlc29sdmU6IHJlc29sdmVcblx0XHR9O1xuXG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHBheWxvYWQgPSB7XG5cdFx0XHRcdG5hbWUsXG5cdFx0XHRcdGFyZ3MsXG5cdFx0XHRcdGNhbGxiYWNrSUQsXG5cdFx0XHR9O1xuXG4gICAgICAgICAgICAvLyBNYWtlIHRoZSBjYWxsXG4gICAgICAgICAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ0MnICsgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxud2luZG93Lk9iZnVzY2F0ZWRDYWxsID0gKGlkLCBhcmdzLCB0aW1lb3V0KSA9PiB7XG5cbiAgICAvLyBUaW1lb3V0IGluZmluaXRlIGJ5IGRlZmF1bHRcbiAgICBpZiAodGltZW91dCA9PSBudWxsKSB7XG4gICAgICAgIHRpbWVvdXQgPSAwO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBhIHByb21pc2VcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXG4gICAgICAgIC8vIENyZWF0ZSBhIHVuaXF1ZSBjYWxsYmFja0lEXG4gICAgICAgIHZhciBjYWxsYmFja0lEO1xuICAgICAgICBkbyB7XG4gICAgICAgICAgICBjYWxsYmFja0lEID0gaWQgKyAnLScgKyByYW5kb21GdW5jKCk7XG4gICAgICAgIH0gd2hpbGUgKGNhbGxiYWNrc1tjYWxsYmFja0lEXSk7XG5cbiAgICAgICAgdmFyIHRpbWVvdXRIYW5kbGU7XG4gICAgICAgIC8vIFNldCB0aW1lb3V0XG4gICAgICAgIGlmICh0aW1lb3V0ID4gMCkge1xuICAgICAgICAgICAgdGltZW91dEhhbmRsZSA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignQ2FsbCB0byBtZXRob2QgJyArIGlkICsgJyB0aW1lZCBvdXQuIFJlcXVlc3QgSUQ6ICcgKyBjYWxsYmFja0lEKSk7XG4gICAgICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0b3JlIGNhbGxiYWNrXG4gICAgICAgIGNhbGxiYWNrc1tjYWxsYmFja0lEXSA9IHtcbiAgICAgICAgICAgIHRpbWVvdXRIYW5kbGU6IHRpbWVvdXRIYW5kbGUsXG4gICAgICAgICAgICByZWplY3Q6IHJlamVjdCxcbiAgICAgICAgICAgIHJlc29sdmU6IHJlc29sdmVcbiAgICAgICAgfTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcblx0XHRcdFx0aWQsXG5cdFx0XHRcdGFyZ3MsXG5cdFx0XHRcdGNhbGxiYWNrSUQsXG5cdFx0XHR9O1xuXG4gICAgICAgICAgICAvLyBNYWtlIHRoZSBjYWxsXG4gICAgICAgICAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ2MnICsgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG5cblxuLyoqXG4gKiBDYWxsZWQgYnkgdGhlIGJhY2tlbmQgdG8gcmV0dXJuIGRhdGEgdG8gYSBwcmV2aW91c2x5IGNhbGxlZFxuICogYmluZGluZyBpbnZvY2F0aW9uXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IGluY29taW5nTWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gQ2FsbGJhY2soaW5jb21pbmdNZXNzYWdlKSB7XG5cdC8vIFBhcnNlIHRoZSBtZXNzYWdlXG5cdGxldCBtZXNzYWdlO1xuXHR0cnkge1xuXHRcdG1lc3NhZ2UgPSBKU09OLnBhcnNlKGluY29taW5nTWVzc2FnZSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRjb25zdCBlcnJvciA9IGBJbnZhbGlkIEpTT04gcGFzc2VkIHRvIGNhbGxiYWNrOiAke2UubWVzc2FnZX0uIE1lc3NhZ2U6ICR7aW5jb21pbmdNZXNzYWdlfWA7XG5cdFx0cnVudGltZS5Mb2dEZWJ1ZyhlcnJvcik7XG5cdFx0dGhyb3cgbmV3IEVycm9yKGVycm9yKTtcblx0fVxuXHRsZXQgY2FsbGJhY2tJRCA9IG1lc3NhZ2UuY2FsbGJhY2tpZDtcblx0bGV0IGNhbGxiYWNrRGF0YSA9IGNhbGxiYWNrc1tjYWxsYmFja0lEXTtcblx0aWYgKCFjYWxsYmFja0RhdGEpIHtcblx0XHRjb25zdCBlcnJvciA9IGBDYWxsYmFjayAnJHtjYWxsYmFja0lEfScgbm90IHJlZ2lzdGVyZWQhISFgO1xuXHRcdGNvbnNvbGUuZXJyb3IoZXJyb3IpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdFx0dGhyb3cgbmV3IEVycm9yKGVycm9yKTtcblx0fVxuXHRjbGVhclRpbWVvdXQoY2FsbGJhY2tEYXRhLnRpbWVvdXRIYW5kbGUpO1xuXG5cdGRlbGV0ZSBjYWxsYmFja3NbY2FsbGJhY2tJRF07XG5cblx0aWYgKG1lc3NhZ2UuZXJyb3IpIHtcblx0XHRjYWxsYmFja0RhdGEucmVqZWN0KG1lc3NhZ2UuZXJyb3IpO1xuXHR9IGVsc2Uge1xuXHRcdGNhbGxiYWNrRGF0YS5yZXNvbHZlKG1lc3NhZ2UucmVzdWx0KTtcblx0fVxufVxuIiwgIi8qXG4gXyAgICAgICBfXyAgICAgIF8gX18gICAgXG58IHwgICAgIC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gICkgXG58X18vfF9fL1xcX18sXy9fL18vX19fXy8gIFxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cbi8qIGpzaGludCBlc3ZlcnNpb246IDYgKi9cblxuaW1wb3J0IHtDYWxsfSBmcm9tICcuL2NhbGxzJztcblxuLy8gVGhpcyBpcyB3aGVyZSB3ZSBiaW5kIGdvIG1ldGhvZCB3cmFwcGVyc1xud2luZG93LmdvID0ge307XG5cbmV4cG9ydCBmdW5jdGlvbiBTZXRCaW5kaW5ncyhiaW5kaW5nc01hcCkge1xuXHR0cnkge1xuXHRcdGJpbmRpbmdzTWFwID0gSlNPTi5wYXJzZShiaW5kaW5nc01hcCk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRjb25zb2xlLmVycm9yKGUpO1xuXHR9XG5cblx0Ly8gSW5pdGlhbGlzZSB0aGUgYmluZGluZ3MgbWFwXG5cdHdpbmRvdy5nbyA9IHdpbmRvdy5nbyB8fCB7fTtcblxuXHQvLyBJdGVyYXRlIHBhY2thZ2UgbmFtZXNcblx0T2JqZWN0LmtleXMoYmluZGluZ3NNYXApLmZvckVhY2goKHBhY2thZ2VOYW1lKSA9PiB7XG5cblx0XHQvLyBDcmVhdGUgaW5uZXIgbWFwIGlmIGl0IGRvZXNuJ3QgZXhpc3Rcblx0XHR3aW5kb3cuZ29bcGFja2FnZU5hbWVdID0gd2luZG93LmdvW3BhY2thZ2VOYW1lXSB8fCB7fTtcblxuXHRcdC8vIEl0ZXJhdGUgc3RydWN0IG5hbWVzXG5cdFx0T2JqZWN0LmtleXMoYmluZGluZ3NNYXBbcGFja2FnZU5hbWVdKS5mb3JFYWNoKChzdHJ1Y3ROYW1lKSA9PiB7XG5cblx0XHRcdC8vIENyZWF0ZSBpbm5lciBtYXAgaWYgaXQgZG9lc24ndCBleGlzdFxuXHRcdFx0d2luZG93LmdvW3BhY2thZ2VOYW1lXVtzdHJ1Y3ROYW1lXSA9IHdpbmRvdy5nb1twYWNrYWdlTmFtZV1bc3RydWN0TmFtZV0gfHwge307XG5cblx0XHRcdE9iamVjdC5rZXlzKGJpbmRpbmdzTWFwW3BhY2thZ2VOYW1lXVtzdHJ1Y3ROYW1lXSkuZm9yRWFjaCgobWV0aG9kTmFtZSkgPT4ge1xuXG5cdFx0XHRcdHdpbmRvdy5nb1twYWNrYWdlTmFtZV1bc3RydWN0TmFtZV1bbWV0aG9kTmFtZV0gPSBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdFx0XHQvLyBObyB0aW1lb3V0IGJ5IGRlZmF1bHRcblx0XHRcdFx0XHRsZXQgdGltZW91dCA9IDA7XG5cblx0XHRcdFx0XHQvLyBBY3R1YWwgZnVuY3Rpb25cblx0XHRcdFx0XHRmdW5jdGlvbiBkeW5hbWljKCkge1xuXHRcdFx0XHRcdFx0Y29uc3QgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblx0XHRcdFx0XHRcdHJldHVybiBDYWxsKFtwYWNrYWdlTmFtZSwgc3RydWN0TmFtZSwgbWV0aG9kTmFtZV0uam9pbignLicpLCBhcmdzLCB0aW1lb3V0KTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBBbGxvdyBzZXR0aW5nIHRpbWVvdXQgdG8gZnVuY3Rpb25cblx0XHRcdFx0XHRkeW5hbWljLnNldFRpbWVvdXQgPSBmdW5jdGlvbiAobmV3VGltZW91dCkge1xuXHRcdFx0XHRcdFx0dGltZW91dCA9IG5ld1RpbWVvdXQ7XG5cdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdC8vIEFsbG93IGdldHRpbmcgdGltZW91dCB0byBmdW5jdGlvblxuXHRcdFx0XHRcdGR5bmFtaWMuZ2V0VGltZW91dCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdHJldHVybiB0aW1lb3V0O1xuXHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRyZXR1cm4gZHluYW1pYztcblx0XHRcdFx0fSgpO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH0pO1xufVxuIiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXG5cblxuaW1wb3J0IHtDYWxsfSBmcm9tIFwiLi9jYWxsc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gV2luZG93UmVsb2FkKCkge1xuICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1JlbG9hZEFwcCgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dSJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRTeXN0ZW1EZWZhdWx0VGhlbWUoKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXQVNEVCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0TGlnaHRUaGVtZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dBTFQnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1NldERhcmtUaGVtZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dBRFQnKTtcbn1cblxuLyoqXG4gKiBQbGFjZSB0aGUgd2luZG93IGluIHRoZSBjZW50ZXIgb2YgdGhlIHNjcmVlblxuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0NlbnRlcigpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1djJyk7XG59XG5cbi8qKlxuICogU2V0cyB0aGUgd2luZG93IHRpdGxlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRpdGxlXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRUaXRsZSh0aXRsZSkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV1QnICsgdGl0bGUpO1xufVxuXG4vKipcbiAqIE1ha2VzIHRoZSB3aW5kb3cgZ28gZnVsbHNjcmVlblxuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0Z1bGxzY3JlZW4oKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXRicpO1xufVxuXG4vKipcbiAqIFJldmVydHMgdGhlIHdpbmRvdyBmcm9tIGZ1bGxzY3JlZW5cbiAqXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dVbmZ1bGxzY3JlZW4oKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXZicpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHN0YXRlIG9mIHRoZSB3aW5kb3csIGkuZS4gd2hldGhlciB0aGUgd2luZG93IGlzIGluIGZ1bGwgc2NyZWVuIG1vZGUgb3Igbm90LlxuICpcbiAqIEBleHBvcnRcbiAqIEByZXR1cm4ge1Byb21pc2U8Ym9vbGVhbj59IFRoZSBzdGF0ZSBvZiB0aGUgd2luZG93XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dJc0Z1bGxzY3JlZW4oKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93SXNGdWxsc2NyZWVuXCIpO1xufVxuXG4vKipcbiAqIFNldCB0aGUgU2l6ZSBvZiB0aGUgd2luZG93XG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRTaXplKHdpZHRoLCBoZWlnaHQpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dzOicgKyB3aWR0aCArICc6JyArIGhlaWdodCk7XG59XG5cbi8qKlxuICogR2V0IHRoZSBTaXplIG9mIHRoZSB3aW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPHt3OiBudW1iZXIsIGg6IG51bWJlcn0+fSBUaGUgc2l6ZSBvZiB0aGUgd2luZG93XG5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0dldFNpemUoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93R2V0U2l6ZVwiKTtcbn1cblxuLyoqXG4gKiBTZXQgdGhlIG1heGltdW0gc2l6ZSBvZiB0aGUgd2luZG93XG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRNYXhTaXplKHdpZHRoLCBoZWlnaHQpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1daOicgKyB3aWR0aCArICc6JyArIGhlaWdodCk7XG59XG5cbi8qKlxuICogU2V0IHRoZSBtaW5pbXVtIHNpemUgb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aFxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0TWluU2l6ZSh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXejonICsgd2lkdGggKyAnOicgKyBoZWlnaHQpO1xufVxuXG5cblxuLyoqXG4gKiBTZXQgdGhlIHdpbmRvdyBBbHdheXNPblRvcCBvciBub3Qgb24gdG9wXG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0QWx3YXlzT25Ub3AoYikge1xuXG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXQVRQOicgKyAoYiA/ICcxJyA6ICcwJykpO1xufVxuXG5cblxuXG4vKipcbiAqIFNldCB0aGUgUG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSB4XG4gKiBAcGFyYW0ge251bWJlcn0geVxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0UG9zaXRpb24oeCwgeSkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV3A6JyArIHggKyAnOicgKyB5KTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIFBvc2l0aW9uIG9mIHRoZSB3aW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPHt4OiBudW1iZXIsIHk6IG51bWJlcn0+fSBUaGUgcG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93R2V0UG9zaXRpb24oKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93R2V0UG9zXCIpO1xufVxuXG4vKipcbiAqIEhpZGUgdGhlIFdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0hpZGUoKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXSCcpO1xufVxuXG4vKipcbiAqIFNob3cgdGhlIFdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1Nob3coKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXUycpO1xufVxuXG4vKipcbiAqIE1heGltaXNlIHRoZSBXaW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dNYXhpbWlzZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dNJyk7XG59XG5cbi8qKlxuICogVG9nZ2xlIHRoZSBNYXhpbWlzZSBvZiB0aGUgV2luZG93XG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93VG9nZ2xlTWF4aW1pc2UoKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXdCcpO1xufVxuXG4vKipcbiAqIFVubWF4aW1pc2UgdGhlIFdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1VubWF4aW1pc2UoKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXVScpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHN0YXRlIG9mIHRoZSB3aW5kb3csIGkuZS4gd2hldGhlciB0aGUgd2luZG93IGlzIG1heGltaXNlZCBvciBub3QuXG4gKlxuICogQGV4cG9ydFxuICogQHJldHVybiB7UHJvbWlzZTxib29sZWFuPn0gVGhlIHN0YXRlIG9mIHRoZSB3aW5kb3dcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0lzTWF4aW1pc2VkKCkge1xuICAgIHJldHVybiBDYWxsKFwiOndhaWxzOldpbmRvd0lzTWF4aW1pc2VkXCIpO1xufVxuXG4vKipcbiAqIE1pbmltaXNlIHRoZSBXaW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dNaW5pbWlzZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dtJyk7XG59XG5cbi8qKlxuICogVW5taW5pbWlzZSB0aGUgV2luZG93XG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93VW5taW5pbWlzZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1d1Jyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3RhdGUgb2YgdGhlIHdpbmRvdywgaS5lLiB3aGV0aGVyIHRoZSB3aW5kb3cgaXMgbWluaW1pc2VkIG9yIG5vdC5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPGJvb2xlYW4+fSBUaGUgc3RhdGUgb2YgdGhlIHdpbmRvd1xuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93SXNNaW5pbWlzZWQoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93SXNNaW5pbWlzZWRcIik7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3RhdGUgb2YgdGhlIHdpbmRvdywgaS5lLiB3aGV0aGVyIHRoZSB3aW5kb3cgaXMgbm9ybWFsIG9yIG5vdC5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPGJvb2xlYW4+fSBUaGUgc3RhdGUgb2YgdGhlIHdpbmRvd1xuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93SXNOb3JtYWwoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93SXNOb3JtYWxcIik7XG59XG5cbi8qKlxuICogU2V0cyB0aGUgYmFja2dyb3VuZCBjb2xvdXIgb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSBSIFJlZFxuICogQHBhcmFtIHtudW1iZXJ9IEcgR3JlZW5cbiAqIEBwYXJhbSB7bnVtYmVyfSBCIEJsdWVcbiAqIEBwYXJhbSB7bnVtYmVyfSBBIEFscGhhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRCYWNrZ3JvdW5kQ29sb3VyKFIsIEcsIEIsIEEpIHtcbiAgICBsZXQgcmdiYSA9IEpTT04uc3RyaW5naWZ5KHtyOiBSIHx8IDAsIGc6IEcgfHwgMCwgYjogQiB8fCAwLCBhOiBBIHx8IDI1NX0pO1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV3I6JyArIHJnYmEpO1xufVxuXG4iLCAiLypcbiBfXHQgICBfX1x0ICBfIF9fXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG5cbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cblxuXG5pbXBvcnQge0NhbGx9IGZyb20gXCIuL2NhbGxzXCI7XG5cblxuLyoqXG4gKiBHZXRzIHRoZSBhbGwgc2NyZWVucy4gQ2FsbCB0aGlzIGFuZXcgZWFjaCB0aW1lIHlvdSB3YW50IHRvIHJlZnJlc2ggZGF0YSBmcm9tIHRoZSB1bmRlcmx5aW5nIHdpbmRvd2luZyBzeXN0ZW0uXG4gKiBAZXhwb3J0XG4gKiBAdHlwZWRlZiB7aW1wb3J0KCcuLi93cmFwcGVyL3J1bnRpbWUnKS5TY3JlZW59IFNjcmVlblxuICogQHJldHVybiB7UHJvbWlzZTx7U2NyZWVuW119Pn0gVGhlIHNjcmVlbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFNjcmVlbkdldEFsbCgpIHtcbiAgICByZXR1cm4gQ2FsbChcIjp3YWlsczpTY3JlZW5HZXRBbGxcIik7XG59XG4iLCAiLyoqXG4gKiBAZGVzY3JpcHRpb246IFVzZSB0aGUgc3lzdGVtIGRlZmF1bHQgYnJvd3NlciB0byBvcGVuIHRoZSB1cmxcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgXG4gKiBAcmV0dXJuIHt2b2lkfVxuICovXG5leHBvcnQgZnVuY3Rpb24gQnJvd3Nlck9wZW5VUkwodXJsKSB7XG4gIHdpbmRvdy5XYWlsc0ludm9rZSgnQk86JyArIHVybCk7XG59IiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXG5cbmltcG9ydCB7Q2FsbH0gZnJvbSBcIi4vY2FsbHNcIjtcblxuLyoqXG4gKiBTZXQgdGhlIFNpemUgb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDbGlwYm9hcmRTZXRUZXh0KHRleHQpIHtcbiAgICByZXR1cm4gQ2FsbChcIjp3YWlsczpDbGlwYm9hcmRTZXRUZXh0XCIsIFt0ZXh0XSk7XG59XG5cbi8qKlxuICogR2V0IHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhlIGNsaXBib2FyZFxuICpcbiAqIEBleHBvcnRcbiAqIEByZXR1cm4ge1Byb21pc2U8e3N0cmluZ30+fSBUZXh0IGNvbnRlbnQgb2YgdGhlIGNsaXBib2FyZFxuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDbGlwYm9hcmRHZXRUZXh0KCkge1xuICAgIHJldHVybiBDYWxsKFwiOndhaWxzOkNsaXBib2FyZEdldFRleHRcIik7XG59IiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xuaW1wb3J0ICogYXMgTG9nIGZyb20gJy4vbG9nJztcbmltcG9ydCB7ZXZlbnRMaXN0ZW5lcnMsIEV2ZW50c0VtaXQsIEV2ZW50c05vdGlmeSwgRXZlbnRzT2ZmLCBFdmVudHNPbiwgRXZlbnRzT25jZSwgRXZlbnRzT25NdWx0aXBsZX0gZnJvbSAnLi9ldmVudHMnO1xuaW1wb3J0IHtDYWxsLCBDYWxsYmFjaywgY2FsbGJhY2tzfSBmcm9tICcuL2NhbGxzJztcbmltcG9ydCB7U2V0QmluZGluZ3N9IGZyb20gXCIuL2JpbmRpbmdzXCI7XG5pbXBvcnQgKiBhcyBXaW5kb3cgZnJvbSBcIi4vd2luZG93XCI7XG5pbXBvcnQgKiBhcyBTY3JlZW4gZnJvbSBcIi4vc2NyZWVuXCI7XG5pbXBvcnQgKiBhcyBCcm93c2VyIGZyb20gXCIuL2Jyb3dzZXJcIjtcbmltcG9ydCAqIGFzIENsaXBib2FyZCBmcm9tIFwiLi9jbGlwYm9hcmRcIjtcblxuXG5leHBvcnQgZnVuY3Rpb24gUXVpdCgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1EnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFNob3coKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdTJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBIaWRlKCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnSCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gRW52aXJvbm1lbnQoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6RW52aXJvbm1lbnRcIik7XG59XG5cbi8vIFRoZSBKUyBydW50aW1lXG53aW5kb3cucnVudGltZSA9IHtcbiAgICAuLi5Mb2csXG4gICAgLi4uV2luZG93LFxuICAgIC4uLkJyb3dzZXIsXG4gICAgLi4uU2NyZWVuLFxuICAgIC4uLkNsaXBib2FyZCxcbiAgICBFdmVudHNPbixcbiAgICBFdmVudHNPbmNlLFxuICAgIEV2ZW50c09uTXVsdGlwbGUsXG4gICAgRXZlbnRzRW1pdCxcbiAgICBFdmVudHNPZmYsXG4gICAgRW52aXJvbm1lbnQsXG4gICAgU2hvdyxcbiAgICBIaWRlLFxuICAgIFF1aXRcbn07XG5cbi8vIEludGVybmFsIHdhaWxzIGVuZHBvaW50c1xud2luZG93LndhaWxzID0ge1xuICAgIENhbGxiYWNrLFxuICAgIEV2ZW50c05vdGlmeSxcbiAgICBTZXRCaW5kaW5ncyxcbiAgICBldmVudExpc3RlbmVycyxcbiAgICBjYWxsYmFja3MsXG4gICAgZmxhZ3M6IHtcbiAgICAgICAgZGlzYWJsZVNjcm9sbGJhckRyYWc6IGZhbHNlLFxuICAgICAgICBkaXNhYmxlV2FpbHNEZWZhdWx0Q29udGV4dE1lbnU6IGZhbHNlLFxuICAgICAgICBlbmFibGVSZXNpemU6IGZhbHNlLFxuICAgICAgICBkZWZhdWx0Q3Vyc29yOiBudWxsLFxuICAgICAgICBib3JkZXJUaGlja25lc3M6IDYsXG4gICAgICAgIHNob3VsZERyYWc6IGZhbHNlLFxuICAgICAgICBkZWZlckRyYWdUb01vdXNlTW92ZTogdHJ1ZSxcbiAgICAgICAgY3NzRHJhZ1Byb3BlcnR5OiBcIi0td2FpbHMtZHJhZ2dhYmxlXCIsXG4gICAgICAgIGNzc0RyYWdWYWx1ZTogXCJkcmFnXCIsXG4gICAgfVxufTtcblxuLy8gU2V0IHRoZSBiaW5kaW5nc1xuaWYgKHdpbmRvdy53YWlsc2JpbmRpbmdzKSB7XG4gICAgd2luZG93LndhaWxzLlNldEJpbmRpbmdzKHdpbmRvdy53YWlsc2JpbmRpbmdzKTtcbiAgICBkZWxldGUgd2luZG93LndhaWxzLlNldEJpbmRpbmdzO1xufVxuXG4vLyBUaGlzIGlzIGV2YWx1YXRlZCBhdCBidWlsZCB0aW1lIGluIHBhY2thZ2UuanNvblxuLy8gY29uc3QgZGV2ID0gMDtcbi8vIGNvbnN0IHByb2R1Y3Rpb24gPSAxO1xuaWYgKEVOViA9PT0gMSkge1xuICAgIGRlbGV0ZSB3aW5kb3cud2FpbHNiaW5kaW5ncztcbn1cblxubGV0IGRyYWdUZXN0ID0gZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgdmFsID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZS50YXJnZXQpLmdldFByb3BlcnR5VmFsdWUod2luZG93LndhaWxzLmZsYWdzLmNzc0RyYWdQcm9wZXJ0eSk7XG4gICAgaWYgKHZhbCkge1xuICAgICAgdmFsID0gdmFsLnRyaW0oKTtcbiAgICB9XG4gICAgXG4gICAgaWYgKHZhbCAhPT0gd2luZG93LndhaWxzLmZsYWdzLmNzc0RyYWdWYWx1ZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKGUuYnV0dG9ucyAhPT0gMSkge1xuICAgICAgICAvLyBEbyBub3Qgc3RhcnQgZHJhZ2dpbmcgaWYgbm90IHRoZSBwcmltYXJ5IGJ1dHRvbiBoYXMgYmVlbiBjbGlja2VkLlxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKGUuZGV0YWlsICE9PSAxKSB7XG4gICAgICAgIC8vIERvIG5vdCBzdGFydCBkcmFnZ2luZyBpZiBtb3JlIHRoYW4gb25jZSBoYXMgYmVlbiBjbGlja2VkLCBlLmcuIHdoZW4gZG91YmxlIGNsaWNraW5nXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5cbndpbmRvdy53YWlscy5zZXRDU1NEcmFnUHJvcGVydGllcyA9IGZ1bmN0aW9uIChwcm9wZXJ0eSwgdmFsdWUpIHtcbiAgICB3aW5kb3cud2FpbHMuZmxhZ3MuY3NzRHJhZ1Byb3BlcnR5ID0gcHJvcGVydHk7XG4gICAgd2luZG93LndhaWxzLmZsYWdzLmNzc0RyYWdWYWx1ZSA9IHZhbHVlO1xufVxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgKGUpID0+IHtcblxuICAgIC8vIENoZWNrIGZvciByZXNpemluZ1xuICAgIGlmICh3aW5kb3cud2FpbHMuZmxhZ3MucmVzaXplRWRnZSkge1xuICAgICAgICB3aW5kb3cuV2FpbHNJbnZva2UoXCJyZXNpemU6XCIgKyB3aW5kb3cud2FpbHMuZmxhZ3MucmVzaXplRWRnZSk7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChkcmFnVGVzdChlKSkge1xuICAgICAgICBpZiAod2luZG93LndhaWxzLmZsYWdzLmRpc2FibGVTY3JvbGxiYXJEcmFnKSB7XG4gICAgICAgICAgICAvLyBUaGlzIGNoZWNrcyBmb3IgY2xpY2tzIG9uIHRoZSBzY3JvbGwgYmFyXG4gICAgICAgICAgICBpZiAoZS5vZmZzZXRYID4gZS50YXJnZXQuY2xpZW50V2lkdGggfHwgZS5vZmZzZXRZID4gZS50YXJnZXQuY2xpZW50SGVpZ2h0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh3aW5kb3cud2FpbHMuZmxhZ3MuZGVmZXJEcmFnVG9Nb3VzZU1vdmUpIHtcbiAgICAgICAgICAgIHdpbmRvdy53YWlscy5mbGFncy5zaG91bGREcmFnID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgICAgICAgd2luZG93LldhaWxzSW52b2tlKFwiZHJhZ1wiKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgfSBlbHNlIHtcbiAgICAgICAgd2luZG93LndhaWxzLmZsYWdzLnNob3VsZERyYWcgPSBmYWxzZTtcbiAgICB9XG59KTtcblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCAoKSA9PiB7XG4gICAgd2luZG93LndhaWxzLmZsYWdzLnNob3VsZERyYWcgPSBmYWxzZTtcbn0pO1xuXG5mdW5jdGlvbiBzZXRSZXNpemUoY3Vyc29yKSB7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLmN1cnNvciA9IGN1cnNvciB8fCB3aW5kb3cud2FpbHMuZmxhZ3MuZGVmYXVsdEN1cnNvcjtcbiAgICB3aW5kb3cud2FpbHMuZmxhZ3MucmVzaXplRWRnZSA9IGN1cnNvcjtcbn1cblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKHdpbmRvdy53YWlscy5mbGFncy5zaG91bGREcmFnKSB7XG4gICAgICAgIHdpbmRvdy53YWlscy5mbGFncy5zaG91bGREcmFnID0gZmFsc2U7XG4gICAgICAgIGxldCBtb3VzZVByZXNzZWQgPSBlLmJ1dHRvbnMgIT09IHVuZGVmaW5lZCA/IGUuYnV0dG9ucyA6IGUud2hpY2g7XG4gICAgICAgIGlmIChtb3VzZVByZXNzZWQgPiAwKSB7XG4gICAgICAgICAgICB3aW5kb3cuV2FpbHNJbnZva2UoXCJkcmFnXCIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICghd2luZG93LndhaWxzLmZsYWdzLmVuYWJsZVJlc2l6ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh3aW5kb3cud2FpbHMuZmxhZ3MuZGVmYXVsdEN1cnNvciA9PSBudWxsKSB7XG4gICAgICAgIHdpbmRvdy53YWlscy5mbGFncy5kZWZhdWx0Q3Vyc29yID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLmN1cnNvcjtcbiAgICB9XG4gICAgaWYgKHdpbmRvdy5vdXRlcldpZHRoIC0gZS5jbGllbnRYIDwgd2luZG93LndhaWxzLmZsYWdzLmJvcmRlclRoaWNrbmVzcyAmJiB3aW5kb3cub3V0ZXJIZWlnaHQgLSBlLmNsaWVudFkgPCB3aW5kb3cud2FpbHMuZmxhZ3MuYm9yZGVyVGhpY2tuZXNzKSB7XG4gICAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5jdXJzb3IgPSBcInNlLXJlc2l6ZVwiO1xuICAgIH1cbiAgICBsZXQgcmlnaHRCb3JkZXIgPSB3aW5kb3cub3V0ZXJXaWR0aCAtIGUuY2xpZW50WCA8IHdpbmRvdy53YWlscy5mbGFncy5ib3JkZXJUaGlja25lc3M7XG4gICAgbGV0IGxlZnRCb3JkZXIgPSBlLmNsaWVudFggPCB3aW5kb3cud2FpbHMuZmxhZ3MuYm9yZGVyVGhpY2tuZXNzO1xuICAgIGxldCB0b3BCb3JkZXIgPSBlLmNsaWVudFkgPCB3aW5kb3cud2FpbHMuZmxhZ3MuYm9yZGVyVGhpY2tuZXNzO1xuICAgIGxldCBib3R0b21Cb3JkZXIgPSB3aW5kb3cub3V0ZXJIZWlnaHQgLSBlLmNsaWVudFkgPCB3aW5kb3cud2FpbHMuZmxhZ3MuYm9yZGVyVGhpY2tuZXNzO1xuXG4gICAgLy8gSWYgd2UgYXJlbid0IG9uIGFuIGVkZ2UsIGJ1dCB3ZXJlLCByZXNldCB0aGUgY3Vyc29yIHRvIGRlZmF1bHRcbiAgICBpZiAoIWxlZnRCb3JkZXIgJiYgIXJpZ2h0Qm9yZGVyICYmICF0b3BCb3JkZXIgJiYgIWJvdHRvbUJvcmRlciAmJiB3aW5kb3cud2FpbHMuZmxhZ3MucmVzaXplRWRnZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHNldFJlc2l6ZSgpO1xuICAgIH0gZWxzZSBpZiAocmlnaHRCb3JkZXIgJiYgYm90dG9tQm9yZGVyKSBzZXRSZXNpemUoXCJzZS1yZXNpemVcIik7XG4gICAgZWxzZSBpZiAobGVmdEJvcmRlciAmJiBib3R0b21Cb3JkZXIpIHNldFJlc2l6ZShcInN3LXJlc2l6ZVwiKTtcbiAgICBlbHNlIGlmIChsZWZ0Qm9yZGVyICYmIHRvcEJvcmRlcikgc2V0UmVzaXplKFwibnctcmVzaXplXCIpO1xuICAgIGVsc2UgaWYgKHRvcEJvcmRlciAmJiByaWdodEJvcmRlcikgc2V0UmVzaXplKFwibmUtcmVzaXplXCIpO1xuICAgIGVsc2UgaWYgKGxlZnRCb3JkZXIpIHNldFJlc2l6ZShcInctcmVzaXplXCIpO1xuICAgIGVsc2UgaWYgKHRvcEJvcmRlcikgc2V0UmVzaXplKFwibi1yZXNpemVcIik7XG4gICAgZWxzZSBpZiAoYm90dG9tQm9yZGVyKSBzZXRSZXNpemUoXCJzLXJlc2l6ZVwiKTtcbiAgICBlbHNlIGlmIChyaWdodEJvcmRlcikgc2V0UmVzaXplKFwiZS1yZXNpemVcIik7XG5cbn0pO1xuXG4vLyBTZXR1cCBjb250ZXh0IG1lbnUgaG9va1xud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAod2luZG93LndhaWxzLmZsYWdzLmRpc2FibGVXYWlsc0RlZmF1bHRDb250ZXh0TWVudSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxufSk7XG5cbndpbmRvdy5XYWlsc0ludm9rZShcInJ1bnRpbWU6cmVhZHlcIik7Il0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7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QSxFQUNwQztBQUVBLFNBQU8saUJBQWlCLGFBQWEsU0FBVSxHQUFHO0FBQzlDLFFBQUksT0FBTyxNQUFNLE1BQU0sWUFBWTtBQUMvQixhQUFPLE1BQU0sTUFBTSxhQUFhO0FBQ2hDLFVBQUksZUFBZSxFQUFFLFlBQVksU0FBWSxFQUFFLFVBQVUsRUFBRTtBQUMzRCxVQUFJLGVBQWUsR0FBRztBQUNsQixlQUFPLFlBQVksTUFBTTtBQUN6QjtBQUFBLE1BQ0o7QUFBQSxJQUNKO0FBQ0EsUUFBSSxDQUFDLE9BQU8sTUFBTSxNQUFNLGNBQWM7QUFDbEM7QUFBQSxJQUNKO0FBQ0EsUUFBSSxPQUFPLE1BQU0sTUFBTSxpQkFBaUIsTUFBTTtBQUMxQyxhQUFPLE1BQU0sTUFBTSxnQkFBZ0IsU0FBUyxnQkFBZ0IsTUFBTTtBQUFBLElBQ3RFO0FBQ0EsUUFBSSxPQUFPLGFBQWEsRUFBRSxVQUFVLE9BQU8sTUFBTSxNQUFNLG1CQUFtQixPQUFPLGNBQWMsRUFBRSxVQUFVLE9BQU8sTUFBTSxNQUFNLGlCQUFpQjtBQUMzSSxlQUFTLGdCQUFnQixNQUFNLFNBQVM7QUFBQSxJQUM1QztBQUNBLFFBQUksY0FBYyxPQUFPLGFBQWEsRUFBRSxVQUFVLE9BQU8sTUFBTSxNQUFNO0FBQ3JFLFFBQUksYUFBYSxFQUFFLFVBQVUsT0FBTyxNQUFNLE1BQU07QUFDaEQsUUFBSSxZQUFZLEVBQUUsVUFBVSxPQUFPLE1BQU0sTUFBTTtBQUMvQyxRQUFJLGVBQWUsT0FBTyxjQUFjLEVBQUUsVUFBVSxPQUFPLE1BQU0sTUFBTTtBQUd2RSxRQUFJLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsZ0JBQWdCLE9BQU8sTUFBTSxNQUFNLGVBQWUsUUFBVztBQUMzRyxnQkFBVTtBQUFBLElBQ2QsV0FBVyxlQUFlO0FBQWMsZ0JBQVUsV0FBVztBQUFBLGFBQ3BELGNBQWM7QUFBYyxnQkFBVSxXQUFXO0FBQUEsYUFDakQsY0FBYztBQUFXLGdCQUFVLFdBQVc7QUFBQSxhQUM5QyxhQUFhO0FBQWEsZ0JBQVUsV0FBVztBQUFBLGFBQy9DO0FBQVksZ0JBQVUsVUFBVTtBQUFBLGFBQ2hDO0FBQVcsZ0JBQVUsVUFBVTtBQUFBLGFBQy9CO0FBQWMsZ0JBQVUsVUFBVTtBQUFBLGFBQ2xDO0FBQWEsZ0JBQVUsVUFBVTtBQUFBLEVBRTlDLENBQUM7QUFHRCxTQUFPLGlCQUFpQixlQUFlLFNBQVUsR0FBRztBQUNoRCxRQUFJLE9BQU8sTUFBTSxNQUFNLGdDQUFnQztBQUNuRCxRQUFFLGVBQWU7QUFBQSxJQUNyQjtBQUFBLEVBQ0osQ0FBQztBQUVELFNBQU8sWUFBWSxlQUFlOyIsCiAgIm5hbWVzIjogWyJldmVudE5hbWUiXQp9Cg== +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiZGVza3RvcC9sb2cuanMiLCAiZGVza3RvcC9ldmVudHMuanMiLCAiZGVza3RvcC9jYWxscy5qcyIsICJkZXNrdG9wL2JpbmRpbmdzLmpzIiwgImRlc2t0b3Avd2luZG93LmpzIiwgImRlc2t0b3Avc2NyZWVuLmpzIiwgImRlc2t0b3AvYnJvd3Nlci5qcyIsICJkZXNrdG9wL2NsaXBib2FyZC5qcyIsICJkZXNrdG9wL21haW4uanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qXG4gXyAgICAgICBfXyAgICAgIF8gX19cbnwgfCAgICAgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA2ICovXG5cbi8qKlxuICogU2VuZHMgYSBsb2cgbWVzc2FnZSB0byB0aGUgYmFja2VuZCB3aXRoIHRoZSBnaXZlbiBsZXZlbCArIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbGV2ZWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmZ1bmN0aW9uIHNlbmRMb2dNZXNzYWdlKGxldmVsLCBtZXNzYWdlKSB7XG5cblx0Ly8gTG9nIE1lc3NhZ2UgZm9ybWF0OlxuXHQvLyBsW3R5cGVdW21lc3NhZ2VdXG5cdHdpbmRvdy5XYWlsc0ludm9rZSgnTCcgKyBsZXZlbCArIG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIExvZyB0aGUgZ2l2ZW4gdHJhY2UgbWVzc2FnZSB3aXRoIHRoZSBiYWNrZW5kXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIExvZ1RyYWNlKG1lc3NhZ2UpIHtcblx0c2VuZExvZ01lc3NhZ2UoJ1QnLCBtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBMb2cgdGhlIGdpdmVuIG1lc3NhZ2Ugd2l0aCB0aGUgYmFja2VuZFxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMb2dQcmludChtZXNzYWdlKSB7XG5cdHNlbmRMb2dNZXNzYWdlKCdQJywgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogTG9nIHRoZSBnaXZlbiBkZWJ1ZyBtZXNzYWdlIHdpdGggdGhlIGJhY2tlbmRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gTG9nRGVidWcobWVzc2FnZSkge1xuXHRzZW5kTG9nTWVzc2FnZSgnRCcsIG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIExvZyB0aGUgZ2l2ZW4gaW5mbyBtZXNzYWdlIHdpdGggdGhlIGJhY2tlbmRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gTG9nSW5mbyhtZXNzYWdlKSB7XG5cdHNlbmRMb2dNZXNzYWdlKCdJJywgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogTG9nIHRoZSBnaXZlbiB3YXJuaW5nIG1lc3NhZ2Ugd2l0aCB0aGUgYmFja2VuZFxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMb2dXYXJuaW5nKG1lc3NhZ2UpIHtcblx0c2VuZExvZ01lc3NhZ2UoJ1cnLCBtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBMb2cgdGhlIGdpdmVuIGVycm9yIG1lc3NhZ2Ugd2l0aCB0aGUgYmFja2VuZFxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMb2dFcnJvcihtZXNzYWdlKSB7XG5cdHNlbmRMb2dNZXNzYWdlKCdFJywgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogTG9nIHRoZSBnaXZlbiBmYXRhbCBtZXNzYWdlIHdpdGggdGhlIGJhY2tlbmRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gTG9nRmF0YWwobWVzc2FnZSkge1xuXHRzZW5kTG9nTWVzc2FnZSgnRicsIG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIFNldHMgdGhlIExvZyBsZXZlbCB0byB0aGUgZ2l2ZW4gbG9nIGxldmVsXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IGxvZ2xldmVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBTZXRMb2dMZXZlbChsb2dsZXZlbCkge1xuXHRzZW5kTG9nTWVzc2FnZSgnUycsIGxvZ2xldmVsKTtcbn1cblxuLy8gTG9nIGxldmVsc1xuZXhwb3J0IGNvbnN0IExvZ0xldmVsID0ge1xuXHRUUkFDRTogMSxcblx0REVCVUc6IDIsXG5cdElORk86IDMsXG5cdFdBUk5JTkc6IDQsXG5cdEVSUk9SOiA1LFxufTtcbiIsICIvKlxuIF8gICAgICAgX18gICAgICBfIF9fXG58IHwgICAgIC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cbi8qIGpzaGludCBlc3ZlcnNpb246IDYgKi9cblxuLy8gRGVmaW5lcyBhIHNpbmdsZSBsaXN0ZW5lciB3aXRoIGEgbWF4aW11bSBudW1iZXIgb2YgdGltZXMgdG8gY2FsbGJhY2tcblxuLyoqXG4gKiBUaGUgTGlzdGVuZXIgY2xhc3MgZGVmaW5lcyBhIGxpc3RlbmVyISA6LSlcbiAqXG4gKiBAY2xhc3MgTGlzdGVuZXJcbiAqL1xuY2xhc3MgTGlzdGVuZXIge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgTGlzdGVuZXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1heENhbGxiYWNrc1xuICAgICAqIEBtZW1iZXJvZiBMaXN0ZW5lclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGV2ZW50TmFtZSwgY2FsbGJhY2ssIG1heENhbGxiYWNrcykge1xuICAgICAgICB0aGlzLmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcbiAgICAgICAgLy8gRGVmYXVsdCBvZiAtMSBtZWFucyBpbmZpbml0ZVxuICAgICAgICB0aGlzLm1heENhbGxiYWNrcyA9IG1heENhbGxiYWNrcyB8fCAtMTtcbiAgICAgICAgLy8gQ2FsbGJhY2sgaW52b2tlcyB0aGUgY2FsbGJhY2sgd2l0aCB0aGUgZ2l2ZW4gZGF0YVxuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBsaXN0ZW5lciBzaG91bGQgYmUgZGVzdHJveWVkXG4gICAgICAgIHRoaXMuQ2FsbGJhY2sgPSAoZGF0YSkgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkobnVsbCwgZGF0YSk7XG4gICAgICAgICAgICAvLyBJZiBtYXhDYWxsYmFja3MgaXMgaW5maW5pdGUsIHJldHVybiBmYWxzZSAoZG8gbm90IGRlc3Ryb3kpXG4gICAgICAgICAgICBpZiAodGhpcy5tYXhDYWxsYmFja3MgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRGVjcmVtZW50IG1heENhbGxiYWNrcy4gUmV0dXJuIHRydWUgaWYgbm93IDAsIG90aGVyd2lzZSBmYWxzZVxuICAgICAgICAgICAgdGhpcy5tYXhDYWxsYmFja3MgLT0gMTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1heENhbGxiYWNrcyA9PT0gMDtcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmV4cG9ydCBjb25zdCBldmVudExpc3RlbmVycyA9IHt9O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBgbWF4Q2FsbGJhY2tzYCB0aW1lcyBiZWZvcmUgYmVpbmcgZGVzdHJveWVkXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhDYWxsYmFja3NcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGxpc3RlbmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIG1heENhbGxiYWNrcykge1xuICAgIGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0gPSBldmVudExpc3RlbmVyc1tldmVudE5hbWVdIHx8IFtdO1xuICAgIGNvbnN0IHRoaXNMaXN0ZW5lciA9IG5ldyBMaXN0ZW5lcihldmVudE5hbWUsIGNhbGxiYWNrLCBtYXhDYWxsYmFja3MpO1xuICAgIGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0ucHVzaCh0aGlzTGlzdGVuZXIpO1xuICAgIHJldHVybiAoKSA9PiBsaXN0ZW5lck9mZih0aGlzTGlzdGVuZXIpO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBldmVyeSB0aW1lIHRoZSBldmVudCBpcyBlbWl0dGVkXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGxpc3RlbmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNPbihldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIEV2ZW50c09uTXVsdGlwbGUoZXZlbnROYW1lLCBjYWxsYmFjaywgLTEpO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBvbmNlIHRoZW4gZGVzdHJveWVkXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGxpc3RlbmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNPbmNlKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gRXZlbnRzT25NdWx0aXBsZShldmVudE5hbWUsIGNhbGxiYWNrLCAxKTtcbn1cblxuZnVuY3Rpb24gbm90aWZ5TGlzdGVuZXJzKGV2ZW50RGF0YSkge1xuXG4gICAgLy8gR2V0IHRoZSBldmVudCBuYW1lXG4gICAgbGV0IGV2ZW50TmFtZSA9IGV2ZW50RGF0YS5uYW1lO1xuXG4gICAgLy8gQ2hlY2sgaWYgd2UgaGF2ZSBhbnkgbGlzdGVuZXJzIGZvciB0aGlzIGV2ZW50XG4gICAgaWYgKGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0pIHtcblxuICAgICAgICAvLyBLZWVwIGEgbGlzdCBvZiBsaXN0ZW5lciBpbmRleGVzIHRvIGRlc3Ryb3lcbiAgICAgICAgY29uc3QgbmV3RXZlbnRMaXN0ZW5lckxpc3QgPSBldmVudExpc3RlbmVyc1tldmVudE5hbWVdLnNsaWNlKCk7XG5cbiAgICAgICAgLy8gSXRlcmF0ZSBsaXN0ZW5lcnNcbiAgICAgICAgZm9yIChsZXQgY291bnQgPSBldmVudExpc3RlbmVyc1tldmVudE5hbWVdLmxlbmd0aCAtIDE7IGNvdW50ID49IDA7IGNvdW50IC09IDEpIHtcblxuICAgICAgICAgICAgLy8gR2V0IG5leHQgbGlzdGVuZXJcbiAgICAgICAgICAgIGNvbnN0IGxpc3RlbmVyID0gZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXVtjb3VudF07XG5cbiAgICAgICAgICAgIGxldCBkYXRhID0gZXZlbnREYXRhLmRhdGE7XG5cbiAgICAgICAgICAgIC8vIERvIHRoZSBjYWxsYmFja1xuICAgICAgICAgICAgY29uc3QgZGVzdHJveSA9IGxpc3RlbmVyLkNhbGxiYWNrKGRhdGEpO1xuICAgICAgICAgICAgaWYgKGRlc3Ryb3kpIHtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgbGlzdGVuZXIgaW5kaWNhdGVkIHRvIGRlc3Ryb3kgaXRzZWxmLCBhZGQgaXQgdG8gdGhlIGRlc3Ryb3kgbGlzdFxuICAgICAgICAgICAgICAgIG5ld0V2ZW50TGlzdGVuZXJMaXN0LnNwbGljZShjb3VudCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVcGRhdGUgY2FsbGJhY2tzIHdpdGggbmV3IGxpc3Qgb2YgbGlzdGVuZXJzXG4gICAgICAgIGlmIChuZXdFdmVudExpc3RlbmVyTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBldmVudExpc3RlbmVyc1tldmVudE5hbWVdID0gbmV3RXZlbnRMaXN0ZW5lckxpc3Q7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogTm90aWZ5IGluZm9ybXMgZnJvbnRlbmQgbGlzdGVuZXJzIHRoYXQgYW4gZXZlbnQgd2FzIGVtaXR0ZWQgd2l0aCB0aGUgZ2l2ZW4gZGF0YVxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBub3RpZnlNZXNzYWdlIC0gZW5jb2RlZCBub3RpZmljYXRpb24gbWVzc2FnZVxuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNOb3RpZnkobm90aWZ5TWVzc2FnZSkge1xuICAgIC8vIFBhcnNlIHRoZSBtZXNzYWdlXG4gICAgbGV0IG1lc3NhZ2U7XG4gICAgdHJ5IHtcbiAgICAgICAgbWVzc2FnZSA9IEpTT04ucGFyc2Uobm90aWZ5TWVzc2FnZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zdCBlcnJvciA9ICdJbnZhbGlkIEpTT04gcGFzc2VkIHRvIE5vdGlmeTogJyArIG5vdGlmeU1lc3NhZ2U7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG4gICAgfVxuICAgIG5vdGlmeUxpc3RlbmVycyhtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBFbWl0IGFuIGV2ZW50IHdpdGggdGhlIGdpdmVuIG5hbWUgYW5kIGRhdGFcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNFbWl0KGV2ZW50TmFtZSkge1xuXG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgbmFtZTogZXZlbnROYW1lLFxuICAgICAgICBkYXRhOiBbXS5zbGljZS5hcHBseShhcmd1bWVudHMpLnNsaWNlKDEpLFxuICAgIH07XG5cbiAgICAvLyBOb3RpZnkgSlMgbGlzdGVuZXJzXG4gICAgbm90aWZ5TGlzdGVuZXJzKHBheWxvYWQpO1xuXG4gICAgLy8gTm90aWZ5IEdvIGxpc3RlbmVyc1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnRUUnICsgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xufVxuXG5mdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihldmVudE5hbWUpIHtcbiAgICAvLyBSZW1vdmUgbG9jYWwgbGlzdGVuZXJzXG4gICAgZGVsZXRlIGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV07XG5cbiAgICAvLyBOb3RpZnkgR28gbGlzdGVuZXJzXG4gICAgd2luZG93LldhaWxzSW52b2tlKCdFWCcgKyBldmVudE5hbWUpO1xufVxuXG4vKipcbiAqIE9mZiB1bnJlZ2lzdGVycyBhIGxpc3RlbmVyIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCB3aXRoIE9uLFxuICogb3B0aW9uYWxseSBtdWx0aXBsZSBsaXN0ZW5lcmVzIGNhbiBiZSB1bnJlZ2lzdGVyZWQgdmlhIGBhZGRpdGlvbmFsRXZlbnROYW1lc2BcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gKiBAcGFyYW0gIHsuLi5zdHJpbmd9IGFkZGl0aW9uYWxFdmVudE5hbWVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNPZmYoZXZlbnROYW1lLCAuLi5hZGRpdGlvbmFsRXZlbnROYW1lcykge1xuICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSlcblxuICAgIGlmIChhZGRpdGlvbmFsRXZlbnROYW1lcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGFkZGl0aW9uYWxFdmVudE5hbWVzLmZvckVhY2goZXZlbnROYW1lID0+IHtcbiAgICAgICAgICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSlcbiAgICAgICAgfSlcbiAgICB9XG59XG5cbi8qKlxuICogT2ZmIHVucmVnaXN0ZXJzIGFsbCBldmVudCBsaXN0ZW5lcnMgcHJldmlvdXNseSByZWdpc3RlcmVkIHdpdGggT25cbiAqL1xuIGV4cG9ydCBmdW5jdGlvbiBFdmVudHNPZmZBbGwoKSB7XG4gICAgY29uc3QgZXZlbnROYW1lcyA9IE9iamVjdC5rZXlzKGV2ZW50TGlzdGVuZXJzKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSAhPT0gZXZlbnROYW1lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICByZW1vdmVMaXN0ZW5lcihldmVudE5hbWVzW2ldKTtcbiAgICB9XG59XG5cbi8qKlxuICogbGlzdGVuZXJPZmYgdW5yZWdpc3RlcnMgYSBsaXN0ZW5lciBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBFdmVudHNPblxuICpcbiAqIEBwYXJhbSB7TGlzdGVuZXJ9IGxpc3RlbmVyXG4gKi9cbiBmdW5jdGlvbiBsaXN0ZW5lck9mZihsaXN0ZW5lcikge1xuICAgIGNvbnN0IGV2ZW50TmFtZSA9IGxpc3RlbmVyLmV2ZW50TmFtZTtcbiAgICAvLyBSZW1vdmUgbG9jYWwgbGlzdGVuZXJcbiAgICBldmVudExpc3RlbmVyc1tldmVudE5hbWVdID0gZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXS5maWx0ZXIobCA9PiBsICE9PSBsaXN0ZW5lcik7XG5cbiAgICAvLyBDbGVhbiB1cCBpZiB0aGVyZSBhcmUgbm8gZXZlbnQgbGlzdGVuZXJzIGxlZnRcbiAgICBpZiAoZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmVtb3ZlTGlzdGVuZXIoZXZlbnROYW1lKTtcbiAgICB9XG59XG4iLCAiLypcbiBfICAgICAgIF9fICAgICAgXyBfX1xufCB8ICAgICAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA2ICovXG5cbmV4cG9ydCBjb25zdCBjYWxsYmFja3MgPSB7fTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgbnVtYmVyIGZyb20gdGhlIG5hdGl2ZSBicm93c2VyIHJhbmRvbSBmdW5jdGlvblxuICpcbiAqIEByZXR1cm5zIG51bWJlclxuICovXG5mdW5jdGlvbiBjcnlwdG9SYW5kb20oKSB7XG5cdHZhciBhcnJheSA9IG5ldyBVaW50MzJBcnJheSgxKTtcblx0cmV0dXJuIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycmF5KVswXTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbnVtYmVyIHVzaW5nIGRhIG9sZC1za29vbCBNYXRoLlJhbmRvbVxuICogSSBsaWtlcyB0byBjYWxsIGl0IExPTFJhbmRvbVxuICpcbiAqIEByZXR1cm5zIG51bWJlclxuICovXG5mdW5jdGlvbiBiYXNpY1JhbmRvbSgpIHtcblx0cmV0dXJuIE1hdGgucmFuZG9tKCkgKiA5MDA3MTk5MjU0NzQwOTkxO1xufVxuXG4vLyBQaWNrIGEgcmFuZG9tIG51bWJlciBmdW5jdGlvbiBiYXNlZCBvbiBicm93c2VyIGNhcGFiaWxpdHlcbnZhciByYW5kb21GdW5jO1xuaWYgKHdpbmRvdy5jcnlwdG8pIHtcblx0cmFuZG9tRnVuYyA9IGNyeXB0b1JhbmRvbTtcbn0gZWxzZSB7XG5cdHJhbmRvbUZ1bmMgPSBiYXNpY1JhbmRvbTtcbn1cblxuXG4vKipcbiAqIENhbGwgc2VuZHMgYSBtZXNzYWdlIHRvIHRoZSBiYWNrZW5kIHRvIGNhbGwgdGhlIGJpbmRpbmcgd2l0aCB0aGVcbiAqIGdpdmVuIGRhdGEuIEEgcHJvbWlzZSBpcyByZXR1cm5lZCBhbmQgd2lsbCBiZSBjb21wbGV0ZWQgd2hlbiB0aGVcbiAqIGJhY2tlbmQgcmVzcG9uZHMuIFRoaXMgd2lsbCBiZSByZXNvbHZlZCB3aGVuIHRoZSBjYWxsIHdhcyBzdWNjZXNzZnVsXG4gKiBvciByZWplY3RlZCBpZiBhbiBlcnJvciBpcyBwYXNzZWQgYmFjay5cbiAqIFRoZXJlIGlzIGEgdGltZW91dCBtZWNoYW5pc20uIElmIHRoZSBjYWxsIGRvZXNuJ3QgcmVzcG9uZCBpbiB0aGUgZ2l2ZW5cbiAqIHRpbWUgKGluIG1pbGxpc2Vjb25kcykgdGhlbiB0aGUgcHJvbWlzZSBpcyByZWplY3RlZC5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHBhcmFtIHthbnk9fSBhcmdzXG4gKiBAcGFyYW0ge251bWJlcj19IHRpbWVvdXRcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDYWxsKG5hbWUsIGFyZ3MsIHRpbWVvdXQpIHtcblxuXHQvLyBUaW1lb3V0IGluZmluaXRlIGJ5IGRlZmF1bHRcblx0aWYgKHRpbWVvdXQgPT0gbnVsbCkge1xuXHRcdHRpbWVvdXQgPSAwO1xuXHR9XG5cblx0Ly8gQ3JlYXRlIGEgcHJvbWlzZVxuXHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXG5cdFx0Ly8gQ3JlYXRlIGEgdW5pcXVlIGNhbGxiYWNrSURcblx0XHR2YXIgY2FsbGJhY2tJRDtcblx0XHRkbyB7XG5cdFx0XHRjYWxsYmFja0lEID0gbmFtZSArICctJyArIHJhbmRvbUZ1bmMoKTtcblx0XHR9IHdoaWxlIChjYWxsYmFja3NbY2FsbGJhY2tJRF0pO1xuXG5cdFx0dmFyIHRpbWVvdXRIYW5kbGU7XG5cdFx0Ly8gU2V0IHRpbWVvdXRcblx0XHRpZiAodGltZW91dCA+IDApIHtcblx0XHRcdHRpbWVvdXRIYW5kbGUgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0cmVqZWN0KEVycm9yKCdDYWxsIHRvICcgKyBuYW1lICsgJyB0aW1lZCBvdXQuIFJlcXVlc3QgSUQ6ICcgKyBjYWxsYmFja0lEKSk7XG5cdFx0XHR9LCB0aW1lb3V0KTtcblx0XHR9XG5cblx0XHQvLyBTdG9yZSBjYWxsYmFja1xuXHRcdGNhbGxiYWNrc1tjYWxsYmFja0lEXSA9IHtcblx0XHRcdHRpbWVvdXRIYW5kbGU6IHRpbWVvdXRIYW5kbGUsXG5cdFx0XHRyZWplY3Q6IHJlamVjdCxcblx0XHRcdHJlc29sdmU6IHJlc29sdmVcblx0XHR9O1xuXG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHBheWxvYWQgPSB7XG5cdFx0XHRcdG5hbWUsXG5cdFx0XHRcdGFyZ3MsXG5cdFx0XHRcdGNhbGxiYWNrSUQsXG5cdFx0XHR9O1xuXG4gICAgICAgICAgICAvLyBNYWtlIHRoZSBjYWxsXG4gICAgICAgICAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ0MnICsgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxud2luZG93Lk9iZnVzY2F0ZWRDYWxsID0gKGlkLCBhcmdzLCB0aW1lb3V0KSA9PiB7XG5cbiAgICAvLyBUaW1lb3V0IGluZmluaXRlIGJ5IGRlZmF1bHRcbiAgICBpZiAodGltZW91dCA9PSBudWxsKSB7XG4gICAgICAgIHRpbWVvdXQgPSAwO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBhIHByb21pc2VcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXG4gICAgICAgIC8vIENyZWF0ZSBhIHVuaXF1ZSBjYWxsYmFja0lEXG4gICAgICAgIHZhciBjYWxsYmFja0lEO1xuICAgICAgICBkbyB7XG4gICAgICAgICAgICBjYWxsYmFja0lEID0gaWQgKyAnLScgKyByYW5kb21GdW5jKCk7XG4gICAgICAgIH0gd2hpbGUgKGNhbGxiYWNrc1tjYWxsYmFja0lEXSk7XG5cbiAgICAgICAgdmFyIHRpbWVvdXRIYW5kbGU7XG4gICAgICAgIC8vIFNldCB0aW1lb3V0XG4gICAgICAgIGlmICh0aW1lb3V0ID4gMCkge1xuICAgICAgICAgICAgdGltZW91dEhhbmRsZSA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignQ2FsbCB0byBtZXRob2QgJyArIGlkICsgJyB0aW1lZCBvdXQuIFJlcXVlc3QgSUQ6ICcgKyBjYWxsYmFja0lEKSk7XG4gICAgICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0b3JlIGNhbGxiYWNrXG4gICAgICAgIGNhbGxiYWNrc1tjYWxsYmFja0lEXSA9IHtcbiAgICAgICAgICAgIHRpbWVvdXRIYW5kbGU6IHRpbWVvdXRIYW5kbGUsXG4gICAgICAgICAgICByZWplY3Q6IHJlamVjdCxcbiAgICAgICAgICAgIHJlc29sdmU6IHJlc29sdmVcbiAgICAgICAgfTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcblx0XHRcdFx0aWQsXG5cdFx0XHRcdGFyZ3MsXG5cdFx0XHRcdGNhbGxiYWNrSUQsXG5cdFx0XHR9O1xuXG4gICAgICAgICAgICAvLyBNYWtlIHRoZSBjYWxsXG4gICAgICAgICAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ2MnICsgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG5cblxuLyoqXG4gKiBDYWxsZWQgYnkgdGhlIGJhY2tlbmQgdG8gcmV0dXJuIGRhdGEgdG8gYSBwcmV2aW91c2x5IGNhbGxlZFxuICogYmluZGluZyBpbnZvY2F0aW9uXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IGluY29taW5nTWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gQ2FsbGJhY2soaW5jb21pbmdNZXNzYWdlKSB7XG5cdC8vIFBhcnNlIHRoZSBtZXNzYWdlXG5cdGxldCBtZXNzYWdlO1xuXHR0cnkge1xuXHRcdG1lc3NhZ2UgPSBKU09OLnBhcnNlKGluY29taW5nTWVzc2FnZSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRjb25zdCBlcnJvciA9IGBJbnZhbGlkIEpTT04gcGFzc2VkIHRvIGNhbGxiYWNrOiAke2UubWVzc2FnZX0uIE1lc3NhZ2U6ICR7aW5jb21pbmdNZXNzYWdlfWA7XG5cdFx0cnVudGltZS5Mb2dEZWJ1ZyhlcnJvcik7XG5cdFx0dGhyb3cgbmV3IEVycm9yKGVycm9yKTtcblx0fVxuXHRsZXQgY2FsbGJhY2tJRCA9IG1lc3NhZ2UuY2FsbGJhY2tpZDtcblx0bGV0IGNhbGxiYWNrRGF0YSA9IGNhbGxiYWNrc1tjYWxsYmFja0lEXTtcblx0aWYgKCFjYWxsYmFja0RhdGEpIHtcblx0XHRjb25zdCBlcnJvciA9IGBDYWxsYmFjayAnJHtjYWxsYmFja0lEfScgbm90IHJlZ2lzdGVyZWQhISFgO1xuXHRcdGNvbnNvbGUuZXJyb3IoZXJyb3IpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdFx0dGhyb3cgbmV3IEVycm9yKGVycm9yKTtcblx0fVxuXHRjbGVhclRpbWVvdXQoY2FsbGJhY2tEYXRhLnRpbWVvdXRIYW5kbGUpO1xuXG5cdGRlbGV0ZSBjYWxsYmFja3NbY2FsbGJhY2tJRF07XG5cblx0aWYgKG1lc3NhZ2UuZXJyb3IpIHtcblx0XHRjYWxsYmFja0RhdGEucmVqZWN0KG1lc3NhZ2UuZXJyb3IpO1xuXHR9IGVsc2Uge1xuXHRcdGNhbGxiYWNrRGF0YS5yZXNvbHZlKG1lc3NhZ2UucmVzdWx0KTtcblx0fVxufVxuIiwgIi8qXG4gXyAgICAgICBfXyAgICAgIF8gX18gICAgXG58IHwgICAgIC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gICkgXG58X18vfF9fL1xcX18sXy9fL18vX19fXy8gIFxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cbi8qIGpzaGludCBlc3ZlcnNpb246IDYgKi9cblxuaW1wb3J0IHtDYWxsfSBmcm9tICcuL2NhbGxzJztcblxuLy8gVGhpcyBpcyB3aGVyZSB3ZSBiaW5kIGdvIG1ldGhvZCB3cmFwcGVyc1xud2luZG93LmdvID0ge307XG5cbmV4cG9ydCBmdW5jdGlvbiBTZXRCaW5kaW5ncyhiaW5kaW5nc01hcCkge1xuXHR0cnkge1xuXHRcdGJpbmRpbmdzTWFwID0gSlNPTi5wYXJzZShiaW5kaW5nc01hcCk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRjb25zb2xlLmVycm9yKGUpO1xuXHR9XG5cblx0Ly8gSW5pdGlhbGlzZSB0aGUgYmluZGluZ3MgbWFwXG5cdHdpbmRvdy5nbyA9IHdpbmRvdy5nbyB8fCB7fTtcblxuXHQvLyBJdGVyYXRlIHBhY2thZ2UgbmFtZXNcblx0T2JqZWN0LmtleXMoYmluZGluZ3NNYXApLmZvckVhY2goKHBhY2thZ2VOYW1lKSA9PiB7XG5cblx0XHQvLyBDcmVhdGUgaW5uZXIgbWFwIGlmIGl0IGRvZXNuJ3QgZXhpc3Rcblx0XHR3aW5kb3cuZ29bcGFja2FnZU5hbWVdID0gd2luZG93LmdvW3BhY2thZ2VOYW1lXSB8fCB7fTtcblxuXHRcdC8vIEl0ZXJhdGUgc3RydWN0IG5hbWVzXG5cdFx0T2JqZWN0LmtleXMoYmluZGluZ3NNYXBbcGFja2FnZU5hbWVdKS5mb3JFYWNoKChzdHJ1Y3ROYW1lKSA9PiB7XG5cblx0XHRcdC8vIENyZWF0ZSBpbm5lciBtYXAgaWYgaXQgZG9lc24ndCBleGlzdFxuXHRcdFx0d2luZG93LmdvW3BhY2thZ2VOYW1lXVtzdHJ1Y3ROYW1lXSA9IHdpbmRvdy5nb1twYWNrYWdlTmFtZV1bc3RydWN0TmFtZV0gfHwge307XG5cblx0XHRcdE9iamVjdC5rZXlzKGJpbmRpbmdzTWFwW3BhY2thZ2VOYW1lXVtzdHJ1Y3ROYW1lXSkuZm9yRWFjaCgobWV0aG9kTmFtZSkgPT4ge1xuXG5cdFx0XHRcdHdpbmRvdy5nb1twYWNrYWdlTmFtZV1bc3RydWN0TmFtZV1bbWV0aG9kTmFtZV0gPSBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdFx0XHQvLyBObyB0aW1lb3V0IGJ5IGRlZmF1bHRcblx0XHRcdFx0XHRsZXQgdGltZW91dCA9IDA7XG5cblx0XHRcdFx0XHQvLyBBY3R1YWwgZnVuY3Rpb25cblx0XHRcdFx0XHRmdW5jdGlvbiBkeW5hbWljKCkge1xuXHRcdFx0XHRcdFx0Y29uc3QgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblx0XHRcdFx0XHRcdHJldHVybiBDYWxsKFtwYWNrYWdlTmFtZSwgc3RydWN0TmFtZSwgbWV0aG9kTmFtZV0uam9pbignLicpLCBhcmdzLCB0aW1lb3V0KTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBBbGxvdyBzZXR0aW5nIHRpbWVvdXQgdG8gZnVuY3Rpb25cblx0XHRcdFx0XHRkeW5hbWljLnNldFRpbWVvdXQgPSBmdW5jdGlvbiAobmV3VGltZW91dCkge1xuXHRcdFx0XHRcdFx0dGltZW91dCA9IG5ld1RpbWVvdXQ7XG5cdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdC8vIEFsbG93IGdldHRpbmcgdGltZW91dCB0byBmdW5jdGlvblxuXHRcdFx0XHRcdGR5bmFtaWMuZ2V0VGltZW91dCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdHJldHVybiB0aW1lb3V0O1xuXHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRyZXR1cm4gZHluYW1pYztcblx0XHRcdFx0fSgpO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH0pO1xufVxuIiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXG5cblxuaW1wb3J0IHtDYWxsfSBmcm9tIFwiLi9jYWxsc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gV2luZG93UmVsb2FkKCkge1xuICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1JlbG9hZEFwcCgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dSJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRTeXN0ZW1EZWZhdWx0VGhlbWUoKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXQVNEVCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0TGlnaHRUaGVtZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dBTFQnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1NldERhcmtUaGVtZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dBRFQnKTtcbn1cblxuLyoqXG4gKiBQbGFjZSB0aGUgd2luZG93IGluIHRoZSBjZW50ZXIgb2YgdGhlIHNjcmVlblxuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0NlbnRlcigpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1djJyk7XG59XG5cbi8qKlxuICogU2V0cyB0aGUgd2luZG93IHRpdGxlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRpdGxlXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRUaXRsZSh0aXRsZSkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV1QnICsgdGl0bGUpO1xufVxuXG4vKipcbiAqIE1ha2VzIHRoZSB3aW5kb3cgZ28gZnVsbHNjcmVlblxuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0Z1bGxzY3JlZW4oKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXRicpO1xufVxuXG4vKipcbiAqIFJldmVydHMgdGhlIHdpbmRvdyBmcm9tIGZ1bGxzY3JlZW5cbiAqXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dVbmZ1bGxzY3JlZW4oKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXZicpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHN0YXRlIG9mIHRoZSB3aW5kb3csIGkuZS4gd2hldGhlciB0aGUgd2luZG93IGlzIGluIGZ1bGwgc2NyZWVuIG1vZGUgb3Igbm90LlxuICpcbiAqIEBleHBvcnRcbiAqIEByZXR1cm4ge1Byb21pc2U8Ym9vbGVhbj59IFRoZSBzdGF0ZSBvZiB0aGUgd2luZG93XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dJc0Z1bGxzY3JlZW4oKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93SXNGdWxsc2NyZWVuXCIpO1xufVxuXG4vKipcbiAqIFNldCB0aGUgU2l6ZSBvZiB0aGUgd2luZG93XG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRTaXplKHdpZHRoLCBoZWlnaHQpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dzOicgKyB3aWR0aCArICc6JyArIGhlaWdodCk7XG59XG5cbi8qKlxuICogR2V0IHRoZSBTaXplIG9mIHRoZSB3aW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPHt3OiBudW1iZXIsIGg6IG51bWJlcn0+fSBUaGUgc2l6ZSBvZiB0aGUgd2luZG93XG5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0dldFNpemUoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93R2V0U2l6ZVwiKTtcbn1cblxuLyoqXG4gKiBTZXQgdGhlIG1heGltdW0gc2l6ZSBvZiB0aGUgd2luZG93XG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRNYXhTaXplKHdpZHRoLCBoZWlnaHQpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1daOicgKyB3aWR0aCArICc6JyArIGhlaWdodCk7XG59XG5cbi8qKlxuICogU2V0IHRoZSBtaW5pbXVtIHNpemUgb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aFxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0TWluU2l6ZSh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXejonICsgd2lkdGggKyAnOicgKyBoZWlnaHQpO1xufVxuXG5cblxuLyoqXG4gKiBTZXQgdGhlIHdpbmRvdyBBbHdheXNPblRvcCBvciBub3Qgb24gdG9wXG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0QWx3YXlzT25Ub3AoYikge1xuXG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXQVRQOicgKyAoYiA/ICcxJyA6ICcwJykpO1xufVxuXG5cblxuXG4vKipcbiAqIFNldCB0aGUgUG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSB4XG4gKiBAcGFyYW0ge251bWJlcn0geVxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0UG9zaXRpb24oeCwgeSkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV3A6JyArIHggKyAnOicgKyB5KTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIFBvc2l0aW9uIG9mIHRoZSB3aW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPHt4OiBudW1iZXIsIHk6IG51bWJlcn0+fSBUaGUgcG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93R2V0UG9zaXRpb24oKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93R2V0UG9zXCIpO1xufVxuXG4vKipcbiAqIEhpZGUgdGhlIFdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0hpZGUoKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXSCcpO1xufVxuXG4vKipcbiAqIFNob3cgdGhlIFdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1Nob3coKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXUycpO1xufVxuXG4vKipcbiAqIE1heGltaXNlIHRoZSBXaW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dNYXhpbWlzZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dNJyk7XG59XG5cbi8qKlxuICogVG9nZ2xlIHRoZSBNYXhpbWlzZSBvZiB0aGUgV2luZG93XG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93VG9nZ2xlTWF4aW1pc2UoKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXdCcpO1xufVxuXG4vKipcbiAqIFVubWF4aW1pc2UgdGhlIFdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1VubWF4aW1pc2UoKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXVScpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHN0YXRlIG9mIHRoZSB3aW5kb3csIGkuZS4gd2hldGhlciB0aGUgd2luZG93IGlzIG1heGltaXNlZCBvciBub3QuXG4gKlxuICogQGV4cG9ydFxuICogQHJldHVybiB7UHJvbWlzZTxib29sZWFuPn0gVGhlIHN0YXRlIG9mIHRoZSB3aW5kb3dcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0lzTWF4aW1pc2VkKCkge1xuICAgIHJldHVybiBDYWxsKFwiOndhaWxzOldpbmRvd0lzTWF4aW1pc2VkXCIpO1xufVxuXG4vKipcbiAqIE1pbmltaXNlIHRoZSBXaW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dNaW5pbWlzZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dtJyk7XG59XG5cbi8qKlxuICogVW5taW5pbWlzZSB0aGUgV2luZG93XG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93VW5taW5pbWlzZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1d1Jyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3RhdGUgb2YgdGhlIHdpbmRvdywgaS5lLiB3aGV0aGVyIHRoZSB3aW5kb3cgaXMgbWluaW1pc2VkIG9yIG5vdC5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPGJvb2xlYW4+fSBUaGUgc3RhdGUgb2YgdGhlIHdpbmRvd1xuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93SXNNaW5pbWlzZWQoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93SXNNaW5pbWlzZWRcIik7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3RhdGUgb2YgdGhlIHdpbmRvdywgaS5lLiB3aGV0aGVyIHRoZSB3aW5kb3cgaXMgbm9ybWFsIG9yIG5vdC5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPGJvb2xlYW4+fSBUaGUgc3RhdGUgb2YgdGhlIHdpbmRvd1xuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93SXNOb3JtYWwoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93SXNOb3JtYWxcIik7XG59XG5cbi8qKlxuICogU2V0cyB0aGUgYmFja2dyb3VuZCBjb2xvdXIgb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSBSIFJlZFxuICogQHBhcmFtIHtudW1iZXJ9IEcgR3JlZW5cbiAqIEBwYXJhbSB7bnVtYmVyfSBCIEJsdWVcbiAqIEBwYXJhbSB7bnVtYmVyfSBBIEFscGhhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRCYWNrZ3JvdW5kQ29sb3VyKFIsIEcsIEIsIEEpIHtcbiAgICBsZXQgcmdiYSA9IEpTT04uc3RyaW5naWZ5KHtyOiBSIHx8IDAsIGc6IEcgfHwgMCwgYjogQiB8fCAwLCBhOiBBIHx8IDI1NX0pO1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV3I6JyArIHJnYmEpO1xufVxuXG4iLCAiLypcbiBfXHQgICBfX1x0ICBfIF9fXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG5cbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cblxuXG5pbXBvcnQge0NhbGx9IGZyb20gXCIuL2NhbGxzXCI7XG5cblxuLyoqXG4gKiBHZXRzIHRoZSBhbGwgc2NyZWVucy4gQ2FsbCB0aGlzIGFuZXcgZWFjaCB0aW1lIHlvdSB3YW50IHRvIHJlZnJlc2ggZGF0YSBmcm9tIHRoZSB1bmRlcmx5aW5nIHdpbmRvd2luZyBzeXN0ZW0uXG4gKiBAZXhwb3J0XG4gKiBAdHlwZWRlZiB7aW1wb3J0KCcuLi93cmFwcGVyL3J1bnRpbWUnKS5TY3JlZW59IFNjcmVlblxuICogQHJldHVybiB7UHJvbWlzZTx7U2NyZWVuW119Pn0gVGhlIHNjcmVlbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFNjcmVlbkdldEFsbCgpIHtcbiAgICByZXR1cm4gQ2FsbChcIjp3YWlsczpTY3JlZW5HZXRBbGxcIik7XG59XG4iLCAiLyoqXG4gKiBAZGVzY3JpcHRpb246IFVzZSB0aGUgc3lzdGVtIGRlZmF1bHQgYnJvd3NlciB0byBvcGVuIHRoZSB1cmxcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgXG4gKiBAcmV0dXJuIHt2b2lkfVxuICovXG5leHBvcnQgZnVuY3Rpb24gQnJvd3Nlck9wZW5VUkwodXJsKSB7XG4gIHdpbmRvdy5XYWlsc0ludm9rZSgnQk86JyArIHVybCk7XG59IiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXG5cbmltcG9ydCB7Q2FsbH0gZnJvbSBcIi4vY2FsbHNcIjtcblxuLyoqXG4gKiBTZXQgdGhlIFNpemUgb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDbGlwYm9hcmRTZXRUZXh0KHRleHQpIHtcbiAgICByZXR1cm4gQ2FsbChcIjp3YWlsczpDbGlwYm9hcmRTZXRUZXh0XCIsIFt0ZXh0XSk7XG59XG5cbi8qKlxuICogR2V0IHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhlIGNsaXBib2FyZFxuICpcbiAqIEBleHBvcnRcbiAqIEByZXR1cm4ge1Byb21pc2U8e3N0cmluZ30+fSBUZXh0IGNvbnRlbnQgb2YgdGhlIGNsaXBib2FyZFxuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDbGlwYm9hcmRHZXRUZXh0KCkge1xuICAgIHJldHVybiBDYWxsKFwiOndhaWxzOkNsaXBib2FyZEdldFRleHRcIik7XG59IiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xuaW1wb3J0ICogYXMgTG9nIGZyb20gJy4vbG9nJztcbmltcG9ydCB7ZXZlbnRMaXN0ZW5lcnMsIEV2ZW50c0VtaXQsIEV2ZW50c05vdGlmeSwgRXZlbnRzT2ZmLCBFdmVudHNPbiwgRXZlbnRzT25jZSwgRXZlbnRzT25NdWx0aXBsZX0gZnJvbSAnLi9ldmVudHMnO1xuaW1wb3J0IHtDYWxsLCBDYWxsYmFjaywgY2FsbGJhY2tzfSBmcm9tICcuL2NhbGxzJztcbmltcG9ydCB7U2V0QmluZGluZ3N9IGZyb20gXCIuL2JpbmRpbmdzXCI7XG5pbXBvcnQgKiBhcyBXaW5kb3cgZnJvbSBcIi4vd2luZG93XCI7XG5pbXBvcnQgKiBhcyBTY3JlZW4gZnJvbSBcIi4vc2NyZWVuXCI7XG5pbXBvcnQgKiBhcyBCcm93c2VyIGZyb20gXCIuL2Jyb3dzZXJcIjtcbmltcG9ydCAqIGFzIENsaXBib2FyZCBmcm9tIFwiLi9jbGlwYm9hcmRcIjtcblxuXG5leHBvcnQgZnVuY3Rpb24gUXVpdCgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1EnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFNob3coKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdTJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBIaWRlKCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnSCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gRW52aXJvbm1lbnQoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6RW52aXJvbm1lbnRcIik7XG59XG5cbi8vIFRoZSBKUyBydW50aW1lXG53aW5kb3cucnVudGltZSA9IHtcbiAgICAuLi5Mb2csXG4gICAgLi4uV2luZG93LFxuICAgIC4uLkJyb3dzZXIsXG4gICAgLi4uU2NyZWVuLFxuICAgIC4uLkNsaXBib2FyZCxcbiAgICBFdmVudHNPbixcbiAgICBFdmVudHNPbmNlLFxuICAgIEV2ZW50c09uTXVsdGlwbGUsXG4gICAgRXZlbnRzRW1pdCxcbiAgICBFdmVudHNPZmYsXG4gICAgRW52aXJvbm1lbnQsXG4gICAgU2hvdyxcbiAgICBIaWRlLFxuICAgIFF1aXRcbn07XG5cbi8vIEludGVybmFsIHdhaWxzIGVuZHBvaW50c1xud2luZG93LndhaWxzID0ge1xuICAgIENhbGxiYWNrLFxuICAgIEV2ZW50c05vdGlmeSxcbiAgICBTZXRCaW5kaW5ncyxcbiAgICBldmVudExpc3RlbmVycyxcbiAgICBjYWxsYmFja3MsXG4gICAgZmxhZ3M6IHtcbiAgICAgICAgZGlzYWJsZVNjcm9sbGJhckRyYWc6IGZhbHNlLFxuICAgICAgICBkaXNhYmxlV2FpbHNEZWZhdWx0Q29udGV4dE1lbnU6IGZhbHNlLFxuICAgICAgICBlbmFibGVSZXNpemU6IGZhbHNlLFxuICAgICAgICBkZWZhdWx0Q3Vyc29yOiBudWxsLFxuICAgICAgICBib3JkZXJUaGlja25lc3M6IDYsXG4gICAgICAgIHNob3VsZERyYWc6IGZhbHNlLFxuICAgICAgICBkZWZlckRyYWdUb01vdXNlTW92ZTogdHJ1ZSxcbiAgICAgICAgY3NzRHJhZ1Byb3BlcnR5OiBcIi0td2FpbHMtZHJhZ2dhYmxlXCIsXG4gICAgICAgIGNzc0RyYWdWYWx1ZTogXCJkcmFnXCIsXG4gICAgfVxufTtcblxuLy8gU2V0IHRoZSBiaW5kaW5nc1xuaWYgKHdpbmRvdy53YWlsc2JpbmRpbmdzKSB7XG4gICAgd2luZG93LndhaWxzLlNldEJpbmRpbmdzKHdpbmRvdy53YWlsc2JpbmRpbmdzKTtcbiAgICBkZWxldGUgd2luZG93LndhaWxzLlNldEJpbmRpbmdzO1xufVxuXG4vLyAoYm9vbCkgVGhpcyBpcyBldmFsdWF0ZWQgYXQgYnVpbGQgdGltZSBpbiBwYWNrYWdlLmpzb25cbmlmICghREVCVUcpIHtcbiAgICBkZWxldGUgd2luZG93LndhaWxzYmluZGluZ3M7XG59XG5cbmxldCBkcmFnVGVzdCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIHZhbCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGUudGFyZ2V0KS5nZXRQcm9wZXJ0eVZhbHVlKHdpbmRvdy53YWlscy5mbGFncy5jc3NEcmFnUHJvcGVydHkpO1xuICAgIGlmICh2YWwpIHtcbiAgICAgIHZhbCA9IHZhbC50cmltKCk7XG4gICAgfVxuICAgIFxuICAgIGlmICh2YWwgIT09IHdpbmRvdy53YWlscy5mbGFncy5jc3NEcmFnVmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChlLmJ1dHRvbnMgIT09IDEpIHtcbiAgICAgICAgLy8gRG8gbm90IHN0YXJ0IGRyYWdnaW5nIGlmIG5vdCB0aGUgcHJpbWFyeSBidXR0b24gaGFzIGJlZW4gY2xpY2tlZC5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChlLmRldGFpbCAhPT0gMSkge1xuICAgICAgICAvLyBEbyBub3Qgc3RhcnQgZHJhZ2dpbmcgaWYgbW9yZSB0aGFuIG9uY2UgaGFzIGJlZW4gY2xpY2tlZCwgZS5nLiB3aGVuIGRvdWJsZSBjbGlja2luZ1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG59O1xuXG53aW5kb3cud2FpbHMuc2V0Q1NTRHJhZ1Byb3BlcnRpZXMgPSBmdW5jdGlvbiAocHJvcGVydHksIHZhbHVlKSB7XG4gICAgd2luZG93LndhaWxzLmZsYWdzLmNzc0RyYWdQcm9wZXJ0eSA9IHByb3BlcnR5O1xuICAgIHdpbmRvdy53YWlscy5mbGFncy5jc3NEcmFnVmFsdWUgPSB2YWx1ZTtcbn1cblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIChlKSA9PiB7XG5cbiAgICAvLyBDaGVjayBmb3IgcmVzaXppbmdcbiAgICBpZiAod2luZG93LndhaWxzLmZsYWdzLnJlc2l6ZUVkZ2UpIHtcbiAgICAgICAgd2luZG93LldhaWxzSW52b2tlKFwicmVzaXplOlwiICsgd2luZG93LndhaWxzLmZsYWdzLnJlc2l6ZUVkZ2UpO1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZHJhZ1Rlc3QoZSkpIHtcbiAgICAgICAgaWYgKHdpbmRvdy53YWlscy5mbGFncy5kaXNhYmxlU2Nyb2xsYmFyRHJhZykge1xuICAgICAgICAgICAgLy8gVGhpcyBjaGVja3MgZm9yIGNsaWNrcyBvbiB0aGUgc2Nyb2xsIGJhclxuICAgICAgICAgICAgaWYgKGUub2Zmc2V0WCA+IGUudGFyZ2V0LmNsaWVudFdpZHRoIHx8IGUub2Zmc2V0WSA+IGUudGFyZ2V0LmNsaWVudEhlaWdodCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAod2luZG93LndhaWxzLmZsYWdzLmRlZmVyRHJhZ1RvTW91c2VNb3ZlKSB7XG4gICAgICAgICAgICB3aW5kb3cud2FpbHMuZmxhZ3Muc2hvdWxkRHJhZyA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgIHdpbmRvdy5XYWlsc0ludm9rZShcImRyYWdcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHdpbmRvdy53YWlscy5mbGFncy5zaG91bGREcmFnID0gZmFsc2U7XG4gICAgfVxufSk7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgKCkgPT4ge1xuICAgIHdpbmRvdy53YWlscy5mbGFncy5zaG91bGREcmFnID0gZmFsc2U7XG59KTtcblxuZnVuY3Rpb24gc2V0UmVzaXplKGN1cnNvcikge1xuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5jdXJzb3IgPSBjdXJzb3IgfHwgd2luZG93LndhaWxzLmZsYWdzLmRlZmF1bHRDdXJzb3I7XG4gICAgd2luZG93LndhaWxzLmZsYWdzLnJlc2l6ZUVkZ2UgPSBjdXJzb3I7XG59XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBmdW5jdGlvbiAoZSkge1xuICAgIGlmICh3aW5kb3cud2FpbHMuZmxhZ3Muc2hvdWxkRHJhZykge1xuICAgICAgICB3aW5kb3cud2FpbHMuZmxhZ3Muc2hvdWxkRHJhZyA9IGZhbHNlO1xuICAgICAgICBsZXQgbW91c2VQcmVzc2VkID0gZS5idXR0b25zICE9PSB1bmRlZmluZWQgPyBlLmJ1dHRvbnMgOiBlLndoaWNoO1xuICAgICAgICBpZiAobW91c2VQcmVzc2VkID4gMCkge1xuICAgICAgICAgICAgd2luZG93LldhaWxzSW52b2tlKFwiZHJhZ1wiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoIXdpbmRvdy53YWlscy5mbGFncy5lbmFibGVSZXNpemUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAod2luZG93LndhaWxzLmZsYWdzLmRlZmF1bHRDdXJzb3IgPT0gbnVsbCkge1xuICAgICAgICB3aW5kb3cud2FpbHMuZmxhZ3MuZGVmYXVsdEN1cnNvciA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5jdXJzb3I7XG4gICAgfVxuICAgIGlmICh3aW5kb3cub3V0ZXJXaWR0aCAtIGUuY2xpZW50WCA8IHdpbmRvdy53YWlscy5mbGFncy5ib3JkZXJUaGlja25lc3MgJiYgd2luZG93Lm91dGVySGVpZ2h0IC0gZS5jbGllbnRZIDwgd2luZG93LndhaWxzLmZsYWdzLmJvcmRlclRoaWNrbmVzcykge1xuICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gXCJzZS1yZXNpemVcIjtcbiAgICB9XG4gICAgbGV0IHJpZ2h0Qm9yZGVyID0gd2luZG93Lm91dGVyV2lkdGggLSBlLmNsaWVudFggPCB3aW5kb3cud2FpbHMuZmxhZ3MuYm9yZGVyVGhpY2tuZXNzO1xuICAgIGxldCBsZWZ0Qm9yZGVyID0gZS5jbGllbnRYIDwgd2luZG93LndhaWxzLmZsYWdzLmJvcmRlclRoaWNrbmVzcztcbiAgICBsZXQgdG9wQm9yZGVyID0gZS5jbGllbnRZIDwgd2luZG93LndhaWxzLmZsYWdzLmJvcmRlclRoaWNrbmVzcztcbiAgICBsZXQgYm90dG9tQm9yZGVyID0gd2luZG93Lm91dGVySGVpZ2h0IC0gZS5jbGllbnRZIDwgd2luZG93LndhaWxzLmZsYWdzLmJvcmRlclRoaWNrbmVzcztcblxuICAgIC8vIElmIHdlIGFyZW4ndCBvbiBhbiBlZGdlLCBidXQgd2VyZSwgcmVzZXQgdGhlIGN1cnNvciB0byBkZWZhdWx0XG4gICAgaWYgKCFsZWZ0Qm9yZGVyICYmICFyaWdodEJvcmRlciAmJiAhdG9wQm9yZGVyICYmICFib3R0b21Cb3JkZXIgJiYgd2luZG93LndhaWxzLmZsYWdzLnJlc2l6ZUVkZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzZXRSZXNpemUoKTtcbiAgICB9IGVsc2UgaWYgKHJpZ2h0Qm9yZGVyICYmIGJvdHRvbUJvcmRlcikgc2V0UmVzaXplKFwic2UtcmVzaXplXCIpO1xuICAgIGVsc2UgaWYgKGxlZnRCb3JkZXIgJiYgYm90dG9tQm9yZGVyKSBzZXRSZXNpemUoXCJzdy1yZXNpemVcIik7XG4gICAgZWxzZSBpZiAobGVmdEJvcmRlciAmJiB0b3BCb3JkZXIpIHNldFJlc2l6ZShcIm53LXJlc2l6ZVwiKTtcbiAgICBlbHNlIGlmICh0b3BCb3JkZXIgJiYgcmlnaHRCb3JkZXIpIHNldFJlc2l6ZShcIm5lLXJlc2l6ZVwiKTtcbiAgICBlbHNlIGlmIChsZWZ0Qm9yZGVyKSBzZXRSZXNpemUoXCJ3LXJlc2l6ZVwiKTtcbiAgICBlbHNlIGlmICh0b3BCb3JkZXIpIHNldFJlc2l6ZShcIm4tcmVzaXplXCIpO1xuICAgIGVsc2UgaWYgKGJvdHRvbUJvcmRlcikgc2V0UmVzaXplKFwicy1yZXNpemVcIik7XG4gICAgZWxzZSBpZiAocmlnaHRCb3JkZXIpIHNldFJlc2l6ZShcImUtcmVzaXplXCIpO1xuXG59KTtcblxuLy8gU2V0dXAgY29udGV4dCBtZW51IGhvb2tcbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdjb250ZXh0bWVudScsIGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKHdpbmRvdy53YWlscy5mbGFncy5kaXNhYmxlV2FpbHNEZWZhdWx0Q29udGV4dE1lbnUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbn0pO1xuXG53aW5kb3cuV2FpbHNJbnZva2UoXCJydW50aW1lOnJlYWR5XCIpOyJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBa0JBLFdBQVMsZUFBZSxPQUFPLFNBQVM7QUFJdkMsV0FBTyxZQUFZ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 diff --git a/v2/internal/frontend/runtime/runtime_dev_desktop.go b/v2/internal/frontend/runtime/runtime_dev_desktop.go deleted file mode 100644 index c0dcb1fc..00000000 --- a/v2/internal/frontend/runtime/runtime_dev_desktop.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build dev || bindings || (!dev && !production && !bindings) - -package runtime - -import _ "embed" - -//go:embed runtime_dev_desktop.js -var RuntimeDesktopJS []byte diff --git a/v2/internal/frontend/runtime/runtime_prod_desktop.go b/v2/internal/frontend/runtime/runtime_prod_desktop.go index 4fd8aaa5..7336f010 100644 --- a/v2/internal/frontend/runtime/runtime_prod_desktop.go +++ b/v2/internal/frontend/runtime/runtime_prod_desktop.go @@ -1,4 +1,4 @@ -//go:build production +//go:build production && !debug package runtime diff --git a/v2/internal/frontend/runtime/runtime_prod_desktop.js b/v2/internal/frontend/runtime/runtime_prod_desktop.js index 23b66953..a22739c9 100644 --- a/v2/internal/frontend/runtime/runtime_prod_desktop.js +++ b/v2/internal/frontend/runtime/runtime_prod_desktop.js @@ -1 +1 @@ -(()=>{var L=Object.defineProperty;var c=(e,n)=>{for(var o in n)L(e,o,{get:n[o],enumerable:!0})};var m={};c(m,{LogDebug:()=>M,LogError:()=>A,LogFatal:()=>H,LogInfo:()=>P,LogLevel:()=>J,LogPrint:()=>R,LogTrace:()=>z,LogWarning:()=>B,SetLogLevel:()=>G});function d(e,n){window.WailsInvoke("L"+e+n)}function z(e){d("T",e)}function R(e){d("P",e)}function M(e){d("D",e)}function P(e){d("I",e)}function B(e){d("W",e)}function A(e){d("E",e)}function H(e){d("F",e)}function G(e){d("S",e)}var J={TRACE:1,DEBUG:2,INFO:3,WARNING:4,ERROR:5};var v=class{constructor(n,o,i){this.eventName=n,this.maxCallbacks=i||-1,this.Callback=t=>(o.apply(null,t),this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0))}},l={};function p(e,n,o){l[e]=l[e]||[];let i=new v(e,n,o);return l[e].push(i),()=>F(i)}function b(e,n){return p(e,n,-1)}function E(e,n){return p(e,n,1)}function S(e){let n=e.name;if(l[n]){let o=l[n].slice();for(let i=l[n].length-1;i>=0;i-=1){let t=l[n][i],r=e.data;t.Callback(r)&&o.splice(i,1)}o.length===0?g(n):l[n]=o}}function y(e){let n;try{n=JSON.parse(e)}catch{let i="Invalid JSON passed to Notify: "+e;throw new Error(i)}S(n)}function C(e){let n={name:e,data:[].slice.apply(arguments).slice(1)};S(n),window.WailsInvoke("EE"+JSON.stringify(n))}function g(e){delete l[e],window.WailsInvoke("EX"+e)}function D(e,...n){g(e),n.length>0&&n.forEach(o=>{g(o)})}function F(e){let n=e.eventName;l[n]=l[n].filter(o=>o!==e),l[n].length===0&&g(n)}var f={};function U(){var e=new Uint32Array(1);return window.crypto.getRandomValues(e)[0]}function j(){return Math.random()*9007199254740991}var W;window.crypto?W=U:W=j;function s(e,n,o){return o==null&&(o=0),new Promise(function(i,t){var r;do r=e+"-"+W();while(f[r]);var a;o>0&&(a=setTimeout(function(){t(Error("Call to "+e+" timed out. Request ID: "+r))},o)),f[r]={timeoutHandle:a,reject:t,resolve:i};try{let u={name:e,args:n,callbackID:r};window.WailsInvoke("C"+JSON.stringify(u))}catch(u){console.error(u)}})}window.ObfuscatedCall=(e,n,o)=>(o==null&&(o=0),new Promise(function(i,t){var r;do r=e+"-"+W();while(f[r]);var a;o>0&&(a=setTimeout(function(){t(Error("Call to method "+e+" timed out. Request ID: "+r))},o)),f[r]={timeoutHandle:a,reject:t,resolve:i};try{let u={id:e,args:n,callbackID:r};window.WailsInvoke("c"+JSON.stringify(u))}catch(u){console.error(u)}}));function T(e){let n;try{n=JSON.parse(e)}catch(t){let r=`Invalid JSON passed to callback: ${t.message}. Message: ${e}`;throw runtime.LogDebug(r),new Error(r)}let o=n.callbackid,i=f[o];if(!i){let t=`Callback '${o}' not registered!!!`;throw console.error(t),new Error(t)}clearTimeout(i.timeoutHandle),delete f[o],n.error?i.reject(n.error):i.resolve(n.result)}window.go={};function O(e){try{e=JSON.parse(e)}catch(n){console.error(n)}window.go=window.go||{},Object.keys(e).forEach(n=>{window.go[n]=window.go[n]||{},Object.keys(e[n]).forEach(o=>{window.go[n][o]=window.go[n][o]||{},Object.keys(e[n][o]).forEach(i=>{window.go[n][o][i]=function(){let t=0;function r(){let a=[].slice.call(arguments);return s([n,o,i].join("."),a,t)}return r.setTimeout=function(a){t=a},r.getTimeout=function(){return t},r}()})})})}var x={};c(x,{WindowCenter:()=>q,WindowFullscreen:()=>Z,WindowGetPosition:()=>se,WindowGetSize:()=>ne,WindowHide:()=>le,WindowIsFullscreen:()=>_,WindowIsMaximised:()=>ue,WindowIsMinimised:()=>pe,WindowIsNormal:()=>We,WindowMaximise:()=>we,WindowMinimise:()=>ce,WindowReload:()=>N,WindowReloadApp:()=>V,WindowSetAlwaysOnTop:()=>te,WindowSetBackgroundColour:()=>me,WindowSetDarkTheme:()=>$,WindowSetLightTheme:()=>Y,WindowSetMaxSize:()=>oe,WindowSetMinSize:()=>ie,WindowSetPosition:()=>re,WindowSetSize:()=>ee,WindowSetSystemDefaultTheme:()=>X,WindowSetTitle:()=>Q,WindowShow:()=>ae,WindowToggleMaximise:()=>de,WindowUnfullscreen:()=>K,WindowUnmaximise:()=>fe,WindowUnminimise:()=>ge});function N(){window.location.reload()}function V(){window.WailsInvoke("WR")}function X(){window.WailsInvoke("WASDT")}function Y(){window.WailsInvoke("WALT")}function $(){window.WailsInvoke("WADT")}function q(){window.WailsInvoke("Wc")}function Q(e){window.WailsInvoke("WT"+e)}function Z(){window.WailsInvoke("WF")}function K(){window.WailsInvoke("Wf")}function _(){return s(":wails:WindowIsFullscreen")}function ee(e,n){window.WailsInvoke("Ws:"+e+":"+n)}function ne(){return s(":wails:WindowGetSize")}function oe(e,n){window.WailsInvoke("WZ:"+e+":"+n)}function ie(e,n){window.WailsInvoke("Wz:"+e+":"+n)}function te(e){window.WailsInvoke("WATP:"+(e?"1":"0"))}function re(e,n){window.WailsInvoke("Wp:"+e+":"+n)}function se(){return s(":wails:WindowGetPos")}function le(){window.WailsInvoke("WH")}function ae(){window.WailsInvoke("WS")}function we(){window.WailsInvoke("WM")}function de(){window.WailsInvoke("Wt")}function fe(){window.WailsInvoke("WU")}function ue(){return s(":wails:WindowIsMaximised")}function ce(){window.WailsInvoke("Wm")}function ge(){window.WailsInvoke("Wu")}function pe(){return s(":wails:WindowIsMinimised")}function We(){return s(":wails:WindowIsNormal")}function me(e,n,o,i){let t=JSON.stringify({r:e||0,g:n||0,b:o||0,a:i||255});window.WailsInvoke("Wr:"+t)}var k={};c(k,{ScreenGetAll:()=>ve});function ve(){return s(":wails:ScreenGetAll")}var h={};c(h,{BrowserOpenURL:()=>xe});function xe(e){window.WailsInvoke("BO:"+e)}var I={};c(I,{ClipboardGetText:()=>he,ClipboardSetText:()=>ke});function ke(e){return s(":wails:ClipboardSetText",[e])}function he(){return s(":wails:ClipboardGetText")}function Ie(){window.WailsInvoke("Q")}function be(){window.WailsInvoke("S")}function Ee(){window.WailsInvoke("H")}function Se(){return s(":wails:Environment")}window.runtime={...m,...x,...h,...k,...I,EventsOn:b,EventsOnce:E,EventsOnMultiple:p,EventsEmit:C,EventsOff:D,Environment:Se,Show:be,Hide:Ee,Quit:Ie};window.wails={Callback:T,EventsNotify:y,SetBindings:O,eventListeners:l,callbacks:f,flags:{disableScrollbarDrag:!1,disableWailsDefaultContextMenu:!1,enableResize:!1,defaultCursor:null,borderThickness:6,shouldDrag:!1,deferDragToMouseMove:!0,cssDragProperty:"--wails-draggable",cssDragValue:"drag"}};window.wailsbindings&&(window.wails.SetBindings(window.wailsbindings),delete window.wails.SetBindings);delete window.wailsbindings;var ye=function(e){var n=window.getComputedStyle(e.target).getPropertyValue(window.wails.flags.cssDragProperty);return n&&(n=n.trim()),!(n!==window.wails.flags.cssDragValue||e.buttons!==1||e.detail!==1)};window.wails.setCSSDragProperties=function(e,n){window.wails.flags.cssDragProperty=e,window.wails.flags.cssDragValue=n};window.addEventListener("mousedown",e=>{if(window.wails.flags.resizeEdge){window.WailsInvoke("resize:"+window.wails.flags.resizeEdge),e.preventDefault();return}if(ye(e)){if(window.wails.flags.disableScrollbarDrag&&(e.offsetX>e.target.clientWidth||e.offsetY>e.target.clientHeight))return;window.wails.flags.deferDragToMouseMove?window.wails.flags.shouldDrag=!0:(e.preventDefault(),window.WailsInvoke("drag"));return}else window.wails.flags.shouldDrag=!1});window.addEventListener("mouseup",()=>{window.wails.flags.shouldDrag=!1});function w(e){document.documentElement.style.cursor=e||window.wails.flags.defaultCursor,window.wails.flags.resizeEdge=e}window.addEventListener("mousemove",function(e){if(window.wails.flags.shouldDrag&&(window.wails.flags.shouldDrag=!1,(e.buttons!==void 0?e.buttons:e.which)>0)){window.WailsInvoke("drag");return}if(!window.wails.flags.enableResize)return;window.wails.flags.defaultCursor==null&&(window.wails.flags.defaultCursor=document.documentElement.style.cursor),window.outerWidth-e.clientX{var L=Object.defineProperty;var c=(e,n)=>{for(var o in n)L(e,o,{get:n[o],enumerable:!0})};var m={};c(m,{LogDebug:()=>M,LogError:()=>A,LogFatal:()=>H,LogInfo:()=>P,LogLevel:()=>J,LogPrint:()=>R,LogTrace:()=>z,LogWarning:()=>B,SetLogLevel:()=>G});function d(e,n){window.WailsInvoke("L"+e+n)}function z(e){d("T",e)}function R(e){d("P",e)}function M(e){d("D",e)}function P(e){d("I",e)}function B(e){d("W",e)}function A(e){d("E",e)}function H(e){d("F",e)}function G(e){d("S",e)}var J={TRACE:1,DEBUG:2,INFO:3,WARNING:4,ERROR:5};var v=class{constructor(n,o,i){this.eventName=n,this.maxCallbacks=i||-1,this.Callback=t=>(o.apply(null,t),this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0))}},l={};function p(e,n,o){l[e]=l[e]||[];let i=new v(e,n,o);return l[e].push(i),()=>F(i)}function b(e,n){return p(e,n,-1)}function E(e,n){return p(e,n,1)}function S(e){let n=e.name;if(l[n]){let o=l[n].slice();for(let i=l[n].length-1;i>=0;i-=1){let t=l[n][i],r=e.data;t.Callback(r)&&o.splice(i,1)}o.length===0?g(n):l[n]=o}}function y(e){let n;try{n=JSON.parse(e)}catch{let i="Invalid JSON passed to Notify: "+e;throw new Error(i)}S(n)}function D(e){let n={name:e,data:[].slice.apply(arguments).slice(1)};S(n),window.WailsInvoke("EE"+JSON.stringify(n))}function g(e){delete l[e],window.WailsInvoke("EX"+e)}function C(e,...n){g(e),n.length>0&&n.forEach(o=>{g(o)})}function F(e){let n=e.eventName;l[n]=l[n].filter(o=>o!==e),l[n].length===0&&g(n)}var f={};function U(){var e=new Uint32Array(1);return window.crypto.getRandomValues(e)[0]}function j(){return Math.random()*9007199254740991}var W;window.crypto?W=U:W=j;function s(e,n,o){return o==null&&(o=0),new Promise(function(i,t){var r;do r=e+"-"+W();while(f[r]);var a;o>0&&(a=setTimeout(function(){t(Error("Call to "+e+" timed out. Request ID: "+r))},o)),f[r]={timeoutHandle:a,reject:t,resolve:i};try{let u={name:e,args:n,callbackID:r};window.WailsInvoke("C"+JSON.stringify(u))}catch(u){console.error(u)}})}window.ObfuscatedCall=(e,n,o)=>(o==null&&(o=0),new Promise(function(i,t){var r;do r=e+"-"+W();while(f[r]);var a;o>0&&(a=setTimeout(function(){t(Error("Call to method "+e+" timed out. Request ID: "+r))},o)),f[r]={timeoutHandle:a,reject:t,resolve:i};try{let u={id:e,args:n,callbackID:r};window.WailsInvoke("c"+JSON.stringify(u))}catch(u){console.error(u)}}));function T(e){let n;try{n=JSON.parse(e)}catch(t){let r=`Invalid JSON passed to callback: ${t.message}. Message: ${e}`;throw runtime.LogDebug(r),new Error(r)}let o=n.callbackid,i=f[o];if(!i){let t=`Callback '${o}' not registered!!!`;throw console.error(t),new Error(t)}clearTimeout(i.timeoutHandle),delete f[o],n.error?i.reject(n.error):i.resolve(n.result)}window.go={};function O(e){try{e=JSON.parse(e)}catch(n){console.error(n)}window.go=window.go||{},Object.keys(e).forEach(n=>{window.go[n]=window.go[n]||{},Object.keys(e[n]).forEach(o=>{window.go[n][o]=window.go[n][o]||{},Object.keys(e[n][o]).forEach(i=>{window.go[n][o][i]=function(){let t=0;function r(){let a=[].slice.call(arguments);return s([n,o,i].join("."),a,t)}return r.setTimeout=function(a){t=a},r.getTimeout=function(){return t},r}()})})})}var x={};c(x,{WindowCenter:()=>q,WindowFullscreen:()=>Z,WindowGetPosition:()=>se,WindowGetSize:()=>ne,WindowHide:()=>le,WindowIsFullscreen:()=>_,WindowIsMaximised:()=>ue,WindowIsMinimised:()=>pe,WindowIsNormal:()=>We,WindowMaximise:()=>we,WindowMinimise:()=>ce,WindowReload:()=>N,WindowReloadApp:()=>V,WindowSetAlwaysOnTop:()=>te,WindowSetBackgroundColour:()=>me,WindowSetDarkTheme:()=>$,WindowSetLightTheme:()=>Y,WindowSetMaxSize:()=>oe,WindowSetMinSize:()=>ie,WindowSetPosition:()=>re,WindowSetSize:()=>ee,WindowSetSystemDefaultTheme:()=>X,WindowSetTitle:()=>Q,WindowShow:()=>ae,WindowToggleMaximise:()=>de,WindowUnfullscreen:()=>K,WindowUnmaximise:()=>fe,WindowUnminimise:()=>ge});function N(){window.location.reload()}function V(){window.WailsInvoke("WR")}function X(){window.WailsInvoke("WASDT")}function Y(){window.WailsInvoke("WALT")}function $(){window.WailsInvoke("WADT")}function q(){window.WailsInvoke("Wc")}function Q(e){window.WailsInvoke("WT"+e)}function Z(){window.WailsInvoke("WF")}function K(){window.WailsInvoke("Wf")}function _(){return s(":wails:WindowIsFullscreen")}function ee(e,n){window.WailsInvoke("Ws:"+e+":"+n)}function ne(){return s(":wails:WindowGetSize")}function oe(e,n){window.WailsInvoke("WZ:"+e+":"+n)}function ie(e,n){window.WailsInvoke("Wz:"+e+":"+n)}function te(e){window.WailsInvoke("WATP:"+(e?"1":"0"))}function re(e,n){window.WailsInvoke("Wp:"+e+":"+n)}function se(){return s(":wails:WindowGetPos")}function le(){window.WailsInvoke("WH")}function ae(){window.WailsInvoke("WS")}function we(){window.WailsInvoke("WM")}function de(){window.WailsInvoke("Wt")}function fe(){window.WailsInvoke("WU")}function ue(){return s(":wails:WindowIsMaximised")}function ce(){window.WailsInvoke("Wm")}function ge(){window.WailsInvoke("Wu")}function pe(){return s(":wails:WindowIsMinimised")}function We(){return s(":wails:WindowIsNormal")}function me(e,n,o,i){let t=JSON.stringify({r:e||0,g:n||0,b:o||0,a:i||255});window.WailsInvoke("Wr:"+t)}var k={};c(k,{ScreenGetAll:()=>ve});function ve(){return s(":wails:ScreenGetAll")}var h={};c(h,{BrowserOpenURL:()=>xe});function xe(e){window.WailsInvoke("BO:"+e)}var I={};c(I,{ClipboardGetText:()=>he,ClipboardSetText:()=>ke});function ke(e){return s(":wails:ClipboardSetText",[e])}function he(){return s(":wails:ClipboardGetText")}function Ie(){window.WailsInvoke("Q")}function be(){window.WailsInvoke("S")}function Ee(){window.WailsInvoke("H")}function Se(){return s(":wails:Environment")}window.runtime={...m,...x,...h,...k,...I,EventsOn:b,EventsOnce:E,EventsOnMultiple:p,EventsEmit:D,EventsOff:C,Environment:Se,Show:be,Hide:Ee,Quit:Ie};window.wails={Callback:T,EventsNotify:y,SetBindings:O,eventListeners:l,callbacks:f,flags:{disableScrollbarDrag:!1,disableWailsDefaultContextMenu:!1,enableResize:!1,defaultCursor:null,borderThickness:6,shouldDrag:!1,deferDragToMouseMove:!0,cssDragProperty:"--wails-draggable",cssDragValue:"drag"}};window.wailsbindings&&(window.wails.SetBindings(window.wailsbindings),delete window.wails.SetBindings);delete window.wailsbindings;var ye=function(e){var n=window.getComputedStyle(e.target).getPropertyValue(window.wails.flags.cssDragProperty);return n&&(n=n.trim()),!(n!==window.wails.flags.cssDragValue||e.buttons!==1||e.detail!==1)};window.wails.setCSSDragProperties=function(e,n){window.wails.flags.cssDragProperty=e,window.wails.flags.cssDragValue=n};window.addEventListener("mousedown",e=>{if(window.wails.flags.resizeEdge){window.WailsInvoke("resize:"+window.wails.flags.resizeEdge),e.preventDefault();return}if(ye(e)){if(window.wails.flags.disableScrollbarDrag&&(e.offsetX>e.target.clientWidth||e.offsetY>e.target.clientHeight))return;window.wails.flags.deferDragToMouseMove?window.wails.flags.shouldDrag=!0:(e.preventDefault(),window.WailsInvoke("drag"));return}else window.wails.flags.shouldDrag=!1});window.addEventListener("mouseup",()=>{window.wails.flags.shouldDrag=!1});function w(e){document.documentElement.style.cursor=e||window.wails.flags.defaultCursor,window.wails.flags.resizeEdge=e}window.addEventListener("mousemove",function(e){if(window.wails.flags.shouldDrag&&(window.wails.flags.shouldDrag=!1,(e.buttons!==void 0?e.buttons:e.which)>0)){window.WailsInvoke("drag");return}if(!window.wails.flags.enableResize)return;window.wails.flags.defaultCursor==null&&(window.wails.flags.defaultCursor=document.documentElement.style.cursor),window.outerWidth-e.clientX Date: Wed, 28 Jun 2023 06:25:00 +1000 Subject: [PATCH 17/36] Bump semver from 7.3.8 to 7.5.3 in /scripts/sponsors (#2747) Bumps [semver](https://github.com/npm/node-semver) from 7.3.8 to 7.5.3. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/main/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v7.3.8...v7.5.3) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- scripts/sponsors/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/sponsors/package-lock.json b/scripts/sponsors/package-lock.json index cb6cc8b9..5153e9cf 100644 --- a/scripts/sponsors/package-lock.json +++ b/scripts/sponsors/package-lock.json @@ -1446,9 +1446,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", + "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", "dependencies": { "lru-cache": "^6.0.0" }, From 8acbdc246cd0a339b89dfce21971bbbd5c41d83e Mon Sep 17 00:00:00 2001 From: Mohamed Gharib Date: Tue, 27 Jun 2023 23:35:02 +0300 Subject: [PATCH 18/36] [v2] Add smart default context-menu functionality (backported from v3) (#2748) * [v2] Add smart default context-menu functionality (backported from v3) * Update changelog --- .../frontend/desktop/darwin/WailsContext.m | 2 +- .../frontend/runtime/desktop/contextmenu.js | 50 +++++++++++++++++++ v2/internal/frontend/runtime/desktop/main.js | 10 +++- .../frontend/runtime/runtime_debug_desktop.js | 48 ++++++++++++++++-- .../frontend/runtime/runtime_prod_desktop.js | 2 +- website/docs/reference/options.mdx | 24 ++++++++- website/src/pages/changelog.mdx | 1 + 7 files changed, 128 insertions(+), 9 deletions(-) create mode 100644 v2/internal/frontend/runtime/desktop/contextmenu.js diff --git a/v2/internal/frontend/desktop/darwin/WailsContext.m b/v2/internal/frontend/desktop/darwin/WailsContext.m index 15c9edff..cc5aa234 100644 --- a/v2/internal/frontend/desktop/darwin/WailsContext.m +++ b/v2/internal/frontend/desktop/darwin/WailsContext.m @@ -230,7 +230,7 @@ typedef void (^schemeTaskCaller)(id); } else if (!self.defaultContextMenu) { // Disable default context menus WKUserScript *initScript = [WKUserScript new]; - [initScript initWithSource:@"window.wails.flags.disableWailsDefaultContextMenu = true;" + [initScript initWithSource:@"window.wails.flags.disableDefaultContextMenu = true;" injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:false]; [userContentController addUserScript:initScript]; diff --git a/v2/internal/frontend/runtime/desktop/contextmenu.js b/v2/internal/frontend/runtime/desktop/contextmenu.js new file mode 100644 index 00000000..b9c39754 --- /dev/null +++ b/v2/internal/frontend/runtime/desktop/contextmenu.js @@ -0,0 +1,50 @@ +/* +--default-contextmenu: auto; (default) will show the default context menu if contentEditable is true OR text has been selected OR element is input or textarea +--default-contextmenu: show; will always show the default context menu +--default-contextmenu: hide; will always hide the default context menu + +This rule is inherited like normal CSS rules, so nesting works as expected +*/ +export function processDefaultContextMenu(event) { + // Process default context menu + const element = event.target; + const computedStyle = window.getComputedStyle(element); + const defaultContextMenuAction = computedStyle.getPropertyValue("--default-contextmenu").trim(); + switch (defaultContextMenuAction) { + case "show": + return; + case "hide": + event.preventDefault(); + return; + default: + // Check if contentEditable is true + if (element.isContentEditable) { + return; + } + + // Check if text has been selected and action is on the selected elements + const selection = window.getSelection(); + const hasSelection = (selection.toString().length > 0) + if (hasSelection) { + for (let i = 0; i < selection.rangeCount; i++) { + const range = selection.getRangeAt(i); + const rects = range.getClientRects(); + for (let j = 0; j < rects.length; j++) { + const rect = rects[j]; + if (document.elementFromPoint(rect.left, rect.top) === element) { + return; + } + } + } + } + // Check if tagname is input or textarea + if (element.tagName === "INPUT" || element.tagName === "TEXTAREA") { + if (hasSelection || (!element.readOnly && !element.disabled)) { + return; + } + } + + // hide default context menu + event.preventDefault(); + } +} diff --git a/v2/internal/frontend/runtime/desktop/main.js b/v2/internal/frontend/runtime/desktop/main.js index 38c56069..65d954d9 100644 --- a/v2/internal/frontend/runtime/desktop/main.js +++ b/v2/internal/frontend/runtime/desktop/main.js @@ -16,6 +16,7 @@ import * as Window from "./window"; import * as Screen from "./screen"; import * as Browser from "./browser"; import * as Clipboard from "./clipboard"; +import * as ContextMenu from "./contextmenu"; export function Quit() { @@ -61,7 +62,7 @@ window.wails = { callbacks, flags: { disableScrollbarDrag: false, - disableWailsDefaultContextMenu: false, + disableDefaultContextMenu: false, enableResize: false, defaultCursor: null, borderThickness: 6, @@ -187,8 +188,13 @@ window.addEventListener('mousemove', function (e) { // Setup context menu hook window.addEventListener('contextmenu', function (e) { - if (window.wails.flags.disableWailsDefaultContextMenu) { + // always show the contextmenu in debug & dev + if (DEBUG) return; + + if (window.wails.flags.disableDefaultContextMenu) { e.preventDefault(); + } else { + ContextMenu.processDefaultContextMenu(e); } }); diff --git a/v2/internal/frontend/runtime/runtime_debug_desktop.js b/v2/internal/frontend/runtime/runtime_debug_desktop.js index 825ea589..e680df85 100644 --- a/v2/internal/frontend/runtime/runtime_debug_desktop.js +++ b/v2/internal/frontend/runtime/runtime_debug_desktop.js @@ -424,6 +424,44 @@ return Call(":wails:ClipboardGetText"); } + // desktop/contextmenu.js + function processDefaultContextMenu(event) { + const element = event.target; + const computedStyle = window.getComputedStyle(element); + const defaultContextMenuAction = computedStyle.getPropertyValue("--default-contextmenu").trim(); + switch (defaultContextMenuAction) { + case "show": + return; + case "hide": + event.preventDefault(); + return; + default: + if (element.isContentEditable) { + return; + } + const selection = window.getSelection(); + const hasSelection = selection.toString().length > 0; + if (hasSelection) { + for (let i = 0; i < selection.rangeCount; i++) { + const range = selection.getRangeAt(i); + const rects = range.getClientRects(); + for (let j = 0; j < rects.length; j++) { + const rect = rects[j]; + if (document.elementFromPoint(rect.left, rect.top) === element) { + return; + } + } + } + } + if (element.tagName === "INPUT" || element.tagName === "TEXTAREA") { + if (hasSelection || !element.readOnly && !element.disabled) { + return; + } + } + event.preventDefault(); + } + } + // desktop/main.js function Quit() { window.WailsInvoke("Q"); @@ -461,7 +499,7 @@ callbacks, flags: { disableScrollbarDrag: false, - disableWailsDefaultContextMenu: false, + disableDefaultContextMenu: false, enableResize: false, defaultCursor: null, borderThickness: 6, @@ -570,10 +608,14 @@ setResize("e-resize"); }); window.addEventListener("contextmenu", function(e) { - if (window.wails.flags.disableWailsDefaultContextMenu) { + if (true) + return; + if (window.wails.flags.disableDefaultContextMenu) { e.preventDefault(); + } else { + processDefaultContextMenu(e); } }); window.WailsInvoke("runtime:ready"); })(); -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiZGVza3RvcC9sb2cuanMiLCAiZGVza3RvcC9ldmVudHMuanMiLCAiZGVza3RvcC9jYWxscy5qcyIsICJkZXNrdG9wL2JpbmRpbmdzLmpzIiwgImRlc2t0b3Avd2luZG93LmpzIiwgImRlc2t0b3Avc2NyZWVuLmpzIiwgImRlc2t0b3AvYnJvd3Nlci5qcyIsICJkZXNrdG9wL2NsaXBib2FyZC5qcyIsICJkZXNrdG9wL21haW4uanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qXG4gXyAgICAgICBfXyAgICAgIF8gX19cbnwgfCAgICAgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA2ICovXG5cbi8qKlxuICogU2VuZHMgYSBsb2cgbWVzc2FnZSB0byB0aGUgYmFja2VuZCB3aXRoIHRoZSBnaXZlbiBsZXZlbCArIG1lc3NhZ2VcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbGV2ZWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmZ1bmN0aW9uIHNlbmRMb2dNZXNzYWdlKGxldmVsLCBtZXNzYWdlKSB7XG5cblx0Ly8gTG9nIE1lc3NhZ2UgZm9ybWF0OlxuXHQvLyBsW3R5cGVdW21lc3NhZ2VdXG5cdHdpbmRvdy5XYWlsc0ludm9rZSgnTCcgKyBsZXZlbCArIG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIExvZyB0aGUgZ2l2ZW4gdHJhY2UgbWVzc2FnZSB3aXRoIHRoZSBiYWNrZW5kXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIExvZ1RyYWNlKG1lc3NhZ2UpIHtcblx0c2VuZExvZ01lc3NhZ2UoJ1QnLCBtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBMb2cgdGhlIGdpdmVuIG1lc3NhZ2Ugd2l0aCB0aGUgYmFja2VuZFxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMb2dQcmludChtZXNzYWdlKSB7XG5cdHNlbmRMb2dNZXNzYWdlKCdQJywgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogTG9nIHRoZSBnaXZlbiBkZWJ1ZyBtZXNzYWdlIHdpdGggdGhlIGJhY2tlbmRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gTG9nRGVidWcobWVzc2FnZSkge1xuXHRzZW5kTG9nTWVzc2FnZSgnRCcsIG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIExvZyB0aGUgZ2l2ZW4gaW5mbyBtZXNzYWdlIHdpdGggdGhlIGJhY2tlbmRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gTG9nSW5mbyhtZXNzYWdlKSB7XG5cdHNlbmRMb2dNZXNzYWdlKCdJJywgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogTG9nIHRoZSBnaXZlbiB3YXJuaW5nIG1lc3NhZ2Ugd2l0aCB0aGUgYmFja2VuZFxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMb2dXYXJuaW5nKG1lc3NhZ2UpIHtcblx0c2VuZExvZ01lc3NhZ2UoJ1cnLCBtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBMb2cgdGhlIGdpdmVuIGVycm9yIG1lc3NhZ2Ugd2l0aCB0aGUgYmFja2VuZFxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMb2dFcnJvcihtZXNzYWdlKSB7XG5cdHNlbmRMb2dNZXNzYWdlKCdFJywgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogTG9nIHRoZSBnaXZlbiBmYXRhbCBtZXNzYWdlIHdpdGggdGhlIGJhY2tlbmRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gTG9nRmF0YWwobWVzc2FnZSkge1xuXHRzZW5kTG9nTWVzc2FnZSgnRicsIG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIFNldHMgdGhlIExvZyBsZXZlbCB0byB0aGUgZ2l2ZW4gbG9nIGxldmVsXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IGxvZ2xldmVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBTZXRMb2dMZXZlbChsb2dsZXZlbCkge1xuXHRzZW5kTG9nTWVzc2FnZSgnUycsIGxvZ2xldmVsKTtcbn1cblxuLy8gTG9nIGxldmVsc1xuZXhwb3J0IGNvbnN0IExvZ0xldmVsID0ge1xuXHRUUkFDRTogMSxcblx0REVCVUc6IDIsXG5cdElORk86IDMsXG5cdFdBUk5JTkc6IDQsXG5cdEVSUk9SOiA1LFxufTtcbiIsICIvKlxuIF8gICAgICAgX18gICAgICBfIF9fXG58IHwgICAgIC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cbi8qIGpzaGludCBlc3ZlcnNpb246IDYgKi9cblxuLy8gRGVmaW5lcyBhIHNpbmdsZSBsaXN0ZW5lciB3aXRoIGEgbWF4aW11bSBudW1iZXIgb2YgdGltZXMgdG8gY2FsbGJhY2tcblxuLyoqXG4gKiBUaGUgTGlzdGVuZXIgY2xhc3MgZGVmaW5lcyBhIGxpc3RlbmVyISA6LSlcbiAqXG4gKiBAY2xhc3MgTGlzdGVuZXJcbiAqL1xuY2xhc3MgTGlzdGVuZXIge1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgTGlzdGVuZXIuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IGNhbGxiYWNrXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IG1heENhbGxiYWNrc1xuICAgICAqIEBtZW1iZXJvZiBMaXN0ZW5lclxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGV2ZW50TmFtZSwgY2FsbGJhY2ssIG1heENhbGxiYWNrcykge1xuICAgICAgICB0aGlzLmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcbiAgICAgICAgLy8gRGVmYXVsdCBvZiAtMSBtZWFucyBpbmZpbml0ZVxuICAgICAgICB0aGlzLm1heENhbGxiYWNrcyA9IG1heENhbGxiYWNrcyB8fCAtMTtcbiAgICAgICAgLy8gQ2FsbGJhY2sgaW52b2tlcyB0aGUgY2FsbGJhY2sgd2l0aCB0aGUgZ2l2ZW4gZGF0YVxuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhpcyBsaXN0ZW5lciBzaG91bGQgYmUgZGVzdHJveWVkXG4gICAgICAgIHRoaXMuQ2FsbGJhY2sgPSAoZGF0YSkgPT4ge1xuICAgICAgICAgICAgY2FsbGJhY2suYXBwbHkobnVsbCwgZGF0YSk7XG4gICAgICAgICAgICAvLyBJZiBtYXhDYWxsYmFja3MgaXMgaW5maW5pdGUsIHJldHVybiBmYWxzZSAoZG8gbm90IGRlc3Ryb3kpXG4gICAgICAgICAgICBpZiAodGhpcy5tYXhDYWxsYmFja3MgPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRGVjcmVtZW50IG1heENhbGxiYWNrcy4gUmV0dXJuIHRydWUgaWYgbm93IDAsIG90aGVyd2lzZSBmYWxzZVxuICAgICAgICAgICAgdGhpcy5tYXhDYWxsYmFja3MgLT0gMTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1heENhbGxiYWNrcyA9PT0gMDtcbiAgICAgICAgfTtcbiAgICB9XG59XG5cbmV4cG9ydCBjb25zdCBldmVudExpc3RlbmVycyA9IHt9O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBgbWF4Q2FsbGJhY2tzYCB0aW1lcyBiZWZvcmUgYmVpbmcgZGVzdHJveWVkXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEBwYXJhbSB7bnVtYmVyfSBtYXhDYWxsYmFja3NcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGxpc3RlbmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIG1heENhbGxiYWNrcykge1xuICAgIGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0gPSBldmVudExpc3RlbmVyc1tldmVudE5hbWVdIHx8IFtdO1xuICAgIGNvbnN0IHRoaXNMaXN0ZW5lciA9IG5ldyBMaXN0ZW5lcihldmVudE5hbWUsIGNhbGxiYWNrLCBtYXhDYWxsYmFja3MpO1xuICAgIGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0ucHVzaCh0aGlzTGlzdGVuZXIpO1xuICAgIHJldHVybiAoKSA9PiBsaXN0ZW5lck9mZih0aGlzTGlzdGVuZXIpO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBldmVyeSB0aW1lIHRoZSBldmVudCBpcyBlbWl0dGVkXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGxpc3RlbmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNPbihldmVudE5hbWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIEV2ZW50c09uTXVsdGlwbGUoZXZlbnROYW1lLCBjYWxsYmFjaywgLTEpO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBhbiBldmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBvbmNlIHRoZW4gZGVzdHJveWVkXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZVxuICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0byBjYW5jZWwgdGhlIGxpc3RlbmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNPbmNlKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gRXZlbnRzT25NdWx0aXBsZShldmVudE5hbWUsIGNhbGxiYWNrLCAxKTtcbn1cblxuZnVuY3Rpb24gbm90aWZ5TGlzdGVuZXJzKGV2ZW50RGF0YSkge1xuXG4gICAgLy8gR2V0IHRoZSBldmVudCBuYW1lXG4gICAgbGV0IGV2ZW50TmFtZSA9IGV2ZW50RGF0YS5uYW1lO1xuXG4gICAgLy8gQ2hlY2sgaWYgd2UgaGF2ZSBhbnkgbGlzdGVuZXJzIGZvciB0aGlzIGV2ZW50XG4gICAgaWYgKGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0pIHtcblxuICAgICAgICAvLyBLZWVwIGEgbGlzdCBvZiBsaXN0ZW5lciBpbmRleGVzIHRvIGRlc3Ryb3lcbiAgICAgICAgY29uc3QgbmV3RXZlbnRMaXN0ZW5lckxpc3QgPSBldmVudExpc3RlbmVyc1tldmVudE5hbWVdLnNsaWNlKCk7XG5cbiAgICAgICAgLy8gSXRlcmF0ZSBsaXN0ZW5lcnNcbiAgICAgICAgZm9yIChsZXQgY291bnQgPSBldmVudExpc3RlbmVyc1tldmVudE5hbWVdLmxlbmd0aCAtIDE7IGNvdW50ID49IDA7IGNvdW50IC09IDEpIHtcblxuICAgICAgICAgICAgLy8gR2V0IG5leHQgbGlzdGVuZXJcbiAgICAgICAgICAgIGNvbnN0IGxpc3RlbmVyID0gZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXVtjb3VudF07XG5cbiAgICAgICAgICAgIGxldCBkYXRhID0gZXZlbnREYXRhLmRhdGE7XG5cbiAgICAgICAgICAgIC8vIERvIHRoZSBjYWxsYmFja1xuICAgICAgICAgICAgY29uc3QgZGVzdHJveSA9IGxpc3RlbmVyLkNhbGxiYWNrKGRhdGEpO1xuICAgICAgICAgICAgaWYgKGRlc3Ryb3kpIHtcbiAgICAgICAgICAgICAgICAvLyBpZiB0aGUgbGlzdGVuZXIgaW5kaWNhdGVkIHRvIGRlc3Ryb3kgaXRzZWxmLCBhZGQgaXQgdG8gdGhlIGRlc3Ryb3kgbGlzdFxuICAgICAgICAgICAgICAgIG5ld0V2ZW50TGlzdGVuZXJMaXN0LnNwbGljZShjb3VudCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVcGRhdGUgY2FsbGJhY2tzIHdpdGggbmV3IGxpc3Qgb2YgbGlzdGVuZXJzXG4gICAgICAgIGlmIChuZXdFdmVudExpc3RlbmVyTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBldmVudExpc3RlbmVyc1tldmVudE5hbWVdID0gbmV3RXZlbnRMaXN0ZW5lckxpc3Q7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogTm90aWZ5IGluZm9ybXMgZnJvbnRlbmQgbGlzdGVuZXJzIHRoYXQgYW4gZXZlbnQgd2FzIGVtaXR0ZWQgd2l0aCB0aGUgZ2l2ZW4gZGF0YVxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBub3RpZnlNZXNzYWdlIC0gZW5jb2RlZCBub3RpZmljYXRpb24gbWVzc2FnZVxuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNOb3RpZnkobm90aWZ5TWVzc2FnZSkge1xuICAgIC8vIFBhcnNlIHRoZSBtZXNzYWdlXG4gICAgbGV0IG1lc3NhZ2U7XG4gICAgdHJ5IHtcbiAgICAgICAgbWVzc2FnZSA9IEpTT04ucGFyc2Uobm90aWZ5TWVzc2FnZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zdCBlcnJvciA9ICdJbnZhbGlkIEpTT04gcGFzc2VkIHRvIE5vdGlmeTogJyArIG5vdGlmeU1lc3NhZ2U7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihlcnJvcik7XG4gICAgfVxuICAgIG5vdGlmeUxpc3RlbmVycyhtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBFbWl0IGFuIGV2ZW50IHdpdGggdGhlIGdpdmVuIG5hbWUgYW5kIGRhdGFcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNFbWl0KGV2ZW50TmFtZSkge1xuXG4gICAgY29uc3QgcGF5bG9hZCA9IHtcbiAgICAgICAgbmFtZTogZXZlbnROYW1lLFxuICAgICAgICBkYXRhOiBbXS5zbGljZS5hcHBseShhcmd1bWVudHMpLnNsaWNlKDEpLFxuICAgIH07XG5cbiAgICAvLyBOb3RpZnkgSlMgbGlzdGVuZXJzXG4gICAgbm90aWZ5TGlzdGVuZXJzKHBheWxvYWQpO1xuXG4gICAgLy8gTm90aWZ5IEdvIGxpc3RlbmVyc1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnRUUnICsgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xufVxuXG5mdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihldmVudE5hbWUpIHtcbiAgICAvLyBSZW1vdmUgbG9jYWwgbGlzdGVuZXJzXG4gICAgZGVsZXRlIGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV07XG5cbiAgICAvLyBOb3RpZnkgR28gbGlzdGVuZXJzXG4gICAgd2luZG93LldhaWxzSW52b2tlKCdFWCcgKyBldmVudE5hbWUpO1xufVxuXG4vKipcbiAqIE9mZiB1bnJlZ2lzdGVycyBhIGxpc3RlbmVyIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCB3aXRoIE9uLFxuICogb3B0aW9uYWxseSBtdWx0aXBsZSBsaXN0ZW5lcmVzIGNhbiBiZSB1bnJlZ2lzdGVyZWQgdmlhIGBhZGRpdGlvbmFsRXZlbnROYW1lc2BcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gKiBAcGFyYW0gIHsuLi5zdHJpbmd9IGFkZGl0aW9uYWxFdmVudE5hbWVzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBFdmVudHNPZmYoZXZlbnROYW1lLCAuLi5hZGRpdGlvbmFsRXZlbnROYW1lcykge1xuICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSlcblxuICAgIGlmIChhZGRpdGlvbmFsRXZlbnROYW1lcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGFkZGl0aW9uYWxFdmVudE5hbWVzLmZvckVhY2goZXZlbnROYW1lID0+IHtcbiAgICAgICAgICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSlcbiAgICAgICAgfSlcbiAgICB9XG59XG5cbi8qKlxuICogT2ZmIHVucmVnaXN0ZXJzIGFsbCBldmVudCBsaXN0ZW5lcnMgcHJldmlvdXNseSByZWdpc3RlcmVkIHdpdGggT25cbiAqL1xuIGV4cG9ydCBmdW5jdGlvbiBFdmVudHNPZmZBbGwoKSB7XG4gICAgY29uc3QgZXZlbnROYW1lcyA9IE9iamVjdC5rZXlzKGV2ZW50TGlzdGVuZXJzKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSAhPT0gZXZlbnROYW1lcy5sZW5ndGg7IGkrKykge1xuICAgICAgICByZW1vdmVMaXN0ZW5lcihldmVudE5hbWVzW2ldKTtcbiAgICB9XG59XG5cbi8qKlxuICogbGlzdGVuZXJPZmYgdW5yZWdpc3RlcnMgYSBsaXN0ZW5lciBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBFdmVudHNPblxuICpcbiAqIEBwYXJhbSB7TGlzdGVuZXJ9IGxpc3RlbmVyXG4gKi9cbiBmdW5jdGlvbiBsaXN0ZW5lck9mZihsaXN0ZW5lcikge1xuICAgIGNvbnN0IGV2ZW50TmFtZSA9IGxpc3RlbmVyLmV2ZW50TmFtZTtcbiAgICAvLyBSZW1vdmUgbG9jYWwgbGlzdGVuZXJcbiAgICBldmVudExpc3RlbmVyc1tldmVudE5hbWVdID0gZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXS5maWx0ZXIobCA9PiBsICE9PSBsaXN0ZW5lcik7XG5cbiAgICAvLyBDbGVhbiB1cCBpZiB0aGVyZSBhcmUgbm8gZXZlbnQgbGlzdGVuZXJzIGxlZnRcbiAgICBpZiAoZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmVtb3ZlTGlzdGVuZXIoZXZlbnROYW1lKTtcbiAgICB9XG59XG4iLCAiLypcbiBfICAgICAgIF9fICAgICAgXyBfX1xufCB8ICAgICAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA2ICovXG5cbmV4cG9ydCBjb25zdCBjYWxsYmFja3MgPSB7fTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgbnVtYmVyIGZyb20gdGhlIG5hdGl2ZSBicm93c2VyIHJhbmRvbSBmdW5jdGlvblxuICpcbiAqIEByZXR1cm5zIG51bWJlclxuICovXG5mdW5jdGlvbiBjcnlwdG9SYW5kb20oKSB7XG5cdHZhciBhcnJheSA9IG5ldyBVaW50MzJBcnJheSgxKTtcblx0cmV0dXJuIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycmF5KVswXTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbnVtYmVyIHVzaW5nIGRhIG9sZC1za29vbCBNYXRoLlJhbmRvbVxuICogSSBsaWtlcyB0byBjYWxsIGl0IExPTFJhbmRvbVxuICpcbiAqIEByZXR1cm5zIG51bWJlclxuICovXG5mdW5jdGlvbiBiYXNpY1JhbmRvbSgpIHtcblx0cmV0dXJuIE1hdGgucmFuZG9tKCkgKiA5MDA3MTk5MjU0NzQwOTkxO1xufVxuXG4vLyBQaWNrIGEgcmFuZG9tIG51bWJlciBmdW5jdGlvbiBiYXNlZCBvbiBicm93c2VyIGNhcGFiaWxpdHlcbnZhciByYW5kb21GdW5jO1xuaWYgKHdpbmRvdy5jcnlwdG8pIHtcblx0cmFuZG9tRnVuYyA9IGNyeXB0b1JhbmRvbTtcbn0gZWxzZSB7XG5cdHJhbmRvbUZ1bmMgPSBiYXNpY1JhbmRvbTtcbn1cblxuXG4vKipcbiAqIENhbGwgc2VuZHMgYSBtZXNzYWdlIHRvIHRoZSBiYWNrZW5kIHRvIGNhbGwgdGhlIGJpbmRpbmcgd2l0aCB0aGVcbiAqIGdpdmVuIGRhdGEuIEEgcHJvbWlzZSBpcyByZXR1cm5lZCBhbmQgd2lsbCBiZSBjb21wbGV0ZWQgd2hlbiB0aGVcbiAqIGJhY2tlbmQgcmVzcG9uZHMuIFRoaXMgd2lsbCBiZSByZXNvbHZlZCB3aGVuIHRoZSBjYWxsIHdhcyBzdWNjZXNzZnVsXG4gKiBvciByZWplY3RlZCBpZiBhbiBlcnJvciBpcyBwYXNzZWQgYmFjay5cbiAqIFRoZXJlIGlzIGEgdGltZW91dCBtZWNoYW5pc20uIElmIHRoZSBjYWxsIGRvZXNuJ3QgcmVzcG9uZCBpbiB0aGUgZ2l2ZW5cbiAqIHRpbWUgKGluIG1pbGxpc2Vjb25kcykgdGhlbiB0aGUgcHJvbWlzZSBpcyByZWplY3RlZC5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICogQHBhcmFtIHthbnk9fSBhcmdzXG4gKiBAcGFyYW0ge251bWJlcj19IHRpbWVvdXRcbiAqIEByZXR1cm5zXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDYWxsKG5hbWUsIGFyZ3MsIHRpbWVvdXQpIHtcblxuXHQvLyBUaW1lb3V0IGluZmluaXRlIGJ5IGRlZmF1bHRcblx0aWYgKHRpbWVvdXQgPT0gbnVsbCkge1xuXHRcdHRpbWVvdXQgPSAwO1xuXHR9XG5cblx0Ly8gQ3JlYXRlIGEgcHJvbWlzZVxuXHRyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXG5cdFx0Ly8gQ3JlYXRlIGEgdW5pcXVlIGNhbGxiYWNrSURcblx0XHR2YXIgY2FsbGJhY2tJRDtcblx0XHRkbyB7XG5cdFx0XHRjYWxsYmFja0lEID0gbmFtZSArICctJyArIHJhbmRvbUZ1bmMoKTtcblx0XHR9IHdoaWxlIChjYWxsYmFja3NbY2FsbGJhY2tJRF0pO1xuXG5cdFx0dmFyIHRpbWVvdXRIYW5kbGU7XG5cdFx0Ly8gU2V0IHRpbWVvdXRcblx0XHRpZiAodGltZW91dCA+IDApIHtcblx0XHRcdHRpbWVvdXRIYW5kbGUgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0cmVqZWN0KEVycm9yKCdDYWxsIHRvICcgKyBuYW1lICsgJyB0aW1lZCBvdXQuIFJlcXVlc3QgSUQ6ICcgKyBjYWxsYmFja0lEKSk7XG5cdFx0XHR9LCB0aW1lb3V0KTtcblx0XHR9XG5cblx0XHQvLyBTdG9yZSBjYWxsYmFja1xuXHRcdGNhbGxiYWNrc1tjYWxsYmFja0lEXSA9IHtcblx0XHRcdHRpbWVvdXRIYW5kbGU6IHRpbWVvdXRIYW5kbGUsXG5cdFx0XHRyZWplY3Q6IHJlamVjdCxcblx0XHRcdHJlc29sdmU6IHJlc29sdmVcblx0XHR9O1xuXG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHBheWxvYWQgPSB7XG5cdFx0XHRcdG5hbWUsXG5cdFx0XHRcdGFyZ3MsXG5cdFx0XHRcdGNhbGxiYWNrSUQsXG5cdFx0XHR9O1xuXG4gICAgICAgICAgICAvLyBNYWtlIHRoZSBjYWxsXG4gICAgICAgICAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ0MnICsgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cblxud2luZG93Lk9iZnVzY2F0ZWRDYWxsID0gKGlkLCBhcmdzLCB0aW1lb3V0KSA9PiB7XG5cbiAgICAvLyBUaW1lb3V0IGluZmluaXRlIGJ5IGRlZmF1bHRcbiAgICBpZiAodGltZW91dCA9PSBudWxsKSB7XG4gICAgICAgIHRpbWVvdXQgPSAwO1xuICAgIH1cblxuICAgIC8vIENyZWF0ZSBhIHByb21pc2VcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXG4gICAgICAgIC8vIENyZWF0ZSBhIHVuaXF1ZSBjYWxsYmFja0lEXG4gICAgICAgIHZhciBjYWxsYmFja0lEO1xuICAgICAgICBkbyB7XG4gICAgICAgICAgICBjYWxsYmFja0lEID0gaWQgKyAnLScgKyByYW5kb21GdW5jKCk7XG4gICAgICAgIH0gd2hpbGUgKGNhbGxiYWNrc1tjYWxsYmFja0lEXSk7XG5cbiAgICAgICAgdmFyIHRpbWVvdXRIYW5kbGU7XG4gICAgICAgIC8vIFNldCB0aW1lb3V0XG4gICAgICAgIGlmICh0aW1lb3V0ID4gMCkge1xuICAgICAgICAgICAgdGltZW91dEhhbmRsZSA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJlamVjdChFcnJvcignQ2FsbCB0byBtZXRob2QgJyArIGlkICsgJyB0aW1lZCBvdXQuIFJlcXVlc3QgSUQ6ICcgKyBjYWxsYmFja0lEKSk7XG4gICAgICAgICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0b3JlIGNhbGxiYWNrXG4gICAgICAgIGNhbGxiYWNrc1tjYWxsYmFja0lEXSA9IHtcbiAgICAgICAgICAgIHRpbWVvdXRIYW5kbGU6IHRpbWVvdXRIYW5kbGUsXG4gICAgICAgICAgICByZWplY3Q6IHJlamVjdCxcbiAgICAgICAgICAgIHJlc29sdmU6IHJlc29sdmVcbiAgICAgICAgfTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcGF5bG9hZCA9IHtcblx0XHRcdFx0aWQsXG5cdFx0XHRcdGFyZ3MsXG5cdFx0XHRcdGNhbGxiYWNrSUQsXG5cdFx0XHR9O1xuXG4gICAgICAgICAgICAvLyBNYWtlIHRoZSBjYWxsXG4gICAgICAgICAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ2MnICsgSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn07XG5cblxuLyoqXG4gKiBDYWxsZWQgYnkgdGhlIGJhY2tlbmQgdG8gcmV0dXJuIGRhdGEgdG8gYSBwcmV2aW91c2x5IGNhbGxlZFxuICogYmluZGluZyBpbnZvY2F0aW9uXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IGluY29taW5nTWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gQ2FsbGJhY2soaW5jb21pbmdNZXNzYWdlKSB7XG5cdC8vIFBhcnNlIHRoZSBtZXNzYWdlXG5cdGxldCBtZXNzYWdlO1xuXHR0cnkge1xuXHRcdG1lc3NhZ2UgPSBKU09OLnBhcnNlKGluY29taW5nTWVzc2FnZSk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRjb25zdCBlcnJvciA9IGBJbnZhbGlkIEpTT04gcGFzc2VkIHRvIGNhbGxiYWNrOiAke2UubWVzc2FnZX0uIE1lc3NhZ2U6ICR7aW5jb21pbmdNZXNzYWdlfWA7XG5cdFx0cnVudGltZS5Mb2dEZWJ1ZyhlcnJvcik7XG5cdFx0dGhyb3cgbmV3IEVycm9yKGVycm9yKTtcblx0fVxuXHRsZXQgY2FsbGJhY2tJRCA9IG1lc3NhZ2UuY2FsbGJhY2tpZDtcblx0bGV0IGNhbGxiYWNrRGF0YSA9IGNhbGxiYWNrc1tjYWxsYmFja0lEXTtcblx0aWYgKCFjYWxsYmFja0RhdGEpIHtcblx0XHRjb25zdCBlcnJvciA9IGBDYWxsYmFjayAnJHtjYWxsYmFja0lEfScgbm90IHJlZ2lzdGVyZWQhISFgO1xuXHRcdGNvbnNvbGUuZXJyb3IoZXJyb3IpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lXG5cdFx0dGhyb3cgbmV3IEVycm9yKGVycm9yKTtcblx0fVxuXHRjbGVhclRpbWVvdXQoY2FsbGJhY2tEYXRhLnRpbWVvdXRIYW5kbGUpO1xuXG5cdGRlbGV0ZSBjYWxsYmFja3NbY2FsbGJhY2tJRF07XG5cblx0aWYgKG1lc3NhZ2UuZXJyb3IpIHtcblx0XHRjYWxsYmFja0RhdGEucmVqZWN0KG1lc3NhZ2UuZXJyb3IpO1xuXHR9IGVsc2Uge1xuXHRcdGNhbGxiYWNrRGF0YS5yZXNvbHZlKG1lc3NhZ2UucmVzdWx0KTtcblx0fVxufVxuIiwgIi8qXG4gXyAgICAgICBfXyAgICAgIF8gX18gICAgXG58IHwgICAgIC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gICkgXG58X18vfF9fL1xcX18sXy9fL18vX19fXy8gIFxuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cbi8qIGpzaGludCBlc3ZlcnNpb246IDYgKi9cblxuaW1wb3J0IHtDYWxsfSBmcm9tICcuL2NhbGxzJztcblxuLy8gVGhpcyBpcyB3aGVyZSB3ZSBiaW5kIGdvIG1ldGhvZCB3cmFwcGVyc1xud2luZG93LmdvID0ge307XG5cbmV4cG9ydCBmdW5jdGlvbiBTZXRCaW5kaW5ncyhiaW5kaW5nc01hcCkge1xuXHR0cnkge1xuXHRcdGJpbmRpbmdzTWFwID0gSlNPTi5wYXJzZShiaW5kaW5nc01hcCk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRjb25zb2xlLmVycm9yKGUpO1xuXHR9XG5cblx0Ly8gSW5pdGlhbGlzZSB0aGUgYmluZGluZ3MgbWFwXG5cdHdpbmRvdy5nbyA9IHdpbmRvdy5nbyB8fCB7fTtcblxuXHQvLyBJdGVyYXRlIHBhY2thZ2UgbmFtZXNcblx0T2JqZWN0LmtleXMoYmluZGluZ3NNYXApLmZvckVhY2goKHBhY2thZ2VOYW1lKSA9PiB7XG5cblx0XHQvLyBDcmVhdGUgaW5uZXIgbWFwIGlmIGl0IGRvZXNuJ3QgZXhpc3Rcblx0XHR3aW5kb3cuZ29bcGFja2FnZU5hbWVdID0gd2luZG93LmdvW3BhY2thZ2VOYW1lXSB8fCB7fTtcblxuXHRcdC8vIEl0ZXJhdGUgc3RydWN0IG5hbWVzXG5cdFx0T2JqZWN0LmtleXMoYmluZGluZ3NNYXBbcGFja2FnZU5hbWVdKS5mb3JFYWNoKChzdHJ1Y3ROYW1lKSA9PiB7XG5cblx0XHRcdC8vIENyZWF0ZSBpbm5lciBtYXAgaWYgaXQgZG9lc24ndCBleGlzdFxuXHRcdFx0d2luZG93LmdvW3BhY2thZ2VOYW1lXVtzdHJ1Y3ROYW1lXSA9IHdpbmRvdy5nb1twYWNrYWdlTmFtZV1bc3RydWN0TmFtZV0gfHwge307XG5cblx0XHRcdE9iamVjdC5rZXlzKGJpbmRpbmdzTWFwW3BhY2thZ2VOYW1lXVtzdHJ1Y3ROYW1lXSkuZm9yRWFjaCgobWV0aG9kTmFtZSkgPT4ge1xuXG5cdFx0XHRcdHdpbmRvdy5nb1twYWNrYWdlTmFtZV1bc3RydWN0TmFtZV1bbWV0aG9kTmFtZV0gPSBmdW5jdGlvbiAoKSB7XG5cblx0XHRcdFx0XHQvLyBObyB0aW1lb3V0IGJ5IGRlZmF1bHRcblx0XHRcdFx0XHRsZXQgdGltZW91dCA9IDA7XG5cblx0XHRcdFx0XHQvLyBBY3R1YWwgZnVuY3Rpb25cblx0XHRcdFx0XHRmdW5jdGlvbiBkeW5hbWljKCkge1xuXHRcdFx0XHRcdFx0Y29uc3QgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblx0XHRcdFx0XHRcdHJldHVybiBDYWxsKFtwYWNrYWdlTmFtZSwgc3RydWN0TmFtZSwgbWV0aG9kTmFtZV0uam9pbignLicpLCBhcmdzLCB0aW1lb3V0KTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBBbGxvdyBzZXR0aW5nIHRpbWVvdXQgdG8gZnVuY3Rpb25cblx0XHRcdFx0XHRkeW5hbWljLnNldFRpbWVvdXQgPSBmdW5jdGlvbiAobmV3VGltZW91dCkge1xuXHRcdFx0XHRcdFx0dGltZW91dCA9IG5ld1RpbWVvdXQ7XG5cdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdC8vIEFsbG93IGdldHRpbmcgdGltZW91dCB0byBmdW5jdGlvblxuXHRcdFx0XHRcdGR5bmFtaWMuZ2V0VGltZW91dCA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdFx0XHRcdHJldHVybiB0aW1lb3V0O1xuXHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRyZXR1cm4gZHluYW1pYztcblx0XHRcdFx0fSgpO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH0pO1xufVxuIiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXG5cblxuaW1wb3J0IHtDYWxsfSBmcm9tIFwiLi9jYWxsc1wiO1xuXG5leHBvcnQgZnVuY3Rpb24gV2luZG93UmVsb2FkKCkge1xuICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1JlbG9hZEFwcCgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dSJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRTeXN0ZW1EZWZhdWx0VGhlbWUoKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXQVNEVCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0TGlnaHRUaGVtZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dBTFQnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1NldERhcmtUaGVtZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dBRFQnKTtcbn1cblxuLyoqXG4gKiBQbGFjZSB0aGUgd2luZG93IGluIHRoZSBjZW50ZXIgb2YgdGhlIHNjcmVlblxuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0NlbnRlcigpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1djJyk7XG59XG5cbi8qKlxuICogU2V0cyB0aGUgd2luZG93IHRpdGxlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHRpdGxlXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRUaXRsZSh0aXRsZSkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV1QnICsgdGl0bGUpO1xufVxuXG4vKipcbiAqIE1ha2VzIHRoZSB3aW5kb3cgZ28gZnVsbHNjcmVlblxuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0Z1bGxzY3JlZW4oKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXRicpO1xufVxuXG4vKipcbiAqIFJldmVydHMgdGhlIHdpbmRvdyBmcm9tIGZ1bGxzY3JlZW5cbiAqXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dVbmZ1bGxzY3JlZW4oKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXZicpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHN0YXRlIG9mIHRoZSB3aW5kb3csIGkuZS4gd2hldGhlciB0aGUgd2luZG93IGlzIGluIGZ1bGwgc2NyZWVuIG1vZGUgb3Igbm90LlxuICpcbiAqIEBleHBvcnRcbiAqIEByZXR1cm4ge1Byb21pc2U8Ym9vbGVhbj59IFRoZSBzdGF0ZSBvZiB0aGUgd2luZG93XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dJc0Z1bGxzY3JlZW4oKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93SXNGdWxsc2NyZWVuXCIpO1xufVxuXG4vKipcbiAqIFNldCB0aGUgU2l6ZSBvZiB0aGUgd2luZG93XG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRTaXplKHdpZHRoLCBoZWlnaHQpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dzOicgKyB3aWR0aCArICc6JyArIGhlaWdodCk7XG59XG5cbi8qKlxuICogR2V0IHRoZSBTaXplIG9mIHRoZSB3aW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPHt3OiBudW1iZXIsIGg6IG51bWJlcn0+fSBUaGUgc2l6ZSBvZiB0aGUgd2luZG93XG5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0dldFNpemUoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93R2V0U2l6ZVwiKTtcbn1cblxuLyoqXG4gKiBTZXQgdGhlIG1heGltdW0gc2l6ZSBvZiB0aGUgd2luZG93XG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRNYXhTaXplKHdpZHRoLCBoZWlnaHQpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1daOicgKyB3aWR0aCArICc6JyArIGhlaWdodCk7XG59XG5cbi8qKlxuICogU2V0IHRoZSBtaW5pbXVtIHNpemUgb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aFxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0TWluU2l6ZSh3aWR0aCwgaGVpZ2h0KSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXejonICsgd2lkdGggKyAnOicgKyBoZWlnaHQpO1xufVxuXG5cblxuLyoqXG4gKiBTZXQgdGhlIHdpbmRvdyBBbHdheXNPblRvcCBvciBub3Qgb24gdG9wXG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0QWx3YXlzT25Ub3AoYikge1xuXG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXQVRQOicgKyAoYiA/ICcxJyA6ICcwJykpO1xufVxuXG5cblxuXG4vKipcbiAqIFNldCB0aGUgUG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSB4XG4gKiBAcGFyYW0ge251bWJlcn0geVxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0UG9zaXRpb24oeCwgeSkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV3A6JyArIHggKyAnOicgKyB5KTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIFBvc2l0aW9uIG9mIHRoZSB3aW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPHt4OiBudW1iZXIsIHk6IG51bWJlcn0+fSBUaGUgcG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93R2V0UG9zaXRpb24oKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93R2V0UG9zXCIpO1xufVxuXG4vKipcbiAqIEhpZGUgdGhlIFdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0hpZGUoKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXSCcpO1xufVxuXG4vKipcbiAqIFNob3cgdGhlIFdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1Nob3coKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXUycpO1xufVxuXG4vKipcbiAqIE1heGltaXNlIHRoZSBXaW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dNYXhpbWlzZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dNJyk7XG59XG5cbi8qKlxuICogVG9nZ2xlIHRoZSBNYXhpbWlzZSBvZiB0aGUgV2luZG93XG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93VG9nZ2xlTWF4aW1pc2UoKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXdCcpO1xufVxuXG4vKipcbiAqIFVubWF4aW1pc2UgdGhlIFdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1VubWF4aW1pc2UoKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXVScpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHN0YXRlIG9mIHRoZSB3aW5kb3csIGkuZS4gd2hldGhlciB0aGUgd2luZG93IGlzIG1heGltaXNlZCBvciBub3QuXG4gKlxuICogQGV4cG9ydFxuICogQHJldHVybiB7UHJvbWlzZTxib29sZWFuPn0gVGhlIHN0YXRlIG9mIHRoZSB3aW5kb3dcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0lzTWF4aW1pc2VkKCkge1xuICAgIHJldHVybiBDYWxsKFwiOndhaWxzOldpbmRvd0lzTWF4aW1pc2VkXCIpO1xufVxuXG4vKipcbiAqIE1pbmltaXNlIHRoZSBXaW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dNaW5pbWlzZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dtJyk7XG59XG5cbi8qKlxuICogVW5taW5pbWlzZSB0aGUgV2luZG93XG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93VW5taW5pbWlzZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1d1Jyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3RhdGUgb2YgdGhlIHdpbmRvdywgaS5lLiB3aGV0aGVyIHRoZSB3aW5kb3cgaXMgbWluaW1pc2VkIG9yIG5vdC5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPGJvb2xlYW4+fSBUaGUgc3RhdGUgb2YgdGhlIHdpbmRvd1xuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93SXNNaW5pbWlzZWQoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93SXNNaW5pbWlzZWRcIik7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3RhdGUgb2YgdGhlIHdpbmRvdywgaS5lLiB3aGV0aGVyIHRoZSB3aW5kb3cgaXMgbm9ybWFsIG9yIG5vdC5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPGJvb2xlYW4+fSBUaGUgc3RhdGUgb2YgdGhlIHdpbmRvd1xuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93SXNOb3JtYWwoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93SXNOb3JtYWxcIik7XG59XG5cbi8qKlxuICogU2V0cyB0aGUgYmFja2dyb3VuZCBjb2xvdXIgb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7bnVtYmVyfSBSIFJlZFxuICogQHBhcmFtIHtudW1iZXJ9IEcgR3JlZW5cbiAqIEBwYXJhbSB7bnVtYmVyfSBCIEJsdWVcbiAqIEBwYXJhbSB7bnVtYmVyfSBBIEFscGhhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRCYWNrZ3JvdW5kQ29sb3VyKFIsIEcsIEIsIEEpIHtcbiAgICBsZXQgcmdiYSA9IEpTT04uc3RyaW5naWZ5KHtyOiBSIHx8IDAsIGc6IEcgfHwgMCwgYjogQiB8fCAwLCBhOiBBIHx8IDI1NX0pO1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV3I6JyArIHJnYmEpO1xufVxuXG4iLCAiLypcbiBfXHQgICBfX1x0ICBfIF9fXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG5cbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cblxuXG5pbXBvcnQge0NhbGx9IGZyb20gXCIuL2NhbGxzXCI7XG5cblxuLyoqXG4gKiBHZXRzIHRoZSBhbGwgc2NyZWVucy4gQ2FsbCB0aGlzIGFuZXcgZWFjaCB0aW1lIHlvdSB3YW50IHRvIHJlZnJlc2ggZGF0YSBmcm9tIHRoZSB1bmRlcmx5aW5nIHdpbmRvd2luZyBzeXN0ZW0uXG4gKiBAZXhwb3J0XG4gKiBAdHlwZWRlZiB7aW1wb3J0KCcuLi93cmFwcGVyL3J1bnRpbWUnKS5TY3JlZW59IFNjcmVlblxuICogQHJldHVybiB7UHJvbWlzZTx7U2NyZWVuW119Pn0gVGhlIHNjcmVlbnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFNjcmVlbkdldEFsbCgpIHtcbiAgICByZXR1cm4gQ2FsbChcIjp3YWlsczpTY3JlZW5HZXRBbGxcIik7XG59XG4iLCAiLyoqXG4gKiBAZGVzY3JpcHRpb246IFVzZSB0aGUgc3lzdGVtIGRlZmF1bHQgYnJvd3NlciB0byBvcGVuIHRoZSB1cmxcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgXG4gKiBAcmV0dXJuIHt2b2lkfVxuICovXG5leHBvcnQgZnVuY3Rpb24gQnJvd3Nlck9wZW5VUkwodXJsKSB7XG4gIHdpbmRvdy5XYWlsc0ludm9rZSgnQk86JyArIHVybCk7XG59IiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXG5cbmltcG9ydCB7Q2FsbH0gZnJvbSBcIi4vY2FsbHNcIjtcblxuLyoqXG4gKiBTZXQgdGhlIFNpemUgb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSB0ZXh0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDbGlwYm9hcmRTZXRUZXh0KHRleHQpIHtcbiAgICByZXR1cm4gQ2FsbChcIjp3YWlsczpDbGlwYm9hcmRTZXRUZXh0XCIsIFt0ZXh0XSk7XG59XG5cbi8qKlxuICogR2V0IHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhlIGNsaXBib2FyZFxuICpcbiAqIEBleHBvcnRcbiAqIEByZXR1cm4ge1Byb21pc2U8e3N0cmluZ30+fSBUZXh0IGNvbnRlbnQgb2YgdGhlIGNsaXBib2FyZFxuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDbGlwYm9hcmRHZXRUZXh0KCkge1xuICAgIHJldHVybiBDYWxsKFwiOndhaWxzOkNsaXBib2FyZEdldFRleHRcIik7XG59IiwgIi8qXG4gX1x0ICAgX19cdCAgXyBfX1xufCB8XHQgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xuaW1wb3J0ICogYXMgTG9nIGZyb20gJy4vbG9nJztcbmltcG9ydCB7ZXZlbnRMaXN0ZW5lcnMsIEV2ZW50c0VtaXQsIEV2ZW50c05vdGlmeSwgRXZlbnRzT2ZmLCBFdmVudHNPbiwgRXZlbnRzT25jZSwgRXZlbnRzT25NdWx0aXBsZX0gZnJvbSAnLi9ldmVudHMnO1xuaW1wb3J0IHtDYWxsLCBDYWxsYmFjaywgY2FsbGJhY2tzfSBmcm9tICcuL2NhbGxzJztcbmltcG9ydCB7U2V0QmluZGluZ3N9IGZyb20gXCIuL2JpbmRpbmdzXCI7XG5pbXBvcnQgKiBhcyBXaW5kb3cgZnJvbSBcIi4vd2luZG93XCI7XG5pbXBvcnQgKiBhcyBTY3JlZW4gZnJvbSBcIi4vc2NyZWVuXCI7XG5pbXBvcnQgKiBhcyBCcm93c2VyIGZyb20gXCIuL2Jyb3dzZXJcIjtcbmltcG9ydCAqIGFzIENsaXBib2FyZCBmcm9tIFwiLi9jbGlwYm9hcmRcIjtcblxuXG5leHBvcnQgZnVuY3Rpb24gUXVpdCgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1EnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFNob3coKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdTJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBIaWRlKCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnSCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gRW52aXJvbm1lbnQoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6RW52aXJvbm1lbnRcIik7XG59XG5cbi8vIFRoZSBKUyBydW50aW1lXG53aW5kb3cucnVudGltZSA9IHtcbiAgICAuLi5Mb2csXG4gICAgLi4uV2luZG93LFxuICAgIC4uLkJyb3dzZXIsXG4gICAgLi4uU2NyZWVuLFxuICAgIC4uLkNsaXBib2FyZCxcbiAgICBFdmVudHNPbixcbiAgICBFdmVudHNPbmNlLFxuICAgIEV2ZW50c09uTXVsdGlwbGUsXG4gICAgRXZlbnRzRW1pdCxcbiAgICBFdmVudHNPZmYsXG4gICAgRW52aXJvbm1lbnQsXG4gICAgU2hvdyxcbiAgICBIaWRlLFxuICAgIFF1aXRcbn07XG5cbi8vIEludGVybmFsIHdhaWxzIGVuZHBvaW50c1xud2luZG93LndhaWxzID0ge1xuICAgIENhbGxiYWNrLFxuICAgIEV2ZW50c05vdGlmeSxcbiAgICBTZXRCaW5kaW5ncyxcbiAgICBldmVudExpc3RlbmVycyxcbiAgICBjYWxsYmFja3MsXG4gICAgZmxhZ3M6IHtcbiAgICAgICAgZGlzYWJsZVNjcm9sbGJhckRyYWc6IGZhbHNlLFxuICAgICAgICBkaXNhYmxlV2FpbHNEZWZhdWx0Q29udGV4dE1lbnU6IGZhbHNlLFxuICAgICAgICBlbmFibGVSZXNpemU6IGZhbHNlLFxuICAgICAgICBkZWZhdWx0Q3Vyc29yOiBudWxsLFxuICAgICAgICBib3JkZXJUaGlja25lc3M6IDYsXG4gICAgICAgIHNob3VsZERyYWc6IGZhbHNlLFxuICAgICAgICBkZWZlckRyYWdUb01vdXNlTW92ZTogdHJ1ZSxcbiAgICAgICAgY3NzRHJhZ1Byb3BlcnR5OiBcIi0td2FpbHMtZHJhZ2dhYmxlXCIsXG4gICAgICAgIGNzc0RyYWdWYWx1ZTogXCJkcmFnXCIsXG4gICAgfVxufTtcblxuLy8gU2V0IHRoZSBiaW5kaW5nc1xuaWYgKHdpbmRvdy53YWlsc2JpbmRpbmdzKSB7XG4gICAgd2luZG93LndhaWxzLlNldEJpbmRpbmdzKHdpbmRvdy53YWlsc2JpbmRpbmdzKTtcbiAgICBkZWxldGUgd2luZG93LndhaWxzLlNldEJpbmRpbmdzO1xufVxuXG4vLyAoYm9vbCkgVGhpcyBpcyBldmFsdWF0ZWQgYXQgYnVpbGQgdGltZSBpbiBwYWNrYWdlLmpzb25cbmlmICghREVCVUcpIHtcbiAgICBkZWxldGUgd2luZG93LndhaWxzYmluZGluZ3M7XG59XG5cbmxldCBkcmFnVGVzdCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyIHZhbCA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGUudGFyZ2V0KS5nZXRQcm9wZXJ0eVZhbHVlKHdpbmRvdy53YWlscy5mbGFncy5jc3NEcmFnUHJvcGVydHkpO1xuICAgIGlmICh2YWwpIHtcbiAgICAgIHZhbCA9IHZhbC50cmltKCk7XG4gICAgfVxuICAgIFxuICAgIGlmICh2YWwgIT09IHdpbmRvdy53YWlscy5mbGFncy5jc3NEcmFnVmFsdWUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChlLmJ1dHRvbnMgIT09IDEpIHtcbiAgICAgICAgLy8gRG8gbm90IHN0YXJ0IGRyYWdnaW5nIGlmIG5vdCB0aGUgcHJpbWFyeSBidXR0b24gaGFzIGJlZW4gY2xpY2tlZC5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmIChlLmRldGFpbCAhPT0gMSkge1xuICAgICAgICAvLyBEbyBub3Qgc3RhcnQgZHJhZ2dpbmcgaWYgbW9yZSB0aGFuIG9uY2UgaGFzIGJlZW4gY2xpY2tlZCwgZS5nLiB3aGVuIGRvdWJsZSBjbGlja2luZ1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG59O1xuXG53aW5kb3cud2FpbHMuc2V0Q1NTRHJhZ1Byb3BlcnRpZXMgPSBmdW5jdGlvbiAocHJvcGVydHksIHZhbHVlKSB7XG4gICAgd2luZG93LndhaWxzLmZsYWdzLmNzc0RyYWdQcm9wZXJ0eSA9IHByb3BlcnR5O1xuICAgIHdpbmRvdy53YWlscy5mbGFncy5jc3NEcmFnVmFsdWUgPSB2YWx1ZTtcbn1cblxud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIChlKSA9PiB7XG5cbiAgICAvLyBDaGVjayBmb3IgcmVzaXppbmdcbiAgICBpZiAod2luZG93LndhaWxzLmZsYWdzLnJlc2l6ZUVkZ2UpIHtcbiAgICAgICAgd2luZG93LldhaWxzSW52b2tlKFwicmVzaXplOlwiICsgd2luZG93LndhaWxzLmZsYWdzLnJlc2l6ZUVkZ2UpO1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZHJhZ1Rlc3QoZSkpIHtcbiAgICAgICAgaWYgKHdpbmRvdy53YWlscy5mbGFncy5kaXNhYmxlU2Nyb2xsYmFyRHJhZykge1xuICAgICAgICAgICAgLy8gVGhpcyBjaGVja3MgZm9yIGNsaWNrcyBvbiB0aGUgc2Nyb2xsIGJhclxuICAgICAgICAgICAgaWYgKGUub2Zmc2V0WCA+IGUudGFyZ2V0LmNsaWVudFdpZHRoIHx8IGUub2Zmc2V0WSA+IGUudGFyZ2V0LmNsaWVudEhlaWdodCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAod2luZG93LndhaWxzLmZsYWdzLmRlZmVyRHJhZ1RvTW91c2VNb3ZlKSB7XG4gICAgICAgICAgICB3aW5kb3cud2FpbHMuZmxhZ3Muc2hvdWxkRHJhZyA9IHRydWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgICAgICAgIHdpbmRvdy5XYWlsc0ludm9rZShcImRyYWdcIik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHdpbmRvdy53YWlscy5mbGFncy5zaG91bGREcmFnID0gZmFsc2U7XG4gICAgfVxufSk7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgKCkgPT4ge1xuICAgIHdpbmRvdy53YWlscy5mbGFncy5zaG91bGREcmFnID0gZmFsc2U7XG59KTtcblxuZnVuY3Rpb24gc2V0UmVzaXplKGN1cnNvcikge1xuICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5jdXJzb3IgPSBjdXJzb3IgfHwgd2luZG93LndhaWxzLmZsYWdzLmRlZmF1bHRDdXJzb3I7XG4gICAgd2luZG93LndhaWxzLmZsYWdzLnJlc2l6ZUVkZ2UgPSBjdXJzb3I7XG59XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBmdW5jdGlvbiAoZSkge1xuICAgIGlmICh3aW5kb3cud2FpbHMuZmxhZ3Muc2hvdWxkRHJhZykge1xuICAgICAgICB3aW5kb3cud2FpbHMuZmxhZ3Muc2hvdWxkRHJhZyA9IGZhbHNlO1xuICAgICAgICBsZXQgbW91c2VQcmVzc2VkID0gZS5idXR0b25zICE9PSB1bmRlZmluZWQgPyBlLmJ1dHRvbnMgOiBlLndoaWNoO1xuICAgICAgICBpZiAobW91c2VQcmVzc2VkID4gMCkge1xuICAgICAgICAgICAgd2luZG93LldhaWxzSW52b2tlKFwiZHJhZ1wiKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoIXdpbmRvdy53YWlscy5mbGFncy5lbmFibGVSZXNpemUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAod2luZG93LndhaWxzLmZsYWdzLmRlZmF1bHRDdXJzb3IgPT0gbnVsbCkge1xuICAgICAgICB3aW5kb3cud2FpbHMuZmxhZ3MuZGVmYXVsdEN1cnNvciA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZS5jdXJzb3I7XG4gICAgfVxuICAgIGlmICh3aW5kb3cub3V0ZXJXaWR0aCAtIGUuY2xpZW50WCA8IHdpbmRvdy53YWlscy5mbGFncy5ib3JkZXJUaGlja25lc3MgJiYgd2luZG93Lm91dGVySGVpZ2h0IC0gZS5jbGllbnRZIDwgd2luZG93LndhaWxzLmZsYWdzLmJvcmRlclRoaWNrbmVzcykge1xuICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gXCJzZS1yZXNpemVcIjtcbiAgICB9XG4gICAgbGV0IHJpZ2h0Qm9yZGVyID0gd2luZG93Lm91dGVyV2lkdGggLSBlLmNsaWVudFggPCB3aW5kb3cud2FpbHMuZmxhZ3MuYm9yZGVyVGhpY2tuZXNzO1xuICAgIGxldCBsZWZ0Qm9yZGVyID0gZS5jbGllbnRYIDwgd2luZG93LndhaWxzLmZsYWdzLmJvcmRlclRoaWNrbmVzcztcbiAgICBsZXQgdG9wQm9yZGVyID0gZS5jbGllbnRZIDwgd2luZG93LndhaWxzLmZsYWdzLmJvcmRlclRoaWNrbmVzcztcbiAgICBsZXQgYm90dG9tQm9yZGVyID0gd2luZG93Lm91dGVySGVpZ2h0IC0gZS5jbGllbnRZIDwgd2luZG93LndhaWxzLmZsYWdzLmJvcmRlclRoaWNrbmVzcztcblxuICAgIC8vIElmIHdlIGFyZW4ndCBvbiBhbiBlZGdlLCBidXQgd2VyZSwgcmVzZXQgdGhlIGN1cnNvciB0byBkZWZhdWx0XG4gICAgaWYgKCFsZWZ0Qm9yZGVyICYmICFyaWdodEJvcmRlciAmJiAhdG9wQm9yZGVyICYmICFib3R0b21Cb3JkZXIgJiYgd2luZG93LndhaWxzLmZsYWdzLnJlc2l6ZUVkZ2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzZXRSZXNpemUoKTtcbiAgICB9IGVsc2UgaWYgKHJpZ2h0Qm9yZGVyICYmIGJvdHRvbUJvcmRlcikgc2V0UmVzaXplKFwic2UtcmVzaXplXCIpO1xuICAgIGVsc2UgaWYgKGxlZnRCb3JkZXIgJiYgYm90dG9tQm9yZGVyKSBzZXRSZXNpemUoXCJzdy1yZXNpemVcIik7XG4gICAgZWxzZSBpZiAobGVmdEJvcmRlciAmJiB0b3BCb3JkZXIpIHNldFJlc2l6ZShcIm53LXJlc2l6ZVwiKTtcbiAgICBlbHNlIGlmICh0b3BCb3JkZXIgJiYgcmlnaHRCb3JkZXIpIHNldFJlc2l6ZShcIm5lLXJlc2l6ZVwiKTtcbiAgICBlbHNlIGlmIChsZWZ0Qm9yZGVyKSBzZXRSZXNpemUoXCJ3LXJlc2l6ZVwiKTtcbiAgICBlbHNlIGlmICh0b3BCb3JkZXIpIHNldFJlc2l6ZShcIm4tcmVzaXplXCIpO1xuICAgIGVsc2UgaWYgKGJvdHRvbUJvcmRlcikgc2V0UmVzaXplKFwicy1yZXNpemVcIik7XG4gICAgZWxzZSBpZiAocmlnaHRCb3JkZXIpIHNldFJlc2l6ZShcImUtcmVzaXplXCIpO1xuXG59KTtcblxuLy8gU2V0dXAgY29udGV4dCBtZW51IGhvb2tcbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdjb250ZXh0bWVudScsIGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKHdpbmRvdy53YWlscy5mbGFncy5kaXNhYmxlV2FpbHNEZWZhdWx0Q29udGV4dE1lbnUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbn0pO1xuXG53aW5kb3cuV2FpbHNJbnZva2UoXCJydW50aW1lOnJlYWR5XCIpOyJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBa0JBLFdBQVMsZUFBZSxPQUFPLFNBQVM7QUFJdkMsV0FBTyxZQUFZ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 +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiZGVza3RvcC9sb2cuanMiLCAiZGVza3RvcC9ldmVudHMuanMiLCAiZGVza3RvcC9jYWxscy5qcyIsICJkZXNrdG9wL2JpbmRpbmdzLmpzIiwgImRlc2t0b3Avd2luZG93LmpzIiwgImRlc2t0b3Avc2NyZWVuLmpzIiwgImRlc2t0b3AvYnJvd3Nlci5qcyIsICJkZXNrdG9wL2NsaXBib2FyZC5qcyIsICJkZXNrdG9wL2NvbnRleHRtZW51LmpzIiwgImRlc2t0b3AvbWFpbi5qcyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLypcbiBfICAgICAgIF9fICAgICAgXyBfX1xufCB8ICAgICAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG5cbi8qIGpzaGludCBlc3ZlcnNpb246IDYgKi9cblxuLyoqXG4gKiBTZW5kcyBhIGxvZyBtZXNzYWdlIHRvIHRoZSBiYWNrZW5kIHdpdGggdGhlIGdpdmVuIGxldmVsICsgbWVzc2FnZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBsZXZlbFxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAqL1xuZnVuY3Rpb24gc2VuZExvZ01lc3NhZ2UobGV2ZWwsIG1lc3NhZ2UpIHtcblxuXHQvLyBMb2cgTWVzc2FnZSBmb3JtYXQ6XG5cdC8vIGxbdHlwZV1bbWVzc2FnZV1cblx0d2luZG93LldhaWxzSW52b2tlKCdMJyArIGxldmVsICsgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogTG9nIHRoZSBnaXZlbiB0cmFjZSBtZXNzYWdlIHdpdGggdGhlIGJhY2tlbmRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gTG9nVHJhY2UobWVzc2FnZSkge1xuXHRzZW5kTG9nTWVzc2FnZSgnVCcsIG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIExvZyB0aGUgZ2l2ZW4gbWVzc2FnZSB3aXRoIHRoZSBiYWNrZW5kXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIExvZ1ByaW50KG1lc3NhZ2UpIHtcblx0c2VuZExvZ01lc3NhZ2UoJ1AnLCBtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBMb2cgdGhlIGdpdmVuIGRlYnVnIG1lc3NhZ2Ugd2l0aCB0aGUgYmFja2VuZFxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMb2dEZWJ1ZyhtZXNzYWdlKSB7XG5cdHNlbmRMb2dNZXNzYWdlKCdEJywgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogTG9nIHRoZSBnaXZlbiBpbmZvIG1lc3NhZ2Ugd2l0aCB0aGUgYmFja2VuZFxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMb2dJbmZvKG1lc3NhZ2UpIHtcblx0c2VuZExvZ01lc3NhZ2UoJ0knLCBtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBMb2cgdGhlIGdpdmVuIHdhcm5pbmcgbWVzc2FnZSB3aXRoIHRoZSBiYWNrZW5kXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIExvZ1dhcm5pbmcobWVzc2FnZSkge1xuXHRzZW5kTG9nTWVzc2FnZSgnVycsIG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIExvZyB0aGUgZ2l2ZW4gZXJyb3IgbWVzc2FnZSB3aXRoIHRoZSBiYWNrZW5kXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIExvZ0Vycm9yKG1lc3NhZ2UpIHtcblx0c2VuZExvZ01lc3NhZ2UoJ0UnLCBtZXNzYWdlKTtcbn1cblxuLyoqXG4gKiBMb2cgdGhlIGdpdmVuIGZhdGFsIG1lc3NhZ2Ugd2l0aCB0aGUgYmFja2VuZFxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBMb2dGYXRhbChtZXNzYWdlKSB7XG5cdHNlbmRMb2dNZXNzYWdlKCdGJywgbWVzc2FnZSk7XG59XG5cbi8qKlxuICogU2V0cyB0aGUgTG9nIGxldmVsIHRvIHRoZSBnaXZlbiBsb2cgbGV2ZWxcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge251bWJlcn0gbG9nbGV2ZWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFNldExvZ0xldmVsKGxvZ2xldmVsKSB7XG5cdHNlbmRMb2dNZXNzYWdlKCdTJywgbG9nbGV2ZWwpO1xufVxuXG4vLyBMb2cgbGV2ZWxzXG5leHBvcnQgY29uc3QgTG9nTGV2ZWwgPSB7XG5cdFRSQUNFOiAxLFxuXHRERUJVRzogMixcblx0SU5GTzogMyxcblx0V0FSTklORzogNCxcblx0RVJST1I6IDUsXG59O1xuIiwgIi8qXG4gXyAgICAgICBfXyAgICAgIF8gX19cbnwgfCAgICAgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKVxufF9fL3xfXy9cXF9fLF8vXy9fL19fX18vXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuLyoganNoaW50IGVzdmVyc2lvbjogNiAqL1xuXG4vLyBEZWZpbmVzIGEgc2luZ2xlIGxpc3RlbmVyIHdpdGggYSBtYXhpbXVtIG51bWJlciBvZiB0aW1lcyB0byBjYWxsYmFja1xuXG4vKipcbiAqIFRoZSBMaXN0ZW5lciBjbGFzcyBkZWZpbmVzIGEgbGlzdGVuZXIhIDotKVxuICpcbiAqIEBjbGFzcyBMaXN0ZW5lclxuICovXG5jbGFzcyBMaXN0ZW5lciB7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBMaXN0ZW5lci5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gY2FsbGJhY2tcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gbWF4Q2FsbGJhY2tzXG4gICAgICogQG1lbWJlcm9mIExpc3RlbmVyXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoZXZlbnROYW1lLCBjYWxsYmFjaywgbWF4Q2FsbGJhY2tzKSB7XG4gICAgICAgIHRoaXMuZXZlbnROYW1lID0gZXZlbnROYW1lO1xuICAgICAgICAvLyBEZWZhdWx0IG9mIC0xIG1lYW5zIGluZmluaXRlXG4gICAgICAgIHRoaXMubWF4Q2FsbGJhY2tzID0gbWF4Q2FsbGJhY2tzIHx8IC0xO1xuICAgICAgICAvLyBDYWxsYmFjayBpbnZva2VzIHRoZSBjYWxsYmFjayB3aXRoIHRoZSBnaXZlbiBkYXRhXG4gICAgICAgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGxpc3RlbmVyIHNob3VsZCBiZSBkZXN0cm95ZWRcbiAgICAgICAgdGhpcy5DYWxsYmFjayA9IChkYXRhKSA9PiB7XG4gICAgICAgICAgICBjYWxsYmFjay5hcHBseShudWxsLCBkYXRhKTtcbiAgICAgICAgICAgIC8vIElmIG1heENhbGxiYWNrcyBpcyBpbmZpbml0ZSwgcmV0dXJuIGZhbHNlIChkbyBub3QgZGVzdHJveSlcbiAgICAgICAgICAgIGlmICh0aGlzLm1heENhbGxiYWNrcyA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBEZWNyZW1lbnQgbWF4Q2FsbGJhY2tzLiBSZXR1cm4gdHJ1ZSBpZiBub3cgMCwgb3RoZXJ3aXNlIGZhbHNlXG4gICAgICAgICAgICB0aGlzLm1heENhbGxiYWNrcyAtPSAxO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubWF4Q2FsbGJhY2tzID09PSAwO1xuICAgICAgICB9O1xuICAgIH1cbn1cblxuZXhwb3J0IGNvbnN0IGV2ZW50TGlzdGVuZXJzID0ge307XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGBtYXhDYWxsYmFja3NgIHRpbWVzIGJlZm9yZSBiZWluZyBkZXN0cm95ZWRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHBhcmFtIHtudW1iZXJ9IG1heENhbGxiYWNrc1xuICogQHJldHVybnMge2Z1bmN0aW9ufSBBIGZ1bmN0aW9uIHRvIGNhbmNlbCB0aGUgbGlzdGVuZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEV2ZW50c09uTXVsdGlwbGUoZXZlbnROYW1lLCBjYWxsYmFjaywgbWF4Q2FsbGJhY2tzKSB7XG4gICAgZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXSA9IGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0gfHwgW107XG4gICAgY29uc3QgdGhpc0xpc3RlbmVyID0gbmV3IExpc3RlbmVyKGV2ZW50TmFtZSwgY2FsbGJhY2ssIG1heENhbGxiYWNrcyk7XG4gICAgZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXS5wdXNoKHRoaXNMaXN0ZW5lcik7XG4gICAgcmV0dXJuICgpID0+IGxpc3RlbmVyT2ZmKHRoaXNMaXN0ZW5lcik7XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGV2ZXJ5IHRpbWUgdGhlIGV2ZW50IGlzIGVtaXR0ZWRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHJldHVybnMge2Z1bmN0aW9ufSBBIGZ1bmN0aW9uIHRvIGNhbmNlbCB0aGUgbGlzdGVuZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEV2ZW50c09uKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gRXZlbnRzT25NdWx0aXBsZShldmVudE5hbWUsIGNhbGxiYWNrLCAtMSk7XG59XG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuIGV2ZW50IGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIG9uY2UgdGhlbiBkZXN0cm95ZWRcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gZXZlbnROYW1lXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBjYWxsYmFja1xuICogQHJldHVybnMge2Z1bmN0aW9ufSBBIGZ1bmN0aW9uIHRvIGNhbmNlbCB0aGUgbGlzdGVuZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEV2ZW50c09uY2UoZXZlbnROYW1lLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBFdmVudHNPbk11bHRpcGxlKGV2ZW50TmFtZSwgY2FsbGJhY2ssIDEpO1xufVxuXG5mdW5jdGlvbiBub3RpZnlMaXN0ZW5lcnMoZXZlbnREYXRhKSB7XG5cbiAgICAvLyBHZXQgdGhlIGV2ZW50IG5hbWVcbiAgICBsZXQgZXZlbnROYW1lID0gZXZlbnREYXRhLm5hbWU7XG5cbiAgICAvLyBDaGVjayBpZiB3ZSBoYXZlIGFueSBsaXN0ZW5lcnMgZm9yIHRoaXMgZXZlbnRcbiAgICBpZiAoZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXSkge1xuXG4gICAgICAgIC8vIEtlZXAgYSBsaXN0IG9mIGxpc3RlbmVyIGluZGV4ZXMgdG8gZGVzdHJveVxuICAgICAgICBjb25zdCBuZXdFdmVudExpc3RlbmVyTGlzdCA9IGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0uc2xpY2UoKTtcblxuICAgICAgICAvLyBJdGVyYXRlIGxpc3RlbmVyc1xuICAgICAgICBmb3IgKGxldCBjb3VudCA9IGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0ubGVuZ3RoIC0gMTsgY291bnQgPj0gMDsgY291bnQgLT0gMSkge1xuXG4gICAgICAgICAgICAvLyBHZXQgbmV4dCBsaXN0ZW5lclxuICAgICAgICAgICAgY29uc3QgbGlzdGVuZXIgPSBldmVudExpc3RlbmVyc1tldmVudE5hbWVdW2NvdW50XTtcblxuICAgICAgICAgICAgbGV0IGRhdGEgPSBldmVudERhdGEuZGF0YTtcblxuICAgICAgICAgICAgLy8gRG8gdGhlIGNhbGxiYWNrXG4gICAgICAgICAgICBjb25zdCBkZXN0cm95ID0gbGlzdGVuZXIuQ2FsbGJhY2soZGF0YSk7XG4gICAgICAgICAgICBpZiAoZGVzdHJveSkge1xuICAgICAgICAgICAgICAgIC8vIGlmIHRoZSBsaXN0ZW5lciBpbmRpY2F0ZWQgdG8gZGVzdHJveSBpdHNlbGYsIGFkZCBpdCB0byB0aGUgZGVzdHJveSBsaXN0XG4gICAgICAgICAgICAgICAgbmV3RXZlbnRMaXN0ZW5lckxpc3Quc3BsaWNlKGNvdW50LCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVwZGF0ZSBjYWxsYmFja3Mgd2l0aCBuZXcgbGlzdCBvZiBsaXN0ZW5lcnNcbiAgICAgICAgaWYgKG5ld0V2ZW50TGlzdGVuZXJMaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmVtb3ZlTGlzdGVuZXIoZXZlbnROYW1lKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0gPSBuZXdFdmVudExpc3RlbmVyTGlzdDtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBOb3RpZnkgaW5mb3JtcyBmcm9udGVuZCBsaXN0ZW5lcnMgdGhhdCBhbiBldmVudCB3YXMgZW1pdHRlZCB3aXRoIHRoZSBnaXZlbiBkYXRhXG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IG5vdGlmeU1lc3NhZ2UgLSBlbmNvZGVkIG5vdGlmaWNhdGlvbiBtZXNzYWdlXG5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEV2ZW50c05vdGlmeShub3RpZnlNZXNzYWdlKSB7XG4gICAgLy8gUGFyc2UgdGhlIG1lc3NhZ2VcbiAgICBsZXQgbWVzc2FnZTtcbiAgICB0cnkge1xuICAgICAgICBtZXNzYWdlID0gSlNPTi5wYXJzZShub3RpZnlNZXNzYWdlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnN0IGVycm9yID0gJ0ludmFsaWQgSlNPTiBwYXNzZWQgdG8gTm90aWZ5OiAnICsgbm90aWZ5TWVzc2FnZTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgICB9XG4gICAgbm90aWZ5TGlzdGVuZXJzKG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIEVtaXQgYW4gZXZlbnQgd2l0aCB0aGUgZ2l2ZW4gbmFtZSBhbmQgZGF0YVxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEV2ZW50c0VtaXQoZXZlbnROYW1lKSB7XG5cbiAgICBjb25zdCBwYXlsb2FkID0ge1xuICAgICAgICBuYW1lOiBldmVudE5hbWUsXG4gICAgICAgIGRhdGE6IFtdLnNsaWNlLmFwcGx5KGFyZ3VtZW50cykuc2xpY2UoMSksXG4gICAgfTtcblxuICAgIC8vIE5vdGlmeSBKUyBsaXN0ZW5lcnNcbiAgICBub3RpZnlMaXN0ZW5lcnMocGF5bG9hZCk7XG5cbiAgICAvLyBOb3RpZnkgR28gbGlzdGVuZXJzXG4gICAgd2luZG93LldhaWxzSW52b2tlKCdFRScgKyBKU09OLnN0cmluZ2lmeShwYXlsb2FkKSk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZSkge1xuICAgIC8vIFJlbW92ZSBsb2NhbCBsaXN0ZW5lcnNcbiAgICBkZWxldGUgZXZlbnRMaXN0ZW5lcnNbZXZlbnROYW1lXTtcblxuICAgIC8vIE5vdGlmeSBHbyBsaXN0ZW5lcnNcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ0VYJyArIGV2ZW50TmFtZSk7XG59XG5cbi8qKlxuICogT2ZmIHVucmVnaXN0ZXJzIGEgbGlzdGVuZXIgcHJldmlvdXNseSByZWdpc3RlcmVkIHdpdGggT24sXG4gKiBvcHRpb25hbGx5IG11bHRpcGxlIGxpc3RlbmVyZXMgY2FuIGJlIHVucmVnaXN0ZXJlZCB2aWEgYGFkZGl0aW9uYWxFdmVudE5hbWVzYFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudE5hbWVcbiAqIEBwYXJhbSAgey4uLnN0cmluZ30gYWRkaXRpb25hbEV2ZW50TmFtZXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEV2ZW50c09mZihldmVudE5hbWUsIC4uLmFkZGl0aW9uYWxFdmVudE5hbWVzKSB7XG4gICAgcmVtb3ZlTGlzdGVuZXIoZXZlbnROYW1lKVxuXG4gICAgaWYgKGFkZGl0aW9uYWxFdmVudE5hbWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYWRkaXRpb25hbEV2ZW50TmFtZXMuZm9yRWFjaChldmVudE5hbWUgPT4ge1xuICAgICAgICAgICAgcmVtb3ZlTGlzdGVuZXIoZXZlbnROYW1lKVxuICAgICAgICB9KVxuICAgIH1cbn1cblxuLyoqXG4gKiBPZmYgdW5yZWdpc3RlcnMgYWxsIGV2ZW50IGxpc3RlbmVycyBwcmV2aW91c2x5IHJlZ2lzdGVyZWQgd2l0aCBPblxuICovXG4gZXhwb3J0IGZ1bmN0aW9uIEV2ZW50c09mZkFsbCgpIHtcbiAgICBjb25zdCBldmVudE5hbWVzID0gT2JqZWN0LmtleXMoZXZlbnRMaXN0ZW5lcnMpO1xuICAgIGZvciAobGV0IGkgPSAwOyBpICE9PSBldmVudE5hbWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHJlbW92ZUxpc3RlbmVyKGV2ZW50TmFtZXNbaV0pO1xuICAgIH1cbn1cblxuLyoqXG4gKiBsaXN0ZW5lck9mZiB1bnJlZ2lzdGVycyBhIGxpc3RlbmVyIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCB3aXRoIEV2ZW50c09uXG4gKlxuICogQHBhcmFtIHtMaXN0ZW5lcn0gbGlzdGVuZXJcbiAqL1xuIGZ1bmN0aW9uIGxpc3RlbmVyT2ZmKGxpc3RlbmVyKSB7XG4gICAgY29uc3QgZXZlbnROYW1lID0gbGlzdGVuZXIuZXZlbnROYW1lO1xuICAgIC8vIFJlbW92ZSBsb2NhbCBsaXN0ZW5lclxuICAgIGV2ZW50TGlzdGVuZXJzW2V2ZW50TmFtZV0gPSBldmVudExpc3RlbmVyc1tldmVudE5hbWVdLmZpbHRlcihsID0+IGwgIT09IGxpc3RlbmVyKTtcblxuICAgIC8vIENsZWFuIHVwIGlmIHRoZXJlIGFyZSBubyBldmVudCBsaXN0ZW5lcnMgbGVmdFxuICAgIGlmIChldmVudExpc3RlbmVyc1tldmVudE5hbWVdLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZW1vdmVMaXN0ZW5lcihldmVudE5hbWUpO1xuICAgIH1cbn1cbiIsICIvKlxuIF8gICAgICAgX18gICAgICBfIF9fXG58IHwgICAgIC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cbi8qIGpzaGludCBlc3ZlcnNpb246IDYgKi9cblxuZXhwb3J0IGNvbnN0IGNhbGxiYWNrcyA9IHt9O1xuXG4vKipcbiAqIFJldHVybnMgYSBudW1iZXIgZnJvbSB0aGUgbmF0aXZlIGJyb3dzZXIgcmFuZG9tIGZ1bmN0aW9uXG4gKlxuICogQHJldHVybnMgbnVtYmVyXG4gKi9cbmZ1bmN0aW9uIGNyeXB0b1JhbmRvbSgpIHtcblx0dmFyIGFycmF5ID0gbmV3IFVpbnQzMkFycmF5KDEpO1xuXHRyZXR1cm4gd2luZG93LmNyeXB0by5nZXRSYW5kb21WYWx1ZXMoYXJyYXkpWzBdO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBudW1iZXIgdXNpbmcgZGEgb2xkLXNrb29sIE1hdGguUmFuZG9tXG4gKiBJIGxpa2VzIHRvIGNhbGwgaXQgTE9MUmFuZG9tXG4gKlxuICogQHJldHVybnMgbnVtYmVyXG4gKi9cbmZ1bmN0aW9uIGJhc2ljUmFuZG9tKCkge1xuXHRyZXR1cm4gTWF0aC5yYW5kb20oKSAqIDkwMDcxOTkyNTQ3NDA5OTE7XG59XG5cbi8vIFBpY2sgYSByYW5kb20gbnVtYmVyIGZ1bmN0aW9uIGJhc2VkIG9uIGJyb3dzZXIgY2FwYWJpbGl0eVxudmFyIHJhbmRvbUZ1bmM7XG5pZiAod2luZG93LmNyeXB0bykge1xuXHRyYW5kb21GdW5jID0gY3J5cHRvUmFuZG9tO1xufSBlbHNlIHtcblx0cmFuZG9tRnVuYyA9IGJhc2ljUmFuZG9tO1xufVxuXG5cbi8qKlxuICogQ2FsbCBzZW5kcyBhIG1lc3NhZ2UgdG8gdGhlIGJhY2tlbmQgdG8gY2FsbCB0aGUgYmluZGluZyB3aXRoIHRoZVxuICogZ2l2ZW4gZGF0YS4gQSBwcm9taXNlIGlzIHJldHVybmVkIGFuZCB3aWxsIGJlIGNvbXBsZXRlZCB3aGVuIHRoZVxuICogYmFja2VuZCByZXNwb25kcy4gVGhpcyB3aWxsIGJlIHJlc29sdmVkIHdoZW4gdGhlIGNhbGwgd2FzIHN1Y2Nlc3NmdWxcbiAqIG9yIHJlamVjdGVkIGlmIGFuIGVycm9yIGlzIHBhc3NlZCBiYWNrLlxuICogVGhlcmUgaXMgYSB0aW1lb3V0IG1lY2hhbmlzbS4gSWYgdGhlIGNhbGwgZG9lc24ndCByZXNwb25kIGluIHRoZSBnaXZlblxuICogdGltZSAoaW4gbWlsbGlzZWNvbmRzKSB0aGVuIHRoZSBwcm9taXNlIGlzIHJlamVjdGVkLlxuICpcbiAqIEBleHBvcnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcGFyYW0ge2FueT19IGFyZ3NcbiAqIEBwYXJhbSB7bnVtYmVyPX0gdGltZW91dFxuICogQHJldHVybnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIENhbGwobmFtZSwgYXJncywgdGltZW91dCkge1xuXG5cdC8vIFRpbWVvdXQgaW5maW5pdGUgYnkgZGVmYXVsdFxuXHRpZiAodGltZW91dCA9PSBudWxsKSB7XG5cdFx0dGltZW91dCA9IDA7XG5cdH1cblxuXHQvLyBDcmVhdGUgYSBwcm9taXNlXG5cdHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cblx0XHQvLyBDcmVhdGUgYSB1bmlxdWUgY2FsbGJhY2tJRFxuXHRcdHZhciBjYWxsYmFja0lEO1xuXHRcdGRvIHtcblx0XHRcdGNhbGxiYWNrSUQgPSBuYW1lICsgJy0nICsgcmFuZG9tRnVuYygpO1xuXHRcdH0gd2hpbGUgKGNhbGxiYWNrc1tjYWxsYmFja0lEXSk7XG5cblx0XHR2YXIgdGltZW91dEhhbmRsZTtcblx0XHQvLyBTZXQgdGltZW91dFxuXHRcdGlmICh0aW1lb3V0ID4gMCkge1xuXHRcdFx0dGltZW91dEhhbmRsZSA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRyZWplY3QoRXJyb3IoJ0NhbGwgdG8gJyArIG5hbWUgKyAnIHRpbWVkIG91dC4gUmVxdWVzdCBJRDogJyArIGNhbGxiYWNrSUQpKTtcblx0XHRcdH0sIHRpbWVvdXQpO1xuXHRcdH1cblxuXHRcdC8vIFN0b3JlIGNhbGxiYWNrXG5cdFx0Y2FsbGJhY2tzW2NhbGxiYWNrSURdID0ge1xuXHRcdFx0dGltZW91dEhhbmRsZTogdGltZW91dEhhbmRsZSxcblx0XHRcdHJlamVjdDogcmVqZWN0LFxuXHRcdFx0cmVzb2x2ZTogcmVzb2x2ZVxuXHRcdH07XG5cblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgcGF5bG9hZCA9IHtcblx0XHRcdFx0bmFtZSxcblx0XHRcdFx0YXJncyxcblx0XHRcdFx0Y2FsbGJhY2tJRCxcblx0XHRcdH07XG5cbiAgICAgICAgICAgIC8vIE1ha2UgdGhlIGNhbGxcbiAgICAgICAgICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnQycgKyBKU09OLnN0cmluZ2lmeShwYXlsb2FkKSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG53aW5kb3cuT2JmdXNjYXRlZENhbGwgPSAoaWQsIGFyZ3MsIHRpbWVvdXQpID0+IHtcblxuICAgIC8vIFRpbWVvdXQgaW5maW5pdGUgYnkgZGVmYXVsdFxuICAgIGlmICh0aW1lb3V0ID09IG51bGwpIHtcbiAgICAgICAgdGltZW91dCA9IDA7XG4gICAgfVxuXG4gICAgLy8gQ3JlYXRlIGEgcHJvbWlzZVxuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cbiAgICAgICAgLy8gQ3JlYXRlIGEgdW5pcXVlIGNhbGxiYWNrSURcbiAgICAgICAgdmFyIGNhbGxiYWNrSUQ7XG4gICAgICAgIGRvIHtcbiAgICAgICAgICAgIGNhbGxiYWNrSUQgPSBpZCArICctJyArIHJhbmRvbUZ1bmMoKTtcbiAgICAgICAgfSB3aGlsZSAoY2FsbGJhY2tzW2NhbGxiYWNrSURdKTtcblxuICAgICAgICB2YXIgdGltZW91dEhhbmRsZTtcbiAgICAgICAgLy8gU2V0IHRpbWVvdXRcbiAgICAgICAgaWYgKHRpbWVvdXQgPiAwKSB7XG4gICAgICAgICAgICB0aW1lb3V0SGFuZGxlID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmVqZWN0KEVycm9yKCdDYWxsIHRvIG1ldGhvZCAnICsgaWQgKyAnIHRpbWVkIG91dC4gUmVxdWVzdCBJRDogJyArIGNhbGxiYWNrSUQpKTtcbiAgICAgICAgICAgIH0sIHRpbWVvdXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3RvcmUgY2FsbGJhY2tcbiAgICAgICAgY2FsbGJhY2tzW2NhbGxiYWNrSURdID0ge1xuICAgICAgICAgICAgdGltZW91dEhhbmRsZTogdGltZW91dEhhbmRsZSxcbiAgICAgICAgICAgIHJlamVjdDogcmVqZWN0LFxuICAgICAgICAgICAgcmVzb2x2ZTogcmVzb2x2ZVxuICAgICAgICB9O1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBwYXlsb2FkID0ge1xuXHRcdFx0XHRpZCxcblx0XHRcdFx0YXJncyxcblx0XHRcdFx0Y2FsbGJhY2tJRCxcblx0XHRcdH07XG5cbiAgICAgICAgICAgIC8vIE1ha2UgdGhlIGNhbGxcbiAgICAgICAgICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnYycgKyBKU09OLnN0cmluZ2lmeShwYXlsb2FkKSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgfVxuICAgIH0pO1xufTtcblxuXG4vKipcbiAqIENhbGxlZCBieSB0aGUgYmFja2VuZCB0byByZXR1cm4gZGF0YSB0byBhIHByZXZpb3VzbHkgY2FsbGVkXG4gKiBiaW5kaW5nIGludm9jYXRpb25cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ30gaW5jb21pbmdNZXNzYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDYWxsYmFjayhpbmNvbWluZ01lc3NhZ2UpIHtcblx0Ly8gUGFyc2UgdGhlIG1lc3NhZ2Vcblx0bGV0IG1lc3NhZ2U7XG5cdHRyeSB7XG5cdFx0bWVzc2FnZSA9IEpTT04ucGFyc2UoaW5jb21pbmdNZXNzYWdlKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdGNvbnN0IGVycm9yID0gYEludmFsaWQgSlNPTiBwYXNzZWQgdG8gY2FsbGJhY2s6ICR7ZS5tZXNzYWdlfS4gTWVzc2FnZTogJHtpbmNvbWluZ01lc3NhZ2V9YDtcblx0XHRydW50aW1lLkxvZ0RlYnVnKGVycm9yKTtcblx0XHR0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuXHR9XG5cdGxldCBjYWxsYmFja0lEID0gbWVzc2FnZS5jYWxsYmFja2lkO1xuXHRsZXQgY2FsbGJhY2tEYXRhID0gY2FsbGJhY2tzW2NhbGxiYWNrSURdO1xuXHRpZiAoIWNhbGxiYWNrRGF0YSkge1xuXHRcdGNvbnN0IGVycm9yID0gYENhbGxiYWNrICcke2NhbGxiYWNrSUR9JyBub3QgcmVnaXN0ZXJlZCEhIWA7XG5cdFx0Y29uc29sZS5lcnJvcihlcnJvcik7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0XHR0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuXHR9XG5cdGNsZWFyVGltZW91dChjYWxsYmFja0RhdGEudGltZW91dEhhbmRsZSk7XG5cblx0ZGVsZXRlIGNhbGxiYWNrc1tjYWxsYmFja0lEXTtcblxuXHRpZiAobWVzc2FnZS5lcnJvcikge1xuXHRcdGNhbGxiYWNrRGF0YS5yZWplY3QobWVzc2FnZS5lcnJvcik7XG5cdH0gZWxzZSB7XG5cdFx0Y2FsbGJhY2tEYXRhLnJlc29sdmUobWVzc2FnZS5yZXN1bHQpO1xuXHR9XG59XG4iLCAiLypcbiBfICAgICAgIF9fICAgICAgXyBfXyAgICBcbnwgfCAgICAgLyAvX19fIF8oXykgL19fX19cbnwgfCAvfCAvIC8gX18gYC8gLyAvIF9fXy9cbnwgfC8gfC8gLyAvXy8gLyAvIChfXyAgKSBcbnxfXy98X18vXFxfXyxfL18vXy9fX19fLyAgXG5UaGUgZWxlY3Ryb24gYWx0ZXJuYXRpdmUgZm9yIEdvXG4oYykgTGVhIEFudGhvbnkgMjAxOS1wcmVzZW50XG4qL1xuLyoganNoaW50IGVzdmVyc2lvbjogNiAqL1xuXG5pbXBvcnQge0NhbGx9IGZyb20gJy4vY2FsbHMnO1xuXG4vLyBUaGlzIGlzIHdoZXJlIHdlIGJpbmQgZ28gbWV0aG9kIHdyYXBwZXJzXG53aW5kb3cuZ28gPSB7fTtcblxuZXhwb3J0IGZ1bmN0aW9uIFNldEJpbmRpbmdzKGJpbmRpbmdzTWFwKSB7XG5cdHRyeSB7XG5cdFx0YmluZGluZ3NNYXAgPSBKU09OLnBhcnNlKGJpbmRpbmdzTWFwKTtcblx0fSBjYXRjaCAoZSkge1xuXHRcdGNvbnNvbGUuZXJyb3IoZSk7XG5cdH1cblxuXHQvLyBJbml0aWFsaXNlIHRoZSBiaW5kaW5ncyBtYXBcblx0d2luZG93LmdvID0gd2luZG93LmdvIHx8IHt9O1xuXG5cdC8vIEl0ZXJhdGUgcGFja2FnZSBuYW1lc1xuXHRPYmplY3Qua2V5cyhiaW5kaW5nc01hcCkuZm9yRWFjaCgocGFja2FnZU5hbWUpID0+IHtcblxuXHRcdC8vIENyZWF0ZSBpbm5lciBtYXAgaWYgaXQgZG9lc24ndCBleGlzdFxuXHRcdHdpbmRvdy5nb1twYWNrYWdlTmFtZV0gPSB3aW5kb3cuZ29bcGFja2FnZU5hbWVdIHx8IHt9O1xuXG5cdFx0Ly8gSXRlcmF0ZSBzdHJ1Y3QgbmFtZXNcblx0XHRPYmplY3Qua2V5cyhiaW5kaW5nc01hcFtwYWNrYWdlTmFtZV0pLmZvckVhY2goKHN0cnVjdE5hbWUpID0+IHtcblxuXHRcdFx0Ly8gQ3JlYXRlIGlubmVyIG1hcCBpZiBpdCBkb2Vzbid0IGV4aXN0XG5cdFx0XHR3aW5kb3cuZ29bcGFja2FnZU5hbWVdW3N0cnVjdE5hbWVdID0gd2luZG93LmdvW3BhY2thZ2VOYW1lXVtzdHJ1Y3ROYW1lXSB8fCB7fTtcblxuXHRcdFx0T2JqZWN0LmtleXMoYmluZGluZ3NNYXBbcGFja2FnZU5hbWVdW3N0cnVjdE5hbWVdKS5mb3JFYWNoKChtZXRob2ROYW1lKSA9PiB7XG5cblx0XHRcdFx0d2luZG93LmdvW3BhY2thZ2VOYW1lXVtzdHJ1Y3ROYW1lXVttZXRob2ROYW1lXSA9IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0XHRcdC8vIE5vIHRpbWVvdXQgYnkgZGVmYXVsdFxuXHRcdFx0XHRcdGxldCB0aW1lb3V0ID0gMDtcblxuXHRcdFx0XHRcdC8vIEFjdHVhbCBmdW5jdGlvblxuXHRcdFx0XHRcdGZ1bmN0aW9uIGR5bmFtaWMoKSB7XG5cdFx0XHRcdFx0XHRjb25zdCBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuXHRcdFx0XHRcdFx0cmV0dXJuIENhbGwoW3BhY2thZ2VOYW1lLCBzdHJ1Y3ROYW1lLCBtZXRob2ROYW1lXS5qb2luKCcuJyksIGFyZ3MsIHRpbWVvdXQpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIEFsbG93IHNldHRpbmcgdGltZW91dCB0byBmdW5jdGlvblxuXHRcdFx0XHRcdGR5bmFtaWMuc2V0VGltZW91dCA9IGZ1bmN0aW9uIChuZXdUaW1lb3V0KSB7XG5cdFx0XHRcdFx0XHR0aW1lb3V0ID0gbmV3VGltZW91dDtcblx0XHRcdFx0XHR9O1xuXG5cdFx0XHRcdFx0Ly8gQWxsb3cgZ2V0dGluZyB0aW1lb3V0IHRvIGZ1bmN0aW9uXG5cdFx0XHRcdFx0ZHluYW1pYy5nZXRUaW1lb3V0ID0gZnVuY3Rpb24gKCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRpbWVvdXQ7XG5cdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdHJldHVybiBkeW5hbWljO1xuXHRcdFx0XHR9KCk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fSk7XG59XG4iLCAiLypcbiBfXHQgICBfX1x0ICBfIF9fXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG5cbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cblxuXG5pbXBvcnQge0NhbGx9IGZyb20gXCIuL2NhbGxzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dSZWxvYWQoKSB7XG4gICAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gV2luZG93UmVsb2FkQXBwKCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV1InKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1NldFN5c3RlbURlZmF1bHRUaGVtZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dBU0RUJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRMaWdodFRoZW1lKCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV0FMVCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2V0RGFya1RoZW1lKCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV0FEVCcpO1xufVxuXG4vKipcbiAqIFBsYWNlIHRoZSB3aW5kb3cgaW4gdGhlIGNlbnRlciBvZiB0aGUgc2NyZWVuXG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93Q2VudGVyKCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV2MnKTtcbn1cblxuLyoqXG4gKiBTZXRzIHRoZSB3aW5kb3cgdGl0bGVcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGl0bGVcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1NldFRpdGxlKHRpdGxlKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXVCcgKyB0aXRsZSk7XG59XG5cbi8qKlxuICogTWFrZXMgdGhlIHdpbmRvdyBnbyBmdWxsc2NyZWVuXG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93RnVsbHNjcmVlbigpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dGJyk7XG59XG5cbi8qKlxuICogUmV2ZXJ0cyB0aGUgd2luZG93IGZyb20gZnVsbHNjcmVlblxuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1VuZnVsbHNjcmVlbigpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dmJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3RhdGUgb2YgdGhlIHdpbmRvdywgaS5lLiB3aGV0aGVyIHRoZSB3aW5kb3cgaXMgaW4gZnVsbCBzY3JlZW4gbW9kZSBvciBub3QuXG4gKlxuICogQGV4cG9ydFxuICogQHJldHVybiB7UHJvbWlzZTxib29sZWFuPn0gVGhlIHN0YXRlIG9mIHRoZSB3aW5kb3dcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd0lzRnVsbHNjcmVlbigpIHtcbiAgICByZXR1cm4gQ2FsbChcIjp3YWlsczpXaW5kb3dJc0Z1bGxzY3JlZW5cIik7XG59XG5cbi8qKlxuICogU2V0IHRoZSBTaXplIG9mIHRoZSB3aW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGhcbiAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1NldFNpemUod2lkdGgsIGhlaWdodCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV3M6JyArIHdpZHRoICsgJzonICsgaGVpZ2h0KTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIFNpemUgb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEByZXR1cm4ge1Byb21pc2U8e3c6IG51bWJlciwgaDogbnVtYmVyfT59IFRoZSBzaXplIG9mIHRoZSB3aW5kb3dcblxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93R2V0U2l6ZSgpIHtcbiAgICByZXR1cm4gQ2FsbChcIjp3YWlsczpXaW5kb3dHZXRTaXplXCIpO1xufVxuXG4vKipcbiAqIFNldCB0aGUgbWF4aW11bSBzaXplIG9mIHRoZSB3aW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGhcbiAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1NldE1heFNpemUod2lkdGgsIGhlaWdodCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV1o6JyArIHdpZHRoICsgJzonICsgaGVpZ2h0KTtcbn1cblxuLyoqXG4gKiBTZXQgdGhlIG1pbmltdW0gc2l6ZSBvZiB0aGUgd2luZG93XG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoXG4gKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRNaW5TaXplKHdpZHRoLCBoZWlnaHQpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1d6OicgKyB3aWR0aCArICc6JyArIGhlaWdodCk7XG59XG5cblxuXG4vKipcbiAqIFNldCB0aGUgd2luZG93IEFsd2F5c09uVG9wIG9yIG5vdCBvbiB0b3BcbiAqXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRBbHdheXNPblRvcChiKSB7XG5cbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dBVFA6JyArIChiID8gJzEnIDogJzAnKSk7XG59XG5cblxuXG5cbi8qKlxuICogU2V0IHRoZSBQb3NpdGlvbiBvZiB0aGUgd2luZG93XG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IHhcbiAqIEBwYXJhbSB7bnVtYmVyfSB5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dTZXRQb3NpdGlvbih4LCB5KSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXcDonICsgeCArICc6JyArIHkpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgUG9zaXRpb24gb2YgdGhlIHdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqIEByZXR1cm4ge1Byb21pc2U8e3g6IG51bWJlciwgeTogbnVtYmVyfT59IFRoZSBwb3NpdGlvbiBvZiB0aGUgd2luZG93XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dHZXRQb3NpdGlvbigpIHtcbiAgICByZXR1cm4gQ2FsbChcIjp3YWlsczpXaW5kb3dHZXRQb3NcIik7XG59XG5cbi8qKlxuICogSGlkZSB0aGUgV2luZG93XG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93SGlkZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dIJyk7XG59XG5cbi8qKlxuICogU2hvdyB0aGUgV2luZG93XG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93U2hvdygpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dTJyk7XG59XG5cbi8qKlxuICogTWF4aW1pc2UgdGhlIFdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd01heGltaXNlKCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV00nKTtcbn1cblxuLyoqXG4gKiBUb2dnbGUgdGhlIE1heGltaXNlIG9mIHRoZSBXaW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dUb2dnbGVNYXhpbWlzZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1d0Jyk7XG59XG5cbi8qKlxuICogVW5tYXhpbWlzZSB0aGUgV2luZG93XG4gKlxuICogQGV4cG9ydFxuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93VW5tYXhpbWlzZSgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1dVJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3RhdGUgb2YgdGhlIHdpbmRvdywgaS5lLiB3aGV0aGVyIHRoZSB3aW5kb3cgaXMgbWF4aW1pc2VkIG9yIG5vdC5cbiAqXG4gKiBAZXhwb3J0XG4gKiBAcmV0dXJuIHtQcm9taXNlPGJvb2xlYW4+fSBUaGUgc3RhdGUgb2YgdGhlIHdpbmRvd1xuICovXG5leHBvcnQgZnVuY3Rpb24gV2luZG93SXNNYXhpbWlzZWQoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6V2luZG93SXNNYXhpbWlzZWRcIik7XG59XG5cbi8qKlxuICogTWluaW1pc2UgdGhlIFdpbmRvd1xuICpcbiAqIEBleHBvcnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd01pbmltaXNlKCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV20nKTtcbn1cblxuLyoqXG4gKiBVbm1pbmltaXNlIHRoZSBXaW5kb3dcbiAqXG4gKiBAZXhwb3J0XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dVbm1pbmltaXNlKCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnV3UnKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzdGF0ZSBvZiB0aGUgd2luZG93LCBpLmUuIHdoZXRoZXIgdGhlIHdpbmRvdyBpcyBtaW5pbWlzZWQgb3Igbm90LlxuICpcbiAqIEBleHBvcnRcbiAqIEByZXR1cm4ge1Byb21pc2U8Ym9vbGVhbj59IFRoZSBzdGF0ZSBvZiB0aGUgd2luZG93XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dJc01pbmltaXNlZCgpIHtcbiAgICByZXR1cm4gQ2FsbChcIjp3YWlsczpXaW5kb3dJc01pbmltaXNlZFwiKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzdGF0ZSBvZiB0aGUgd2luZG93LCBpLmUuIHdoZXRoZXIgdGhlIHdpbmRvdyBpcyBub3JtYWwgb3Igbm90LlxuICpcbiAqIEBleHBvcnRcbiAqIEByZXR1cm4ge1Byb21pc2U8Ym9vbGVhbj59IFRoZSBzdGF0ZSBvZiB0aGUgd2luZG93XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBXaW5kb3dJc05vcm1hbCgpIHtcbiAgICByZXR1cm4gQ2FsbChcIjp3YWlsczpXaW5kb3dJc05vcm1hbFwiKTtcbn1cblxuLyoqXG4gKiBTZXRzIHRoZSBiYWNrZ3JvdW5kIGNvbG91ciBvZiB0aGUgd2luZG93XG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtudW1iZXJ9IFIgUmVkXG4gKiBAcGFyYW0ge251bWJlcn0gRyBHcmVlblxuICogQHBhcmFtIHtudW1iZXJ9IEIgQmx1ZVxuICogQHBhcmFtIHtudW1iZXJ9IEEgQWxwaGFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIFdpbmRvd1NldEJhY2tncm91bmRDb2xvdXIoUiwgRywgQiwgQSkge1xuICAgIGxldCByZ2JhID0gSlNPTi5zdHJpbmdpZnkoe3I6IFIgfHwgMCwgZzogRyB8fCAwLCBiOiBCIHx8IDAsIGE6IEEgfHwgMjU1fSk7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdXcjonICsgcmdiYSk7XG59XG5cbiIsICIvKlxuIF9cdCAgIF9fXHQgIF8gX19cbnwgfFx0IC8gL19fXyBfKF8pIC9fX19fXG58IHwgL3wgLyAvIF9fIGAvIC8gLyBfX18vXG58IHwvIHwvIC8gL18vIC8gLyAoX18gIClcbnxfXy98X18vXFxfXyxfL18vXy9fX19fL1xuVGhlIGVsZWN0cm9uIGFsdGVybmF0aXZlIGZvciBHb1xuKGMpIExlYSBBbnRob255IDIwMTktcHJlc2VudFxuKi9cblxuLyoganNoaW50IGVzdmVyc2lvbjogOSAqL1xuXG5cbmltcG9ydCB7Q2FsbH0gZnJvbSBcIi4vY2FsbHNcIjtcblxuXG4vKipcbiAqIEdldHMgdGhlIGFsbCBzY3JlZW5zLiBDYWxsIHRoaXMgYW5ldyBlYWNoIHRpbWUgeW91IHdhbnQgdG8gcmVmcmVzaCBkYXRhIGZyb20gdGhlIHVuZGVybHlpbmcgd2luZG93aW5nIHN5c3RlbS5cbiAqIEBleHBvcnRcbiAqIEB0eXBlZGVmIHtpbXBvcnQoJy4uL3dyYXBwZXIvcnVudGltZScpLlNjcmVlbn0gU2NyZWVuXG4gKiBAcmV0dXJuIHtQcm9taXNlPHtTY3JlZW5bXX0+fSBUaGUgc2NyZWVuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gU2NyZWVuR2V0QWxsKCkge1xuICAgIHJldHVybiBDYWxsKFwiOndhaWxzOlNjcmVlbkdldEFsbFwiKTtcbn1cbiIsICIvKipcbiAqIEBkZXNjcmlwdGlvbjogVXNlIHRoZSBzeXN0ZW0gZGVmYXVsdCBicm93c2VyIHRvIG9wZW4gdGhlIHVybFxuICogQHBhcmFtIHtzdHJpbmd9IHVybCBcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBCcm93c2VyT3BlblVSTCh1cmwpIHtcbiAgd2luZG93LldhaWxzSW52b2tlKCdCTzonICsgdXJsKTtcbn0iLCAiLypcbiBfXHQgICBfX1x0ICBfIF9fXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG5cbi8qIGpzaGludCBlc3ZlcnNpb246IDkgKi9cblxuaW1wb3J0IHtDYWxsfSBmcm9tIFwiLi9jYWxsc1wiO1xuXG4vKipcbiAqIFNldCB0aGUgU2l6ZSBvZiB0aGUgd2luZG93XG4gKlxuICogQGV4cG9ydFxuICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIENsaXBib2FyZFNldFRleHQodGV4dCkge1xuICAgIHJldHVybiBDYWxsKFwiOndhaWxzOkNsaXBib2FyZFNldFRleHRcIiwgW3RleHRdKTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIHRleHQgY29udGVudCBvZiB0aGUgY2xpcGJvYXJkXG4gKlxuICogQGV4cG9ydFxuICogQHJldHVybiB7UHJvbWlzZTx7c3RyaW5nfT59IFRleHQgY29udGVudCBvZiB0aGUgY2xpcGJvYXJkXG5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIENsaXBib2FyZEdldFRleHQoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6Q2xpcGJvYXJkR2V0VGV4dFwiKTtcbn0iLCAiLypcbi0tZGVmYXVsdC1jb250ZXh0bWVudTogYXV0bzsgKGRlZmF1bHQpIHdpbGwgc2hvdyB0aGUgZGVmYXVsdCBjb250ZXh0IG1lbnUgaWYgY29udGVudEVkaXRhYmxlIGlzIHRydWUgT1IgdGV4dCBoYXMgYmVlbiBzZWxlY3RlZCBPUiBlbGVtZW50IGlzIGlucHV0IG9yIHRleHRhcmVhXG4tLWRlZmF1bHQtY29udGV4dG1lbnU6IHNob3c7IHdpbGwgYWx3YXlzIHNob3cgdGhlIGRlZmF1bHQgY29udGV4dCBtZW51XG4tLWRlZmF1bHQtY29udGV4dG1lbnU6IGhpZGU7IHdpbGwgYWx3YXlzIGhpZGUgdGhlIGRlZmF1bHQgY29udGV4dCBtZW51XG5cblRoaXMgcnVsZSBpcyBpbmhlcml0ZWQgbGlrZSBub3JtYWwgQ1NTIHJ1bGVzLCBzbyBuZXN0aW5nIHdvcmtzIGFzIGV4cGVjdGVkXG4qL1xuZXhwb3J0IGZ1bmN0aW9uIHByb2Nlc3NEZWZhdWx0Q29udGV4dE1lbnUoZXZlbnQpIHtcbiAgICAvLyBQcm9jZXNzIGRlZmF1bHQgY29udGV4dCBtZW51XG4gICAgY29uc3QgZWxlbWVudCA9IGV2ZW50LnRhcmdldDtcbiAgICBjb25zdCBjb21wdXRlZFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG4gICAgY29uc3QgZGVmYXVsdENvbnRleHRNZW51QWN0aW9uID0gY29tcHV0ZWRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKFwiLS1kZWZhdWx0LWNvbnRleHRtZW51XCIpLnRyaW0oKTtcbiAgICBzd2l0Y2ggKGRlZmF1bHRDb250ZXh0TWVudUFjdGlvbikge1xuICAgICAgICBjYXNlIFwic2hvd1wiOlxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBjYXNlIFwiaGlkZVwiOlxuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGNvbnRlbnRFZGl0YWJsZSBpcyB0cnVlXG4gICAgICAgICAgICBpZiAoZWxlbWVudC5pc0NvbnRlbnRFZGl0YWJsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGV4dCBoYXMgYmVlbiBzZWxlY3RlZCBhbmQgYWN0aW9uIGlzIG9uIHRoZSBzZWxlY3RlZCBlbGVtZW50c1xuICAgICAgICAgICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICAgICAgICAgICAgY29uc3QgaGFzU2VsZWN0aW9uID0gKHNlbGVjdGlvbi50b1N0cmluZygpLmxlbmd0aCA+IDApXG4gICAgICAgICAgICBpZiAoaGFzU2VsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxlY3Rpb24ucmFuZ2VDb3VudDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoaSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlY3RzID0gcmFuZ2UuZ2V0Q2xpZW50UmVjdHMoKTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCByZWN0cy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVjdCA9IHJlY3RzW2pdO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQocmVjdC5sZWZ0LCByZWN0LnRvcCkgPT09IGVsZW1lbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBDaGVjayBpZiB0YWduYW1lIGlzIGlucHV0IG9yIHRleHRhcmVhXG4gICAgICAgICAgICBpZiAoZWxlbWVudC50YWdOYW1lID09PSBcIklOUFVUXCIgfHwgZWxlbWVudC50YWdOYW1lID09PSBcIlRFWFRBUkVBXCIpIHtcbiAgICAgICAgICAgICAgICBpZiAoaGFzU2VsZWN0aW9uIHx8ICghZWxlbWVudC5yZWFkT25seSAmJiAhZWxlbWVudC5kaXNhYmxlZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gaGlkZSBkZWZhdWx0IGNvbnRleHQgbWVudVxuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG59XG4iLCAiLypcbiBfXHQgICBfX1x0ICBfIF9fXG58IHxcdCAvIC9fX18gXyhfKSAvX19fX1xufCB8IC98IC8gLyBfXyBgLyAvIC8gX19fL1xufCB8LyB8LyAvIC9fLyAvIC8gKF9fICApXG58X18vfF9fL1xcX18sXy9fL18vX19fXy9cblRoZSBlbGVjdHJvbiBhbHRlcm5hdGl2ZSBmb3IgR29cbihjKSBMZWEgQW50aG9ueSAyMDE5LXByZXNlbnRcbiovXG4vKiBqc2hpbnQgZXN2ZXJzaW9uOiA5ICovXG5pbXBvcnQgKiBhcyBMb2cgZnJvbSAnLi9sb2cnO1xuaW1wb3J0IHtldmVudExpc3RlbmVycywgRXZlbnRzRW1pdCwgRXZlbnRzTm90aWZ5LCBFdmVudHNPZmYsIEV2ZW50c09uLCBFdmVudHNPbmNlLCBFdmVudHNPbk11bHRpcGxlfSBmcm9tICcuL2V2ZW50cyc7XG5pbXBvcnQge0NhbGwsIENhbGxiYWNrLCBjYWxsYmFja3N9IGZyb20gJy4vY2FsbHMnO1xuaW1wb3J0IHtTZXRCaW5kaW5nc30gZnJvbSBcIi4vYmluZGluZ3NcIjtcbmltcG9ydCAqIGFzIFdpbmRvdyBmcm9tIFwiLi93aW5kb3dcIjtcbmltcG9ydCAqIGFzIFNjcmVlbiBmcm9tIFwiLi9zY3JlZW5cIjtcbmltcG9ydCAqIGFzIEJyb3dzZXIgZnJvbSBcIi4vYnJvd3NlclwiO1xuaW1wb3J0ICogYXMgQ2xpcGJvYXJkIGZyb20gXCIuL2NsaXBib2FyZFwiO1xuaW1wb3J0ICogYXMgQ29udGV4dE1lbnUgZnJvbSBcIi4vY29udGV4dG1lbnVcIjtcblxuXG5leHBvcnQgZnVuY3Rpb24gUXVpdCgpIHtcbiAgICB3aW5kb3cuV2FpbHNJbnZva2UoJ1EnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFNob3coKSB7XG4gICAgd2luZG93LldhaWxzSW52b2tlKCdTJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBIaWRlKCkge1xuICAgIHdpbmRvdy5XYWlsc0ludm9rZSgnSCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gRW52aXJvbm1lbnQoKSB7XG4gICAgcmV0dXJuIENhbGwoXCI6d2FpbHM6RW52aXJvbm1lbnRcIik7XG59XG5cbi8vIFRoZSBKUyBydW50aW1lXG53aW5kb3cucnVudGltZSA9IHtcbiAgICAuLi5Mb2csXG4gICAgLi4uV2luZG93LFxuICAgIC4uLkJyb3dzZXIsXG4gICAgLi4uU2NyZWVuLFxuICAgIC4uLkNsaXBib2FyZCxcbiAgICBFdmVudHNPbixcbiAgICBFdmVudHNPbmNlLFxuICAgIEV2ZW50c09uTXVsdGlwbGUsXG4gICAgRXZlbnRzRW1pdCxcbiAgICBFdmVudHNPZmYsXG4gICAgRW52aXJvbm1lbnQsXG4gICAgU2hvdyxcbiAgICBIaWRlLFxuICAgIFF1aXRcbn07XG5cbi8vIEludGVybmFsIHdhaWxzIGVuZHBvaW50c1xud2luZG93LndhaWxzID0ge1xuICAgIENhbGxiYWNrLFxuICAgIEV2ZW50c05vdGlmeSxcbiAgICBTZXRCaW5kaW5ncyxcbiAgICBldmVudExpc3RlbmVycyxcbiAgICBjYWxsYmFja3MsXG4gICAgZmxhZ3M6IHtcbiAgICAgICAgZGlzYWJsZVNjcm9sbGJhckRyYWc6IGZhbHNlLFxuICAgICAgICBkaXNhYmxlRGVmYXVsdENvbnRleHRNZW51OiBmYWxzZSxcbiAgICAgICAgZW5hYmxlUmVzaXplOiBmYWxzZSxcbiAgICAgICAgZGVmYXVsdEN1cnNvcjogbnVsbCxcbiAgICAgICAgYm9yZGVyVGhpY2tuZXNzOiA2LFxuICAgICAgICBzaG91bGREcmFnOiBmYWxzZSxcbiAgICAgICAgZGVmZXJEcmFnVG9Nb3VzZU1vdmU6IHRydWUsXG4gICAgICAgIGNzc0RyYWdQcm9wZXJ0eTogXCItLXdhaWxzLWRyYWdnYWJsZVwiLFxuICAgICAgICBjc3NEcmFnVmFsdWU6IFwiZHJhZ1wiLFxuICAgIH1cbn07XG5cbi8vIFNldCB0aGUgYmluZGluZ3NcbmlmICh3aW5kb3cud2FpbHNiaW5kaW5ncykge1xuICAgIHdpbmRvdy53YWlscy5TZXRCaW5kaW5ncyh3aW5kb3cud2FpbHNiaW5kaW5ncyk7XG4gICAgZGVsZXRlIHdpbmRvdy53YWlscy5TZXRCaW5kaW5ncztcbn1cblxuLy8gKGJvb2wpIFRoaXMgaXMgZXZhbHVhdGVkIGF0IGJ1aWxkIHRpbWUgaW4gcGFja2FnZS5qc29uXG5pZiAoIURFQlVHKSB7XG4gICAgZGVsZXRlIHdpbmRvdy53YWlsc2JpbmRpbmdzO1xufVxuXG5sZXQgZHJhZ1Rlc3QgPSBmdW5jdGlvbiAoZSkge1xuICAgIHZhciB2YWwgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlLnRhcmdldCkuZ2V0UHJvcGVydHlWYWx1ZSh3aW5kb3cud2FpbHMuZmxhZ3MuY3NzRHJhZ1Byb3BlcnR5KTtcbiAgICBpZiAodmFsKSB7XG4gICAgICB2YWwgPSB2YWwudHJpbSgpO1xuICAgIH1cbiAgICBcbiAgICBpZiAodmFsICE9PSB3aW5kb3cud2FpbHMuZmxhZ3MuY3NzRHJhZ1ZhbHVlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoZS5idXR0b25zICE9PSAxKSB7XG4gICAgICAgIC8vIERvIG5vdCBzdGFydCBkcmFnZ2luZyBpZiBub3QgdGhlIHByaW1hcnkgYnV0dG9uIGhhcyBiZWVuIGNsaWNrZWQuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoZS5kZXRhaWwgIT09IDEpIHtcbiAgICAgICAgLy8gRG8gbm90IHN0YXJ0IGRyYWdnaW5nIGlmIG1vcmUgdGhhbiBvbmNlIGhhcyBiZWVuIGNsaWNrZWQsIGUuZy4gd2hlbiBkb3VibGUgY2xpY2tpbmdcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xufTtcblxud2luZG93LndhaWxzLnNldENTU0RyYWdQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKHByb3BlcnR5LCB2YWx1ZSkge1xuICAgIHdpbmRvdy53YWlscy5mbGFncy5jc3NEcmFnUHJvcGVydHkgPSBwcm9wZXJ0eTtcbiAgICB3aW5kb3cud2FpbHMuZmxhZ3MuY3NzRHJhZ1ZhbHVlID0gdmFsdWU7XG59XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCAoZSkgPT4ge1xuXG4gICAgLy8gQ2hlY2sgZm9yIHJlc2l6aW5nXG4gICAgaWYgKHdpbmRvdy53YWlscy5mbGFncy5yZXNpemVFZGdlKSB7XG4gICAgICAgIHdpbmRvdy5XYWlsc0ludm9rZShcInJlc2l6ZTpcIiArIHdpbmRvdy53YWlscy5mbGFncy5yZXNpemVFZGdlKTtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGRyYWdUZXN0KGUpKSB7XG4gICAgICAgIGlmICh3aW5kb3cud2FpbHMuZmxhZ3MuZGlzYWJsZVNjcm9sbGJhckRyYWcpIHtcbiAgICAgICAgICAgIC8vIFRoaXMgY2hlY2tzIGZvciBjbGlja3Mgb24gdGhlIHNjcm9sbCBiYXJcbiAgICAgICAgICAgIGlmIChlLm9mZnNldFggPiBlLnRhcmdldC5jbGllbnRXaWR0aCB8fCBlLm9mZnNldFkgPiBlLnRhcmdldC5jbGllbnRIZWlnaHQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHdpbmRvdy53YWlscy5mbGFncy5kZWZlckRyYWdUb01vdXNlTW92ZSkge1xuICAgICAgICAgICAgd2luZG93LndhaWxzLmZsYWdzLnNob3VsZERyYWcgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICAgICAgICB3aW5kb3cuV2FpbHNJbnZva2UoXCJkcmFnXCIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuICAgICAgICB3aW5kb3cud2FpbHMuZmxhZ3Muc2hvdWxkRHJhZyA9IGZhbHNlO1xuICAgIH1cbn0pO1xuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsICgpID0+IHtcbiAgICB3aW5kb3cud2FpbHMuZmxhZ3Muc2hvdWxkRHJhZyA9IGZhbHNlO1xufSk7XG5cbmZ1bmN0aW9uIHNldFJlc2l6ZShjdXJzb3IpIHtcbiAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yID0gY3Vyc29yIHx8IHdpbmRvdy53YWlscy5mbGFncy5kZWZhdWx0Q3Vyc29yO1xuICAgIHdpbmRvdy53YWlscy5mbGFncy5yZXNpemVFZGdlID0gY3Vyc29yO1xufVxuXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAod2luZG93LndhaWxzLmZsYWdzLnNob3VsZERyYWcpIHtcbiAgICAgICAgd2luZG93LndhaWxzLmZsYWdzLnNob3VsZERyYWcgPSBmYWxzZTtcbiAgICAgICAgbGV0IG1vdXNlUHJlc3NlZCA9IGUuYnV0dG9ucyAhPT0gdW5kZWZpbmVkID8gZS5idXR0b25zIDogZS53aGljaDtcbiAgICAgICAgaWYgKG1vdXNlUHJlc3NlZCA+IDApIHtcbiAgICAgICAgICAgIHdpbmRvdy5XYWlsc0ludm9rZShcImRyYWdcIik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKCF3aW5kb3cud2FpbHMuZmxhZ3MuZW5hYmxlUmVzaXplKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHdpbmRvdy53YWlscy5mbGFncy5kZWZhdWx0Q3Vyc29yID09IG51bGwpIHtcbiAgICAgICAgd2luZG93LndhaWxzLmZsYWdzLmRlZmF1bHRDdXJzb3IgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUuY3Vyc29yO1xuICAgIH1cbiAgICBpZiAod2luZG93Lm91dGVyV2lkdGggLSBlLmNsaWVudFggPCB3aW5kb3cud2FpbHMuZmxhZ3MuYm9yZGVyVGhpY2tuZXNzICYmIHdpbmRvdy5vdXRlckhlaWdodCAtIGUuY2xpZW50WSA8IHdpbmRvdy53YWlscy5mbGFncy5ib3JkZXJUaGlja25lc3MpIHtcbiAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLmN1cnNvciA9IFwic2UtcmVzaXplXCI7XG4gICAgfVxuICAgIGxldCByaWdodEJvcmRlciA9IHdpbmRvdy5vdXRlcldpZHRoIC0gZS5jbGllbnRYIDwgd2luZG93LndhaWxzLmZsYWdzLmJvcmRlclRoaWNrbmVzcztcbiAgICBsZXQgbGVmdEJvcmRlciA9IGUuY2xpZW50WCA8IHdpbmRvdy53YWlscy5mbGFncy5ib3JkZXJUaGlja25lc3M7XG4gICAgbGV0IHRvcEJvcmRlciA9IGUuY2xpZW50WSA8IHdpbmRvdy53YWlscy5mbGFncy5ib3JkZXJUaGlja25lc3M7XG4gICAgbGV0IGJvdHRvbUJvcmRlciA9IHdpbmRvdy5vdXRlckhlaWdodCAtIGUuY2xpZW50WSA8IHdpbmRvdy53YWlscy5mbGFncy5ib3JkZXJUaGlja25lc3M7XG5cbiAgICAvLyBJZiB3ZSBhcmVuJ3Qgb24gYW4gZWRnZSwgYnV0IHdlcmUsIHJlc2V0IHRoZSBjdXJzb3IgdG8gZGVmYXVsdFxuICAgIGlmICghbGVmdEJvcmRlciAmJiAhcmlnaHRCb3JkZXIgJiYgIXRvcEJvcmRlciAmJiAhYm90dG9tQm9yZGVyICYmIHdpbmRvdy53YWlscy5mbGFncy5yZXNpemVFZGdlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc2V0UmVzaXplKCk7XG4gICAgfSBlbHNlIGlmIChyaWdodEJvcmRlciAmJiBib3R0b21Cb3JkZXIpIHNldFJlc2l6ZShcInNlLXJlc2l6ZVwiKTtcbiAgICBlbHNlIGlmIChsZWZ0Qm9yZGVyICYmIGJvdHRvbUJvcmRlcikgc2V0UmVzaXplKFwic3ctcmVzaXplXCIpO1xuICAgIGVsc2UgaWYgKGxlZnRCb3JkZXIgJiYgdG9wQm9yZGVyKSBzZXRSZXNpemUoXCJudy1yZXNpemVcIik7XG4gICAgZWxzZSBpZiAodG9wQm9yZGVyICYmIHJpZ2h0Qm9yZGVyKSBzZXRSZXNpemUoXCJuZS1yZXNpemVcIik7XG4gICAgZWxzZSBpZiAobGVmdEJvcmRlcikgc2V0UmVzaXplKFwidy1yZXNpemVcIik7XG4gICAgZWxzZSBpZiAodG9wQm9yZGVyKSBzZXRSZXNpemUoXCJuLXJlc2l6ZVwiKTtcbiAgICBlbHNlIGlmIChib3R0b21Cb3JkZXIpIHNldFJlc2l6ZShcInMtcmVzaXplXCIpO1xuICAgIGVsc2UgaWYgKHJpZ2h0Qm9yZGVyKSBzZXRSZXNpemUoXCJlLXJlc2l6ZVwiKTtcblxufSk7XG5cbi8vIFNldHVwIGNvbnRleHQgbWVudSBob29rXG53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignY29udGV4dG1lbnUnLCBmdW5jdGlvbiAoZSkge1xuICAgIC8vIGFsd2F5cyBzaG93IHRoZSBjb250ZXh0bWVudSBpbiBkZWJ1ZyAmIGRldlxuICAgIGlmIChERUJVRykgcmV0dXJuO1xuXG4gICAgaWYgKHdpbmRvdy53YWlscy5mbGFncy5kaXNhYmxlRGVmYXVsdENvbnRleHRNZW51KSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBDb250ZXh0TWVudS5wcm9jZXNzRGVmYXVsdENvbnRleHRNZW51KGUpO1xuICAgIH1cbn0pO1xuXG53aW5kb3cuV2FpbHNJbnZva2UoXCJydW50aW1lOnJlYWR5XCIpOyJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7O0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBa0JBLFdBQVMsZUFBZSxPQUFPLFNBQVM7QUFJdkMsV0FBTyxZQUFZLE1BQU0sUUFBUSxPQUFPO0FBQUEsRUFDekM7QUFRTyxXQUFTLFNBQVMsU0FBUztBQUNqQyxtQkFBZSxLQUFLLE9BQU87QUFBQSxFQUM1QjtBQVFPLFdBQVMsU0FBUyxTQUFTO0FBQ2pDLG1CQUFlLEtBQUssT0FBTztBQUFBLEVBQzVCO0FBUU8sV0FBUyxTQUFTLFNBQVM7QUFDakMsbUJBQWUsS0FBSyxPQUFPO0FBQUEsRUFDNUI7QUFRTyxXQUFTLFFBQVEsU0FBUztBQUNoQyxtQkFBZSxLQUFLLE9BQU87QUFBQSxFQUM1QjtBQVFPLFdBQVMsV0FBVyxTQUFTO0FBQ25DLG1CQUFlLEtBQUssT0FBTztBQUFBLEVBQzVCO0FBUU8sV0FBUyxTQUFTLFNBQVM7QUFDakMsbUJBQWUsS0FBSyxPQUFPO0FBQUEsRUFDNUI7QUFRTyxXQUFTLFNBQVMsU0FB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 diff --git a/v2/internal/frontend/runtime/runtime_prod_desktop.js b/v2/internal/frontend/runtime/runtime_prod_desktop.js index a22739c9..9b2f39ff 100644 --- a/v2/internal/frontend/runtime/runtime_prod_desktop.js +++ b/v2/internal/frontend/runtime/runtime_prod_desktop.js @@ -1 +1 @@ -(()=>{var L=Object.defineProperty;var c=(e,n)=>{for(var o in n)L(e,o,{get:n[o],enumerable:!0})};var m={};c(m,{LogDebug:()=>M,LogError:()=>A,LogFatal:()=>H,LogInfo:()=>P,LogLevel:()=>J,LogPrint:()=>R,LogTrace:()=>z,LogWarning:()=>B,SetLogLevel:()=>G});function d(e,n){window.WailsInvoke("L"+e+n)}function z(e){d("T",e)}function R(e){d("P",e)}function M(e){d("D",e)}function P(e){d("I",e)}function B(e){d("W",e)}function A(e){d("E",e)}function H(e){d("F",e)}function G(e){d("S",e)}var J={TRACE:1,DEBUG:2,INFO:3,WARNING:4,ERROR:5};var v=class{constructor(n,o,i){this.eventName=n,this.maxCallbacks=i||-1,this.Callback=t=>(o.apply(null,t),this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0))}},l={};function p(e,n,o){l[e]=l[e]||[];let i=new v(e,n,o);return l[e].push(i),()=>F(i)}function b(e,n){return p(e,n,-1)}function E(e,n){return p(e,n,1)}function S(e){let n=e.name;if(l[n]){let o=l[n].slice();for(let i=l[n].length-1;i>=0;i-=1){let t=l[n][i],r=e.data;t.Callback(r)&&o.splice(i,1)}o.length===0?g(n):l[n]=o}}function y(e){let n;try{n=JSON.parse(e)}catch{let i="Invalid JSON passed to Notify: "+e;throw new Error(i)}S(n)}function D(e){let n={name:e,data:[].slice.apply(arguments).slice(1)};S(n),window.WailsInvoke("EE"+JSON.stringify(n))}function g(e){delete l[e],window.WailsInvoke("EX"+e)}function C(e,...n){g(e),n.length>0&&n.forEach(o=>{g(o)})}function F(e){let n=e.eventName;l[n]=l[n].filter(o=>o!==e),l[n].length===0&&g(n)}var f={};function U(){var e=new Uint32Array(1);return window.crypto.getRandomValues(e)[0]}function j(){return Math.random()*9007199254740991}var W;window.crypto?W=U:W=j;function s(e,n,o){return o==null&&(o=0),new Promise(function(i,t){var r;do r=e+"-"+W();while(f[r]);var a;o>0&&(a=setTimeout(function(){t(Error("Call to "+e+" timed out. Request ID: "+r))},o)),f[r]={timeoutHandle:a,reject:t,resolve:i};try{let u={name:e,args:n,callbackID:r};window.WailsInvoke("C"+JSON.stringify(u))}catch(u){console.error(u)}})}window.ObfuscatedCall=(e,n,o)=>(o==null&&(o=0),new Promise(function(i,t){var r;do r=e+"-"+W();while(f[r]);var a;o>0&&(a=setTimeout(function(){t(Error("Call to method "+e+" timed out. Request ID: "+r))},o)),f[r]={timeoutHandle:a,reject:t,resolve:i};try{let u={id:e,args:n,callbackID:r};window.WailsInvoke("c"+JSON.stringify(u))}catch(u){console.error(u)}}));function T(e){let n;try{n=JSON.parse(e)}catch(t){let r=`Invalid JSON passed to callback: ${t.message}. Message: ${e}`;throw runtime.LogDebug(r),new Error(r)}let o=n.callbackid,i=f[o];if(!i){let t=`Callback '${o}' not registered!!!`;throw console.error(t),new Error(t)}clearTimeout(i.timeoutHandle),delete f[o],n.error?i.reject(n.error):i.resolve(n.result)}window.go={};function O(e){try{e=JSON.parse(e)}catch(n){console.error(n)}window.go=window.go||{},Object.keys(e).forEach(n=>{window.go[n]=window.go[n]||{},Object.keys(e[n]).forEach(o=>{window.go[n][o]=window.go[n][o]||{},Object.keys(e[n][o]).forEach(i=>{window.go[n][o][i]=function(){let t=0;function r(){let a=[].slice.call(arguments);return s([n,o,i].join("."),a,t)}return r.setTimeout=function(a){t=a},r.getTimeout=function(){return t},r}()})})})}var x={};c(x,{WindowCenter:()=>q,WindowFullscreen:()=>Z,WindowGetPosition:()=>se,WindowGetSize:()=>ne,WindowHide:()=>le,WindowIsFullscreen:()=>_,WindowIsMaximised:()=>ue,WindowIsMinimised:()=>pe,WindowIsNormal:()=>We,WindowMaximise:()=>we,WindowMinimise:()=>ce,WindowReload:()=>N,WindowReloadApp:()=>V,WindowSetAlwaysOnTop:()=>te,WindowSetBackgroundColour:()=>me,WindowSetDarkTheme:()=>$,WindowSetLightTheme:()=>Y,WindowSetMaxSize:()=>oe,WindowSetMinSize:()=>ie,WindowSetPosition:()=>re,WindowSetSize:()=>ee,WindowSetSystemDefaultTheme:()=>X,WindowSetTitle:()=>Q,WindowShow:()=>ae,WindowToggleMaximise:()=>de,WindowUnfullscreen:()=>K,WindowUnmaximise:()=>fe,WindowUnminimise:()=>ge});function N(){window.location.reload()}function V(){window.WailsInvoke("WR")}function X(){window.WailsInvoke("WASDT")}function Y(){window.WailsInvoke("WALT")}function $(){window.WailsInvoke("WADT")}function q(){window.WailsInvoke("Wc")}function Q(e){window.WailsInvoke("WT"+e)}function Z(){window.WailsInvoke("WF")}function K(){window.WailsInvoke("Wf")}function _(){return s(":wails:WindowIsFullscreen")}function ee(e,n){window.WailsInvoke("Ws:"+e+":"+n)}function ne(){return s(":wails:WindowGetSize")}function oe(e,n){window.WailsInvoke("WZ:"+e+":"+n)}function ie(e,n){window.WailsInvoke("Wz:"+e+":"+n)}function te(e){window.WailsInvoke("WATP:"+(e?"1":"0"))}function re(e,n){window.WailsInvoke("Wp:"+e+":"+n)}function se(){return s(":wails:WindowGetPos")}function le(){window.WailsInvoke("WH")}function ae(){window.WailsInvoke("WS")}function we(){window.WailsInvoke("WM")}function de(){window.WailsInvoke("Wt")}function fe(){window.WailsInvoke("WU")}function ue(){return s(":wails:WindowIsMaximised")}function ce(){window.WailsInvoke("Wm")}function ge(){window.WailsInvoke("Wu")}function pe(){return s(":wails:WindowIsMinimised")}function We(){return s(":wails:WindowIsNormal")}function me(e,n,o,i){let t=JSON.stringify({r:e||0,g:n||0,b:o||0,a:i||255});window.WailsInvoke("Wr:"+t)}var k={};c(k,{ScreenGetAll:()=>ve});function ve(){return s(":wails:ScreenGetAll")}var h={};c(h,{BrowserOpenURL:()=>xe});function xe(e){window.WailsInvoke("BO:"+e)}var I={};c(I,{ClipboardGetText:()=>he,ClipboardSetText:()=>ke});function ke(e){return s(":wails:ClipboardSetText",[e])}function he(){return s(":wails:ClipboardGetText")}function Ie(){window.WailsInvoke("Q")}function be(){window.WailsInvoke("S")}function Ee(){window.WailsInvoke("H")}function Se(){return s(":wails:Environment")}window.runtime={...m,...x,...h,...k,...I,EventsOn:b,EventsOnce:E,EventsOnMultiple:p,EventsEmit:D,EventsOff:C,Environment:Se,Show:be,Hide:Ee,Quit:Ie};window.wails={Callback:T,EventsNotify:y,SetBindings:O,eventListeners:l,callbacks:f,flags:{disableScrollbarDrag:!1,disableWailsDefaultContextMenu:!1,enableResize:!1,defaultCursor:null,borderThickness:6,shouldDrag:!1,deferDragToMouseMove:!0,cssDragProperty:"--wails-draggable",cssDragValue:"drag"}};window.wailsbindings&&(window.wails.SetBindings(window.wailsbindings),delete window.wails.SetBindings);delete window.wailsbindings;var ye=function(e){var n=window.getComputedStyle(e.target).getPropertyValue(window.wails.flags.cssDragProperty);return n&&(n=n.trim()),!(n!==window.wails.flags.cssDragValue||e.buttons!==1||e.detail!==1)};window.wails.setCSSDragProperties=function(e,n){window.wails.flags.cssDragProperty=e,window.wails.flags.cssDragValue=n};window.addEventListener("mousedown",e=>{if(window.wails.flags.resizeEdge){window.WailsInvoke("resize:"+window.wails.flags.resizeEdge),e.preventDefault();return}if(ye(e)){if(window.wails.flags.disableScrollbarDrag&&(e.offsetX>e.target.clientWidth||e.offsetY>e.target.clientHeight))return;window.wails.flags.deferDragToMouseMove?window.wails.flags.shouldDrag=!0:(e.preventDefault(),window.WailsInvoke("drag"));return}else window.wails.flags.shouldDrag=!1});window.addEventListener("mouseup",()=>{window.wails.flags.shouldDrag=!1});function w(e){document.documentElement.style.cursor=e||window.wails.flags.defaultCursor,window.wails.flags.resizeEdge=e}window.addEventListener("mousemove",function(e){if(window.wails.flags.shouldDrag&&(window.wails.flags.shouldDrag=!1,(e.buttons!==void 0?e.buttons:e.which)>0)){window.WailsInvoke("drag");return}if(!window.wails.flags.enableResize)return;window.wails.flags.defaultCursor==null&&(window.wails.flags.defaultCursor=document.documentElement.style.cursor),window.outerWidth-e.clientX{var P=Object.defineProperty;var c=(e,n)=>{for(var o in n)P(e,o,{get:n[o],enumerable:!0})};var x={};c(x,{LogDebug:()=>G,LogError:()=>F,LogFatal:()=>J,LogInfo:()=>H,LogLevel:()=>j,LogPrint:()=>B,LogTrace:()=>A,LogWarning:()=>U,SetLogLevel:()=>N});function f(e,n){window.WailsInvoke("L"+e+n)}function A(e){f("T",e)}function B(e){f("P",e)}function G(e){f("D",e)}function H(e){f("I",e)}function U(e){f("W",e)}function F(e){f("E",e)}function J(e){f("F",e)}function N(e){f("S",e)}var j={TRACE:1,DEBUG:2,INFO:3,WARNING:4,ERROR:5};var v=class{constructor(n,o,t){this.eventName=n,this.maxCallbacks=t||-1,this.Callback=i=>(o.apply(null,i),this.maxCallbacks===-1?!1:(this.maxCallbacks-=1,this.maxCallbacks===0))}},a={};function p(e,n,o){a[e]=a[e]||[];let t=new v(e,n,o);return a[e].push(t),()=>V(t)}function y(e,n){return p(e,n,-1)}function C(e,n){return p(e,n,1)}function D(e){let n=e.name;if(a[n]){let o=a[n].slice();for(let t=a[n].length-1;t>=0;t-=1){let i=a[n][t],r=e.data;i.Callback(r)&&o.splice(t,1)}o.length===0?g(n):a[n]=o}}function T(e){let n;try{n=JSON.parse(e)}catch{let t="Invalid JSON passed to Notify: "+e;throw new Error(t)}D(n)}function O(e){let n={name:e,data:[].slice.apply(arguments).slice(1)};D(n),window.WailsInvoke("EE"+JSON.stringify(n))}function g(e){delete a[e],window.WailsInvoke("EX"+e)}function L(e,...n){g(e),n.length>0&&n.forEach(o=>{g(o)})}function V(e){let n=e.eventName;a[n]=a[n].filter(o=>o!==e),a[n].length===0&&g(n)}var u={};function X(){var e=new Uint32Array(1);return window.crypto.getRandomValues(e)[0]}function Y(){return Math.random()*9007199254740991}var W;window.crypto?W=X:W=Y;function s(e,n,o){return o==null&&(o=0),new Promise(function(t,i){var r;do r=e+"-"+W();while(u[r]);var l;o>0&&(l=setTimeout(function(){i(Error("Call to "+e+" timed out. Request ID: "+r))},o)),u[r]={timeoutHandle:l,reject:i,resolve:t};try{let d={name:e,args:n,callbackID:r};window.WailsInvoke("C"+JSON.stringify(d))}catch(d){console.error(d)}})}window.ObfuscatedCall=(e,n,o)=>(o==null&&(o=0),new Promise(function(t,i){var r;do r=e+"-"+W();while(u[r]);var l;o>0&&(l=setTimeout(function(){i(Error("Call to method "+e+" timed out. Request ID: "+r))},o)),u[r]={timeoutHandle:l,reject:i,resolve:t};try{let d={id:e,args:n,callbackID:r};window.WailsInvoke("c"+JSON.stringify(d))}catch(d){console.error(d)}}));function z(e){let n;try{n=JSON.parse(e)}catch(i){let r=`Invalid JSON passed to callback: ${i.message}. Message: ${e}`;throw runtime.LogDebug(r),new Error(r)}let o=n.callbackid,t=u[o];if(!t){let i=`Callback '${o}' not registered!!!`;throw console.error(i),new Error(i)}clearTimeout(t.timeoutHandle),delete u[o],n.error?t.reject(n.error):t.resolve(n.result)}window.go={};function M(e){try{e=JSON.parse(e)}catch(n){console.error(n)}window.go=window.go||{},Object.keys(e).forEach(n=>{window.go[n]=window.go[n]||{},Object.keys(e[n]).forEach(o=>{window.go[n][o]=window.go[n][o]||{},Object.keys(e[n][o]).forEach(t=>{window.go[n][o][t]=function(){let i=0;function r(){let l=[].slice.call(arguments);return s([n,o,t].join("."),l,i)}return r.setTimeout=function(l){i=l},r.getTimeout=function(){return i},r}()})})})}var h={};c(h,{WindowCenter:()=>_,WindowFullscreen:()=>ne,WindowGetPosition:()=>de,WindowGetSize:()=>re,WindowHide:()=>fe,WindowIsFullscreen:()=>te,WindowIsMaximised:()=>We,WindowIsMinimised:()=>ve,WindowIsNormal:()=>he,WindowMaximise:()=>ce,WindowMinimise:()=>me,WindowReload:()=>$,WindowReloadApp:()=>q,WindowSetAlwaysOnTop:()=>ae,WindowSetBackgroundColour:()=>ke,WindowSetDarkTheme:()=>K,WindowSetLightTheme:()=>Z,WindowSetMaxSize:()=>se,WindowSetMinSize:()=>le,WindowSetPosition:()=>we,WindowSetSize:()=>ie,WindowSetSystemDefaultTheme:()=>Q,WindowSetTitle:()=>ee,WindowShow:()=>ue,WindowToggleMaximise:()=>ge,WindowUnfullscreen:()=>oe,WindowUnmaximise:()=>pe,WindowUnminimise:()=>xe});function $(){window.location.reload()}function q(){window.WailsInvoke("WR")}function Q(){window.WailsInvoke("WASDT")}function Z(){window.WailsInvoke("WALT")}function K(){window.WailsInvoke("WADT")}function _(){window.WailsInvoke("Wc")}function ee(e){window.WailsInvoke("WT"+e)}function ne(){window.WailsInvoke("WF")}function oe(){window.WailsInvoke("Wf")}function te(){return s(":wails:WindowIsFullscreen")}function ie(e,n){window.WailsInvoke("Ws:"+e+":"+n)}function re(){return s(":wails:WindowGetSize")}function se(e,n){window.WailsInvoke("WZ:"+e+":"+n)}function le(e,n){window.WailsInvoke("Wz:"+e+":"+n)}function ae(e){window.WailsInvoke("WATP:"+(e?"1":"0"))}function we(e,n){window.WailsInvoke("Wp:"+e+":"+n)}function de(){return s(":wails:WindowGetPos")}function fe(){window.WailsInvoke("WH")}function ue(){window.WailsInvoke("WS")}function ce(){window.WailsInvoke("WM")}function ge(){window.WailsInvoke("Wt")}function pe(){window.WailsInvoke("WU")}function We(){return s(":wails:WindowIsMaximised")}function me(){window.WailsInvoke("Wm")}function xe(){window.WailsInvoke("Wu")}function ve(){return s(":wails:WindowIsMinimised")}function he(){return s(":wails:WindowIsNormal")}function ke(e,n,o,t){let i=JSON.stringify({r:e||0,g:n||0,b:o||0,a:t||255});window.WailsInvoke("Wr:"+i)}var k={};c(k,{ScreenGetAll:()=>Ie});function Ie(){return s(":wails:ScreenGetAll")}var I={};c(I,{BrowserOpenURL:()=>be});function be(e){window.WailsInvoke("BO:"+e)}var b={};c(b,{ClipboardGetText:()=>Ee,ClipboardSetText:()=>Se});function Se(e){return s(":wails:ClipboardSetText",[e])}function Ee(){return s(":wails:ClipboardGetText")}function R(e){let n=e.target;switch(window.getComputedStyle(n).getPropertyValue("--default-contextmenu").trim()){case"show":return;case"hide":e.preventDefault();return;default:if(n.isContentEditable)return;let i=window.getSelection(),r=i.toString().length>0;if(r)for(let l=0;l{if(window.wails.flags.resizeEdge){window.WailsInvoke("resize:"+window.wails.flags.resizeEdge),e.preventDefault();return}if(Le(e)){if(window.wails.flags.disableScrollbarDrag&&(e.offsetX>e.target.clientWidth||e.offsetY>e.target.clientHeight))return;window.wails.flags.deferDragToMouseMove?window.wails.flags.shouldDrag=!0:(e.preventDefault(),window.WailsInvoke("drag"));return}else window.wails.flags.shouldDrag=!1});window.addEventListener("mouseup",()=>{window.wails.flags.shouldDrag=!1});function w(e){document.documentElement.style.cursor=e||window.wails.flags.defaultCursor,window.wails.flags.resizeEdge=e}window.addEventListener("mousemove",function(e){if(window.wails.flags.shouldDrag&&(window.wails.flags.shouldDrag=!1,(e.buttons!==void 0?e.buttons:e.which)>0)){window.WailsInvoke("drag");return}if(!window.wails.flags.enableResize)return;window.wails.flags.defaultCursor==null&&(window.wails.flags.defaultCursor=document.documentElement.style.cursor),window.outerWidth-e.clientX contentEditable is true OR text has been selected OR element is input or textarea | +| `--default-contextmenu: show;` | will always show the default context menu | +| `--default-contextmenu: hide;` | will always hide the default context menu | + +This rule is inherited like any normal CSS rule, so nesting works as expected. + +:::note +This filtering functionality is only enabled in production, so in development and in debug build, the full context-menu is always available everywhere. +::: + +:::warning +This filtering functionality is NOT a security measure, the developer should expect that the full context-menu could be leaked anytime which could contain commands like (Download image, Reload, Save webpage), if this is a concern, the developer SHOULD NOT enable the default context-menu. +::: + Name: EnableDefaultContextMenu
Type: `bool` diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 43b1bf08..f82f2fd5 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `-devtools` production build flag. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2725) - Added `EnableDefaultContextMenu` option to allow enabling the browser's default context-menu in production . Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2733) +- Added smart functionality for the default context-menu in production with CSS styles to control it. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2748) ### Changed From f150d251520c0a4acd2b8f45e4d49949443bda72 Mon Sep 17 00:00:00 2001 From: Marcus Crane Date: Thu, 6 Jul 2023 22:51:40 +1200 Subject: [PATCH 19/36] Update October showcase image (#2762) --- website/static/img/showcase/october.webp | Bin 71756 -> 39314 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/website/static/img/showcase/october.webp b/website/static/img/showcase/october.webp index e731189a47ebe2a28cc6b6aa3617426636a4b2cf..98e620c3bcf66751ce59c72e40aa0e5b865f22d0 100644 GIT binary patch literal 39314 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
fB)d#BEfR=v-e6qcJKb6s65+Sc*(kJ>#o+N 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 VMc@xrW literal 71756 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�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 Date: Tue, 11 Jul 2023 05:27:41 +1000 Subject: [PATCH 20/36] [v2 templates] Add explicit style import (#2721) * [v2 templates] Add explicit style import * [v2] Remove style import --- v2/pkg/templates/generate/assets/lit-ts/frontend/index.tmpl.html | 1 - v2/pkg/templates/generate/assets/lit/frontend/index.tmpl.html | 1 - .../templates/generate/assets/svelte-ts/frontend/index.tmpl.html | 1 - v2/pkg/templates/generate/assets/vue-ts/frontend/index.tmpl.html | 1 - v2/pkg/templates/generate/assets/vue/frontend/index.tmpl.html | 1 - v2/pkg/templates/templates/lit-ts/frontend/index.tmpl.html | 1 - v2/pkg/templates/templates/lit-ts/frontend/src/my-element.ts | 1 + v2/pkg/templates/templates/lit/frontend/index.tmpl.html | 1 - v2/pkg/templates/templates/lit/frontend/src/my-element.js | 1 + v2/pkg/templates/templates/plain/frontend/src/main.js | 1 + v2/pkg/templates/templates/svelte-ts/frontend/index.tmpl.html | 1 - v2/pkg/templates/templates/vue-ts/frontend/index.tmpl.html | 1 - v2/pkg/templates/templates/vue-ts/frontend/src/main.ts | 1 + v2/pkg/templates/templates/vue/frontend/index.tmpl.html | 1 - v2/pkg/templates/templates/vue/frontend/src/main.js | 1 + 15 files changed, 5 insertions(+), 10 deletions(-) diff --git a/v2/pkg/templates/generate/assets/lit-ts/frontend/index.tmpl.html b/v2/pkg/templates/generate/assets/lit-ts/frontend/index.tmpl.html index 4944992b..febcb76c 100644 --- a/v2/pkg/templates/generate/assets/lit-ts/frontend/index.tmpl.html +++ b/v2/pkg/templates/generate/assets/lit-ts/frontend/index.tmpl.html @@ -4,7 +4,6 @@ {{.ProjectName}} - diff --git a/v2/pkg/templates/generate/assets/lit/frontend/index.tmpl.html b/v2/pkg/templates/generate/assets/lit/frontend/index.tmpl.html index e2db01c7..fbe3eb24 100644 --- a/v2/pkg/templates/generate/assets/lit/frontend/index.tmpl.html +++ b/v2/pkg/templates/generate/assets/lit/frontend/index.tmpl.html @@ -4,7 +4,6 @@ {{.ProjectName}} - diff --git a/v2/pkg/templates/generate/assets/svelte-ts/frontend/index.tmpl.html b/v2/pkg/templates/generate/assets/svelte-ts/frontend/index.tmpl.html index e88b655e..3dd212f2 100644 --- a/v2/pkg/templates/generate/assets/svelte-ts/frontend/index.tmpl.html +++ b/v2/pkg/templates/generate/assets/svelte-ts/frontend/index.tmpl.html @@ -3,7 +3,6 @@ - {{.ProjectName}} diff --git a/v2/pkg/templates/generate/assets/vue-ts/frontend/index.tmpl.html b/v2/pkg/templates/generate/assets/vue-ts/frontend/index.tmpl.html index 5c0949b5..cc259435 100644 --- a/v2/pkg/templates/generate/assets/vue-ts/frontend/index.tmpl.html +++ b/v2/pkg/templates/generate/assets/vue-ts/frontend/index.tmpl.html @@ -4,7 +4,6 @@ {{.ProjectName}} -

diff --git a/v2/pkg/templates/generate/assets/vue/frontend/index.tmpl.html b/v2/pkg/templates/generate/assets/vue/frontend/index.tmpl.html index b3d4289c..d45b7a8c 100644 --- a/v2/pkg/templates/generate/assets/vue/frontend/index.tmpl.html +++ b/v2/pkg/templates/generate/assets/vue/frontend/index.tmpl.html @@ -4,7 +4,6 @@ {{.ProjectName}} -
diff --git a/v2/pkg/templates/templates/lit-ts/frontend/index.tmpl.html b/v2/pkg/templates/templates/lit-ts/frontend/index.tmpl.html index 4944992b..febcb76c 100644 --- a/v2/pkg/templates/templates/lit-ts/frontend/index.tmpl.html +++ b/v2/pkg/templates/templates/lit-ts/frontend/index.tmpl.html @@ -4,7 +4,6 @@ {{.ProjectName}} - diff --git a/v2/pkg/templates/templates/lit-ts/frontend/src/my-element.ts b/v2/pkg/templates/templates/lit-ts/frontend/src/my-element.ts index 27fd71e4..af4e9ce2 100644 --- a/v2/pkg/templates/templates/lit-ts/frontend/src/my-element.ts +++ b/v2/pkg/templates/templates/lit-ts/frontend/src/my-element.ts @@ -2,6 +2,7 @@ import {css, html, LitElement} from 'lit' import logo from './assets/images/logo-universal.png' import {Greet} from "../wailsjs/go/main/App"; import {customElement, property} from 'lit/decorators.js' +import './style.css'; /** * An example element. diff --git a/v2/pkg/templates/templates/lit/frontend/index.tmpl.html b/v2/pkg/templates/templates/lit/frontend/index.tmpl.html index e2db01c7..fbe3eb24 100644 --- a/v2/pkg/templates/templates/lit/frontend/index.tmpl.html +++ b/v2/pkg/templates/templates/lit/frontend/index.tmpl.html @@ -4,7 +4,6 @@ {{.ProjectName}} - diff --git a/v2/pkg/templates/templates/lit/frontend/src/my-element.js b/v2/pkg/templates/templates/lit/frontend/src/my-element.js index ed65e222..017632c0 100644 --- a/v2/pkg/templates/templates/lit/frontend/src/my-element.js +++ b/v2/pkg/templates/templates/lit/frontend/src/my-element.js @@ -1,6 +1,7 @@ import {css, html, LitElement} from 'lit' import logo from './assets/images/logo-universal.png' import {Greet} from "../wailsjs/go/main/App"; +import './style.css'; /** * An example element. diff --git a/v2/pkg/templates/templates/plain/frontend/src/main.js b/v2/pkg/templates/templates/plain/frontend/src/main.js index 3346d59f..e4945441 100644 --- a/v2/pkg/templates/templates/plain/frontend/src/main.js +++ b/v2/pkg/templates/templates/plain/frontend/src/main.js @@ -1,6 +1,7 @@ // Get input + focus let nameElement = document.getElementById("name"); nameElement.focus(); +import './main.css'; // Setup the greet function window.greet = function () { diff --git a/v2/pkg/templates/templates/svelte-ts/frontend/index.tmpl.html b/v2/pkg/templates/templates/svelte-ts/frontend/index.tmpl.html index e88b655e..3dd212f2 100644 --- a/v2/pkg/templates/templates/svelte-ts/frontend/index.tmpl.html +++ b/v2/pkg/templates/templates/svelte-ts/frontend/index.tmpl.html @@ -3,7 +3,6 @@ - {{.ProjectName}} diff --git a/v2/pkg/templates/templates/vue-ts/frontend/index.tmpl.html b/v2/pkg/templates/templates/vue-ts/frontend/index.tmpl.html index 5c0949b5..cc259435 100644 --- a/v2/pkg/templates/templates/vue-ts/frontend/index.tmpl.html +++ b/v2/pkg/templates/templates/vue-ts/frontend/index.tmpl.html @@ -4,7 +4,6 @@ {{.ProjectName}} -
diff --git a/v2/pkg/templates/templates/vue-ts/frontend/src/main.ts b/v2/pkg/templates/templates/vue-ts/frontend/src/main.ts index e57db594..f9754fe1 100644 --- a/v2/pkg/templates/templates/vue-ts/frontend/src/main.ts +++ b/v2/pkg/templates/templates/vue-ts/frontend/src/main.ts @@ -1,4 +1,5 @@ import {createApp} from 'vue' import App from './App.vue' +import './style.css'; createApp(App).mount('#app') diff --git a/v2/pkg/templates/templates/vue/frontend/index.tmpl.html b/v2/pkg/templates/templates/vue/frontend/index.tmpl.html index b3d4289c..d45b7a8c 100644 --- a/v2/pkg/templates/templates/vue/frontend/index.tmpl.html +++ b/v2/pkg/templates/templates/vue/frontend/index.tmpl.html @@ -4,7 +4,6 @@ {{.ProjectName}} -
diff --git a/v2/pkg/templates/templates/vue/frontend/src/main.js b/v2/pkg/templates/templates/vue/frontend/src/main.js index e57db594..f9754fe1 100644 --- a/v2/pkg/templates/templates/vue/frontend/src/main.js +++ b/v2/pkg/templates/templates/vue/frontend/src/main.js @@ -1,4 +1,5 @@ import {createApp} from 'vue' import App from './App.vue' +import './style.css'; createApp(App).mount('#app') From 22cfcbd5a1a4a28d68151241b5365b393f911ccf Mon Sep 17 00:00:00 2001 From: Ethan Reesor Date: Thu, 13 Jul 2023 05:40:22 -0500 Subject: [PATCH 21/36] Override error formatting (#2717) --- v2/internal/app/app_dev.go | 2 +- v2/internal/app/app_production.go | 2 +- v2/internal/frontend/dispatcher/calls.go | 12 +++++++++--- v2/internal/frontend/dispatcher/dispatcher.go | 5 ++++- v2/pkg/options/options.go | 5 +++++ website/docs/reference/options.mdx | 9 +++++++++ website/src/pages/changelog.mdx | 1 + 7 files changed, 30 insertions(+), 6 deletions(-) diff --git a/v2/internal/app/app_dev.go b/v2/internal/app/app_dev.go index 7cdc627f..2e04f448 100644 --- a/v2/internal/app/app_dev.go +++ b/v2/internal/app/app_dev.go @@ -213,7 +213,7 @@ func CreateApp(appoptions *options.App) (*App, error) { eventHandler := runtime.NewEvents(myLogger) ctx = context.WithValue(ctx, "events", eventHandler) - messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler) + messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler, appoptions.ErrorFormatter) // Create the frontends and register to event handler desktopFrontend := desktop.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher) diff --git a/v2/internal/app/app_production.go b/v2/internal/app/app_production.go index 2dfad601..5b847260 100644 --- a/v2/internal/app/app_production.go +++ b/v2/internal/app/app_production.go @@ -82,7 +82,7 @@ func CreateApp(appoptions *options.App) (*App, error) { ctx = context.WithValue(ctx, "buildtype", "production") } - messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler) + messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler, appoptions.ErrorFormatter) appFrontend := desktop.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher) eventHandler.AddFrontend(appFrontend) diff --git a/v2/internal/frontend/dispatcher/calls.go b/v2/internal/frontend/dispatcher/calls.go index ef19c603..491d17fe 100644 --- a/v2/internal/frontend/dispatcher/calls.go +++ b/v2/internal/frontend/dispatcher/calls.go @@ -3,8 +3,9 @@ package dispatcher import ( "encoding/json" "fmt" - "github.com/wailsapp/wails/v2/internal/frontend" "strings" + + "github.com/wailsapp/wails/v2/internal/frontend" ) type callMessage struct { @@ -49,7 +50,12 @@ func (d *Dispatcher) processCallMessage(message string, sender frontend.Frontend CallbackID: payload.CallbackID, } if err != nil { - callbackMessage.Err = err.Error() + // Use the error formatter if one was provided + if d.errfmt != nil { + callbackMessage.Err = d.errfmt(err) + } else { + callbackMessage.Err = err.Error() + } } else { callbackMessage.Result = result } @@ -66,7 +72,7 @@ func (d *Dispatcher) processCallMessage(message string, sender frontend.Frontend // CallbackMessage defines a message that contains the result of a call type CallbackMessage struct { Result interface{} `json:"result"` - Err string `json:"error"` + Err any `json:"error"` CallbackID string `json:"callbackid"` } diff --git a/v2/internal/frontend/dispatcher/dispatcher.go b/v2/internal/frontend/dispatcher/dispatcher.go index 44a8886e..56092d37 100644 --- a/v2/internal/frontend/dispatcher/dispatcher.go +++ b/v2/internal/frontend/dispatcher/dispatcher.go @@ -7,6 +7,7 @@ import ( "github.com/wailsapp/wails/v2/internal/binding" "github.com/wailsapp/wails/v2/internal/frontend" "github.com/wailsapp/wails/v2/internal/logger" + "github.com/wailsapp/wails/v2/pkg/options" ) type Dispatcher struct { @@ -15,15 +16,17 @@ type Dispatcher struct { events frontend.Events bindingsDB *binding.DB ctx context.Context + errfmt options.ErrorFormatter } -func NewDispatcher(ctx context.Context, log *logger.Logger, bindings *binding.Bindings, events frontend.Events) *Dispatcher { +func NewDispatcher(ctx context.Context, log *logger.Logger, bindings *binding.Bindings, events frontend.Events, errfmt options.ErrorFormatter) *Dispatcher { return &Dispatcher{ log: log, bindings: bindings, events: events, bindingsDB: bindings.DB(), ctx: ctx, + errfmt: errfmt, } } diff --git a/v2/pkg/options/options.go b/v2/pkg/options/options.go index 1562a7df..2fbcbc8b 100644 --- a/v2/pkg/options/options.go +++ b/v2/pkg/options/options.go @@ -64,6 +64,9 @@ type App struct { Bind []interface{} WindowStartState WindowStartState + // ErrorFormatter overrides the formatting of errors returned by backend methods + ErrorFormatter ErrorFormatter + // CSS property to test for draggable elements. Default "--wails-draggable" CSSDragProperty string @@ -90,6 +93,8 @@ type App struct { Debug Debug } +type ErrorFormatter func(error) any + type RGBA struct { R uint8 `json:"r"` G uint8 `json:"g"` diff --git a/website/docs/reference/options.mdx b/website/docs/reference/options.mdx index 62ffffe1..5eb5f097 100644 --- a/website/docs/reference/options.mdx +++ b/website/docs/reference/options.mdx @@ -58,6 +58,7 @@ func main() { Bind: []interface{}{ app, }, + ErrorFormatter: func(err error) any { return err.Error() }, Windows: &windows.Options{ WebviewIsTransparent: false, WindowIsTranslucent: false, @@ -477,6 +478,14 @@ A slice of struct instances defining methods that need to be bound to the fronte Name: Bind
Type: `[]interface{}` +### ErrorFormatter + +A function that determines how errors are formatted when returned by a JS-to-Go +method call. The returned value will be marshalled as JSON. + +Name: ErrorFormatter
+Type: `func (error) any` + ### Windows This defines [Windows specific options](#windows). diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index f82f2fd5..632b8c69 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `-devtools` production build flag. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2725) - Added `EnableDefaultContextMenu` option to allow enabling the browser's default context-menu in production . Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2733) - Added smart functionality for the default context-menu in production with CSS styles to control it. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2748) +- Added custom error formatting to allow passing structured errors back to the frontend. ### Changed From 150dac9eade0614f270b455214dba20721cbf0cb Mon Sep 17 00:00:00 2001 From: guangwu Date: Thu, 13 Jul 2023 21:13:47 +0800 Subject: [PATCH 22/36] chore: slice replace loop (#2757) Signed-off-by: guoguangwu --- v2/internal/shell/shell.go | 4 +--- v2/pkg/menu/keys/keys.go | 4 +--- v2/pkg/menu/menu.go | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/v2/internal/shell/shell.go b/v2/internal/shell/shell.go index e16b96ca..badea2b3 100644 --- a/v2/internal/shell/shell.go +++ b/v2/internal/shell/shell.go @@ -47,9 +47,7 @@ func (c *Command) Stderr() string { } func (c *Command) AddArgs(args []string) { - for _, arg := range args { - c.args = append(c.args, arg) - } + c.args = append(c.args, args...) } // CreateCommand returns a *Cmd struct that when run, will run the given command + args in the given directory diff --git a/v2/pkg/menu/keys/keys.go b/v2/pkg/menu/keys/keys.go index 73bc9414..fa8027a3 100644 --- a/v2/pkg/menu/keys/keys.go +++ b/v2/pkg/menu/keys/keys.go @@ -99,8 +99,6 @@ func Combo(key string, modifier1 Modifier, modifier2 Modifier, rest ...Modifier) Key: key, Modifiers: []Modifier{modifier1, modifier2}, } - for _, extra := range rest { - result.Modifiers = append(result.Modifiers, extra) - } + result.Modifiers = append(result.Modifiers, rest...) return result } diff --git a/v2/pkg/menu/menu.go b/v2/pkg/menu/menu.go index 0c3ddb61..819939bb 100644 --- a/v2/pkg/menu/menu.go +++ b/v2/pkg/menu/menu.go @@ -17,9 +17,7 @@ func (m *Menu) Append(item *MenuItem) { // Merge will append the items in the given menu // into this menu func (m *Menu) Merge(menu *Menu) { - for _, item := range menu.Items { - m.Items = append(m.Items, item) - } + m.Items = append(m.Items, menu.Items...) } // AddText adds a TextMenu item to the menu From e0a92712fe94f74025f10bfb99c7e8f92483376b Mon Sep 17 00:00:00 2001 From: figuerom16 <112363116+figuerom16@users.noreply.github.com> Date: Sat, 15 Jul 2023 06:52:33 -0700 Subject: [PATCH 23/36] SvelteKit Guide: Manual installation, Bash installation, Usage Notes. (#2771) * Create SvelteKit.mdx * Rename SvelteKit.mdx to sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update sveltekit.mdx * Update changelog.mdx --- website/docs/guides/sveltekit.mdx | 133 ++++++++++++++++++++++++++++++ website/src/pages/changelog.mdx | 1 + 2 files changed, 134 insertions(+) create mode 100644 website/docs/guides/sveltekit.mdx diff --git a/website/docs/guides/sveltekit.mdx b/website/docs/guides/sveltekit.mdx new file mode 100644 index 00000000..6be40949 --- /dev/null +++ b/website/docs/guides/sveltekit.mdx @@ -0,0 +1,133 @@ +# SvelteKit + +This guide will go into: +1. Miminal Installation Steps - The steps needed to get a minimum Wails setup working for SvelteKit. +2. Install Script - Bash script for accomplishing the Minimal Installation Steps with optional Wails branding. +3. Important Notes - Issues that can be encountered when using SvelteKit + Wails and fixes. + +## 1. Minimal Installation Steps + +##### Install Wails for Svelte. +- `wails init -n myapp -t svelte` + +##### Delete the svelte frontend. +- Navigate into your newly created myapp folder. +- Delete the folder named "frontend" + +##### While in the Wails project root. Use your favorite package manager and install SvelteKit as the new frontend. Follow the prompts. +- `npm create svelte@latest frontend` + +##### Modify wails.json. +- Add `"wailsjsdir": "./frontend/src/lib",` Do note that this is where your Go and runtime functions will appear. +- Change your package manager frontend here if not using npm. + +##### Modify main.go. +- The first comment `//go:embed all:frontend/dist` needs to be changed to `//go:embed all:frontend/build` + +##### Install/remove dependencies using your favorite package manager. +- Navigate into your "frontend" folder. +- `npm i` +- `npm uninstall @sveltejs/adapter-auto` +- `npm i -D @sveltejs/adapter-static` + +##### Change adapter in svelte.config.js +- First line of file change `import adapter from '@sveltejs/adapter-auto';` to `import adapter from '@sveltejs/adapter-static';` + +##### Put SvelteKit into SPA mode with prerendering. +- Create a file under myapp/frontend/src/routes/ named +layout.ts/+layout.js. +- Add two lines into the newly created file `export const prerender = true` and `export const ssr = false` + +##### Test installation. +- Navigate back into the Wails project root (one directory up). +- run `wails dev` +- If the application doesn't run please check through the previous steps. + +## 2. Install Script + +##### This Bash Script does the steps listed above. Make sure to read over the script and understand what the script is doing on your computer. + +- Create a file sveltekit-wails.sh +- Copy the below code into the new file then save it. +- Make it executable with `chmod +x sveltekit-wails.sh` +- Brand is an optional param below that adds back in the wails branding. Leave third param blank to not insert the Wails branding. +- Example usage: `./sveltekit-wails.sh pnpm newapp brand` + +##### sveltekit-wails.sh: +``` +manager=$1 +project=$2 +brand=$3 +wails init -n $project -t svelte +cd $project +sed -i "s|npm|$manager|g" wails.json +sed -i 's|"auto",|"auto",\n "wailsjsdir": "./frontend/src/lib",|' wails.json +sed -i "s|all:frontend/dist|all:frontend/build|" main.go +if [[ -n $brand ]]; then + mv frontend/src/App.svelte +page.svelte + sed -i "s|'./assets|'\$lib/assets|" +page.svelte + sed -i "s|'../wails|'\$lib/wails|" +page.svelte + mv frontend/src/assets . +fi +rm -r frontend +$manager create svelte@latest frontend +if [[ -n $brand ]]; then + mv +page.svelte frontend/src/routes/+page.svelte + mkdir frontend/src/lib + mv assets frontend/src/lib/ +fi +cd frontend +$manager i +$manager uninstall @sveltejs/adapter-auto +$manager i -D @sveltejs/adapter-static +echo -e "export const prerender = true\nexport const ssr = false" > src/routes/+layout.ts +sed -i "s|-auto';|-static';|" svelte.config.js +cd .. +wails dev +``` + +## 3. Important Notes + +##### Server files will cause build failures. +- +layout.server.ts, +page.server.ts, +server.ts or any file with "server" in the name will fail to build as all routes are prerendered. + +##### The Wails runtime unloads with full page navigations! +- Anything that causes full page navigations: `window.location.href = '//'` or Context menu reload when using wails dev. What this means is that you can end up losing the ability to call any runtime breaking the app. There are two ways to work around this. +- Use `import { goto } from '$app/navigation'` then call `goto('//')` in your +page.svelte. This will prevent a full page navigation. +- If full page navigation can't be prevented the Wails runtime can be added to all pages by adding the below into the of myapp/frontend/src/app.html +``` + +... + + + +... + +``` +See https://wails.io/docs/guides/frontend for more information. + +##### Inital data can be loaded and refreshed from +page.ts/+page.js to +page.svelte. +- +page.ts/+page.js works well with load() https://kit.svelte.dev/docs/load#page-data +- invalidateAll() in +page.svelte will call load() from +page.ts/+page.js https://kit.svelte.dev/docs/load#rerunning-load-functions-manual-invalidation. + +##### Error Handling +- Expected errors using Throw error works in +page.ts/+page.js with a +error.svelte page. https://kit.svelte.dev/docs/errors#expected-errors +- Unexpected errors will cause the application to become unusable. Only recovery option (known so far) from unexpected errors is to reload the app. To do this create a file myapp/frontend/src/hooks.client.ts then add the below code to the file. +``` +import { WindowReloadApp } from '$lib/wailsjs/runtime/runtime' +export async function handleError() { + WindowReloadApp() +} +``` + +##### Using Forms and handling functions +- The simplest way is to call a function from the form is the standard, bind:value your variables and prevent submission `
` +- The more advanced way is to use:enhance (progressive enhancement) which will allow for convenient access to formData, formElement, submitter. The important note is to always cancel() the form which prevents server side behavior. https://kit.svelte.dev/docs/form-actions#progressive-enhancement Example: +``` + { + cancel() + console.log(Object.fromEntries(formData)) + console.log(formElement) + console.log(submitter) + handle() +}}> +``` diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 632b8c69..a1b7b4e7 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added `EnableDefaultContextMenu` option to allow enabling the browser's default context-menu in production . Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2733) - Added smart functionality for the default context-menu in production with CSS styles to control it. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2748) - Added custom error formatting to allow passing structured errors back to the frontend. +- Added sveltekit.mdx guide. Added by @figuerom16 in [PR](https://github.com/wailsapp/wails/pull/2771) ### Changed From 1e76b0b52e5b04180e795c198686f6e1526b0249 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Tue, 18 Jul 2023 21:47:26 +1000 Subject: [PATCH 24/36] Remove markdown formatter --- .github/workflows/format-markdown-files.yml | 33 --------------------- 1 file changed, 33 deletions(-) delete mode 100644 .github/workflows/format-markdown-files.yml diff --git a/.github/workflows/format-markdown-files.yml b/.github/workflows/format-markdown-files.yml deleted file mode 100644 index a8f7de9c..00000000 --- a/.github/workflows/format-markdown-files.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Format Markdown Files - - -jobs: - format_markdown_files: - runs-on: ubuntu-latest - if: github.repository == 'wailsapp/wails' - steps: - - uses: actions/checkout@v3 - - - name: Setup Nodejs - uses: actions/setup-node@v2 - with: - node-version: 18.x - - - name: Install Task - uses: arduino/setup-task@v1 - with: - version: 3.x - repo-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Format All Markdown Files - run: task format-all-md - - - name: Create Pull Request - uses: peter-evans/create-pull-request@v4 - with: - commit-message: "docs: format document" - title: "docs: format document" - body: "- [x] Format all Markdown(x) documents" - branch: chore/format-markdown-files - delete-branch: true - draft: false From 7f402bf0c42fe87669ae0faf96407a308f768bdb Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 18 Jul 2023 23:04:16 +1000 Subject: [PATCH 25/36] chore: update sponsors.svg (#2778) Co-authored-by: leaanthony --- website/static/img/sponsors.svg | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/website/static/img/sponsors.svg b/website/static/img/sponsors.svg index 1a20e9c2..12c6eb82 100644 --- a/website/static/img/sponsors.svg +++ b/website/static/img/sponsors.svg @@ -90,42 +90,46 @@ text { Helpers - + - + - + - + - + - + - + - + - + - + + + + + From 48b35aaafe79a748ed2e888af8b80fac8353f62f Mon Sep 17 00:00:00 2001 From: "Aranggi J. Toar" Date: Mon, 24 Jul 2023 16:53:24 +0700 Subject: [PATCH 26/36] chore: update npm and docker package names for dnf package manager (#2790) * chore: update package names for dnf package manager * chore: update changelog --- v2/internal/system/packagemanager/dnf.go | 2 ++ website/src/pages/changelog.mdx | 1 + 2 files changed, 3 insertions(+) diff --git a/v2/internal/system/packagemanager/dnf.go b/v2/internal/system/packagemanager/dnf.go index d9eaf806..fec676f1 100644 --- a/v2/internal/system/packagemanager/dnf.go +++ b/v2/internal/system/packagemanager/dnf.go @@ -44,6 +44,7 @@ func (y *Dnf) Packages() packagemap { }, "npm": []*Package{ {Name: "npm", SystemPackage: true}, + {Name: "nodejs-npm", SystemPackage: true}, }, "upx": []*Package{ {Name: "upx", SystemPackage: true, Optional: true}, @@ -57,6 +58,7 @@ func (y *Dnf) Packages() packagemap { "fedora": "Follow the guide: https://docs.docker.com/engine/install/fedora/", }, }, + {Name: "moby-engine", SystemPackage: true, Optional: true}, }, } } diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index a1b7b4e7..6ffd1d64 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added correct NodeJS and Docker package names for DNF package manager of Fedora 38. Added by @aranggitoar in [PR](https://github.com/wailsapp/wails/pull/2790) - Added `-devtools` production build flag. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2725) - Added `EnableDefaultContextMenu` option to allow enabling the browser's default context-menu in production . Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2733) - Added smart functionality for the default context-menu in production with CSS styles to control it. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2748) From 84d2576e061477269e334a751e0d79831e471162 Mon Sep 17 00:00:00 2001 From: Li Yang <384113872@qq.com> Date: Wed, 26 Jul 2023 18:32:43 +0800 Subject: [PATCH 27/36] Update README.zh-Hans.md (#2791) Fixed a link error --- README.zh-Hans.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.zh-Hans.md b/README.zh-Hans.md index 69d456e7..5afce335 100644 --- a/README.zh-Hans.md +++ b/README.zh-Hans.md @@ -87,7 +87,7 @@ ## 快速入门 -使用说明在 [官网](https://wails.io/docs/gettingstarted/installation)。 +使用说明在 [官网](https://wails.io/zh-Hans/docs/gettingstarted/installation/)。 ## 赞助商 From fe479876c5f83fa0e34ea042577ba0d4a5158958 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 28 Jul 2023 08:15:00 +1000 Subject: [PATCH 28/36] chore: update sponsors.svg (#2794) Co-authored-by: leaanthony --- website/static/img/sponsors.svg | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/website/static/img/sponsors.svg b/website/static/img/sponsors.svg index 12c6eb82..039fdef7 100644 --- a/website/static/img/sponsors.svg +++ b/website/static/img/sponsors.svg @@ -90,46 +90,42 @@ text { Helpers - + - + - - - - - + - + - + - + - + - + - + - + From a96d51be026bfed552cff0ea81bde0f757a9dd55 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 29 Jul 2023 12:04:41 +1000 Subject: [PATCH 29/36] Update project-config.mdx --- website/docs/reference/project-config.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/reference/project-config.mdx b/website/docs/reference/project-config.mdx index 5c7d578b..8e763502 100644 --- a/website/docs/reference/project-config.mdx +++ b/website/docs/reference/project-config.mdx @@ -6,7 +6,7 @@ sidebar_position: 5 The project config resides in the `wails.json` file in the project directory. The structure of the config is: -```json +```json5 { // Project config version "version": "", From 027edad51b0ceaa2aa1e9aa25ab78253f420e19e Mon Sep 17 00:00:00 2001 From: Andreas Christou Date: Tue, 1 Aug 2023 23:58:05 +0100 Subject: [PATCH 30/36] Create-React-App documentation updates (#2805) * Add documentation for running a create-react-app project in watch mode * Fix build warning --- .../docs/guides/application-development.mdx | 29 +++++++++++++++++-- website/docs/guides/sveltekit.mdx | 2 +- .../guides/application-development.mdx | 29 +++++++++++++++++-- .../guides/application-development.mdx | 29 +++++++++++++++++-- 4 files changed, 82 insertions(+), 7 deletions(-) diff --git a/website/docs/guides/application-development.mdx b/website/docs/guides/application-development.mdx index f8074d15..9d04fe91 100644 --- a/website/docs/guides/application-development.mdx +++ b/website/docs/guides/application-development.mdx @@ -219,8 +219,33 @@ be saved to your project config and become the default. Some frameworks come with their own live-reloading server, however they will not be able to take advantage of the Wails Go bindings. In this scenario, it is best to run a watcher script that rebuilds the project into the build directory, which Wails will be watching. For an example, see the default svelte template that uses [rollup](https://rollupjs.org/guide/en/). -For [create-react-app](https://create-react-app.dev/), it's possible to use -[this script](https://gist.github.com/int128/e0cdec598c5b3db728ff35758abdbafd) to achieve a similar result. + +### Create React App + +The process for a Create-React-App project is slightly more complicated. In order to support live frontend reloading the following configuration +needs to be added to your `wails.json`: + +```json + "frontend:dev:watcher": "yarn start", + "frontend:dev:serverUrl": "http://localhost:3000", +``` + +The `frontend:dev:watcher` command will start the Create-React-App development server (hosted on port `3000` typically). The `frontend:dev:serverUrl` command then +instructs Wails to serve assets from the development server when loading the frontend rather than from the build folder. In addition to the above, the +`index.html` needs to be updated with the following: + +```html + + + + + +``` + +This is required as the watcher command that rebuilds the frontend prevents Wails from injecting the required scripts. This circumvents that issue by ensuring +the scripts are always injected. With this configuration, `wails dev` can be run which will appropriately build the frontend and backend with hot-reloading enabled. +Additionally, when accessing the application from a browser the React developer tools can now be used on a non-minified version of the application for straightforward +debugging. Finally, for faster builds, `wails dev -s` can be run to skip the default building of the frontend by Wails as this is an unnecessary step. ## Go Module diff --git a/website/docs/guides/sveltekit.mdx b/website/docs/guides/sveltekit.mdx index 6be40949..3f82eb81 100644 --- a/website/docs/guides/sveltekit.mdx +++ b/website/docs/guides/sveltekit.mdx @@ -93,7 +93,7 @@ wails dev ##### The Wails runtime unloads with full page navigations! - Anything that causes full page navigations: `window.location.href = '//'` or Context menu reload when using wails dev. What this means is that you can end up losing the ability to call any runtime breaking the app. There are two ways to work around this. - Use `import { goto } from '$app/navigation'` then call `goto('//')` in your +page.svelte. This will prevent a full page navigation. -- If full page navigation can't be prevented the Wails runtime can be added to all pages by adding the below into the of myapp/frontend/src/app.html +- If full page navigation can't be prevented the Wails runtime can be added to all pages by adding the below into the `` of myapp/frontend/src/app.html ``` ... diff --git a/website/versioned_docs/version-v2.4.0/guides/application-development.mdx b/website/versioned_docs/version-v2.4.0/guides/application-development.mdx index f8074d15..9d04fe91 100644 --- a/website/versioned_docs/version-v2.4.0/guides/application-development.mdx +++ b/website/versioned_docs/version-v2.4.0/guides/application-development.mdx @@ -219,8 +219,33 @@ be saved to your project config and become the default. Some frameworks come with their own live-reloading server, however they will not be able to take advantage of the Wails Go bindings. In this scenario, it is best to run a watcher script that rebuilds the project into the build directory, which Wails will be watching. For an example, see the default svelte template that uses [rollup](https://rollupjs.org/guide/en/). -For [create-react-app](https://create-react-app.dev/), it's possible to use -[this script](https://gist.github.com/int128/e0cdec598c5b3db728ff35758abdbafd) to achieve a similar result. + +### Create React App + +The process for a Create-React-App project is slightly more complicated. In order to support live frontend reloading the following configuration +needs to be added to your `wails.json`: + +```json + "frontend:dev:watcher": "yarn start", + "frontend:dev:serverUrl": "http://localhost:3000", +``` + +The `frontend:dev:watcher` command will start the Create-React-App development server (hosted on port `3000` typically). The `frontend:dev:serverUrl` command then +instructs Wails to serve assets from the development server when loading the frontend rather than from the build folder. In addition to the above, the +`index.html` needs to be updated with the following: + +```html + + + + + +``` + +This is required as the watcher command that rebuilds the frontend prevents Wails from injecting the required scripts. This circumvents that issue by ensuring +the scripts are always injected. With this configuration, `wails dev` can be run which will appropriately build the frontend and backend with hot-reloading enabled. +Additionally, when accessing the application from a browser the React developer tools can now be used on a non-minified version of the application for straightforward +debugging. Finally, for faster builds, `wails dev -s` can be run to skip the default building of the frontend by Wails as this is an unnecessary step. ## Go Module diff --git a/website/versioned_docs/version-v2.5.0/guides/application-development.mdx b/website/versioned_docs/version-v2.5.0/guides/application-development.mdx index f8074d15..9d04fe91 100644 --- a/website/versioned_docs/version-v2.5.0/guides/application-development.mdx +++ b/website/versioned_docs/version-v2.5.0/guides/application-development.mdx @@ -219,8 +219,33 @@ be saved to your project config and become the default. Some frameworks come with their own live-reloading server, however they will not be able to take advantage of the Wails Go bindings. In this scenario, it is best to run a watcher script that rebuilds the project into the build directory, which Wails will be watching. For an example, see the default svelte template that uses [rollup](https://rollupjs.org/guide/en/). -For [create-react-app](https://create-react-app.dev/), it's possible to use -[this script](https://gist.github.com/int128/e0cdec598c5b3db728ff35758abdbafd) to achieve a similar result. + +### Create React App + +The process for a Create-React-App project is slightly more complicated. In order to support live frontend reloading the following configuration +needs to be added to your `wails.json`: + +```json + "frontend:dev:watcher": "yarn start", + "frontend:dev:serverUrl": "http://localhost:3000", +``` + +The `frontend:dev:watcher` command will start the Create-React-App development server (hosted on port `3000` typically). The `frontend:dev:serverUrl` command then +instructs Wails to serve assets from the development server when loading the frontend rather than from the build folder. In addition to the above, the +`index.html` needs to be updated with the following: + +```html + + + + + +``` + +This is required as the watcher command that rebuilds the frontend prevents Wails from injecting the required scripts. This circumvents that issue by ensuring +the scripts are always injected. With this configuration, `wails dev` can be run which will appropriately build the frontend and backend with hot-reloading enabled. +Additionally, when accessing the application from a browser the React developer tools can now be used on a non-minified version of the application for straightforward +debugging. Finally, for faster builds, `wails dev -s` can be run to skip the default building of the frontend by Wails as this is an unnecessary step. ## Go Module From 2859143b2f9966dd3fb2096744feed95dc78c195 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Thu, 3 Aug 2023 08:35:34 +1000 Subject: [PATCH 31/36] Add Screen docs --- website/docs/reference/runtime/screen.mdx | 35 +++++++++++++++++++ .../reference/runtime/screen.mdx | 35 +++++++++++++++++++ .../reference/runtime/screen.mdx | 35 +++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 website/docs/reference/runtime/screen.mdx create mode 100644 website/versioned_docs/version-v2.4.0/reference/runtime/screen.mdx create mode 100644 website/versioned_docs/version-v2.5.0/reference/runtime/screen.mdx diff --git a/website/docs/reference/runtime/screen.mdx b/website/docs/reference/runtime/screen.mdx new file mode 100644 index 00000000..d2ccabcf --- /dev/null +++ b/website/docs/reference/runtime/screen.mdx @@ -0,0 +1,35 @@ +--- +sidebar_position: 9 +--- + +# Screen + +These methods provide information about the currently connected screens. + +### ScreenGetAll + +Returns a list of currently connected screens. + +Go: `ScreenGetAll(ctx context.Context) []screen`
+JS: `ScreenGetAll()` + + +#### Screen + +```go +type Screen struct { + IsCurrent bool + IsPrimary bool + Width int + Height int +} +``` + +```ts +interface Screen { + isCurrent: boolean; + isPrimary: boolean; + width : number + height : number +} +``` diff --git a/website/versioned_docs/version-v2.4.0/reference/runtime/screen.mdx b/website/versioned_docs/version-v2.4.0/reference/runtime/screen.mdx new file mode 100644 index 00000000..d2ccabcf --- /dev/null +++ b/website/versioned_docs/version-v2.4.0/reference/runtime/screen.mdx @@ -0,0 +1,35 @@ +--- +sidebar_position: 9 +--- + +# Screen + +These methods provide information about the currently connected screens. + +### ScreenGetAll + +Returns a list of currently connected screens. + +Go: `ScreenGetAll(ctx context.Context) []screen`
+JS: `ScreenGetAll()` + + +#### Screen + +```go +type Screen struct { + IsCurrent bool + IsPrimary bool + Width int + Height int +} +``` + +```ts +interface Screen { + isCurrent: boolean; + isPrimary: boolean; + width : number + height : number +} +``` diff --git a/website/versioned_docs/version-v2.5.0/reference/runtime/screen.mdx b/website/versioned_docs/version-v2.5.0/reference/runtime/screen.mdx new file mode 100644 index 00000000..d2ccabcf --- /dev/null +++ b/website/versioned_docs/version-v2.5.0/reference/runtime/screen.mdx @@ -0,0 +1,35 @@ +--- +sidebar_position: 9 +--- + +# Screen + +These methods provide information about the currently connected screens. + +### ScreenGetAll + +Returns a list of currently connected screens. + +Go: `ScreenGetAll(ctx context.Context) []screen`
+JS: `ScreenGetAll()` + + +#### Screen + +```go +type Screen struct { + IsCurrent bool + IsPrimary bool + Width int + Height int +} +``` + +```ts +interface Screen { + isCurrent: boolean; + isPrimary: boolean; + width : number + height : number +} +``` From 083e6b03f30225d1c3c313230ffe54c87ed66f2c Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Fri, 4 Aug 2023 08:18:34 +1000 Subject: [PATCH 32/36] Update Screen docs --- website/docs/reference/runtime/screen.mdx | 2 ++ .../versioned_docs/version-v2.4.0/reference/runtime/screen.mdx | 2 ++ .../versioned_docs/version-v2.5.0/reference/runtime/screen.mdx | 2 ++ 3 files changed, 6 insertions(+) diff --git a/website/docs/reference/runtime/screen.mdx b/website/docs/reference/runtime/screen.mdx index d2ccabcf..f0feee9e 100644 --- a/website/docs/reference/runtime/screen.mdx +++ b/website/docs/reference/runtime/screen.mdx @@ -16,6 +16,7 @@ JS: `ScreenGetAll()` #### Screen +Go struct: ```go type Screen struct { IsCurrent bool @@ -25,6 +26,7 @@ type Screen struct { } ``` +Typescript interface: ```ts interface Screen { isCurrent: boolean; diff --git a/website/versioned_docs/version-v2.4.0/reference/runtime/screen.mdx b/website/versioned_docs/version-v2.4.0/reference/runtime/screen.mdx index d2ccabcf..f0feee9e 100644 --- a/website/versioned_docs/version-v2.4.0/reference/runtime/screen.mdx +++ b/website/versioned_docs/version-v2.4.0/reference/runtime/screen.mdx @@ -16,6 +16,7 @@ JS: `ScreenGetAll()` #### Screen +Go struct: ```go type Screen struct { IsCurrent bool @@ -25,6 +26,7 @@ type Screen struct { } ``` +Typescript interface: ```ts interface Screen { isCurrent: boolean; diff --git a/website/versioned_docs/version-v2.5.0/reference/runtime/screen.mdx b/website/versioned_docs/version-v2.5.0/reference/runtime/screen.mdx index d2ccabcf..f0feee9e 100644 --- a/website/versioned_docs/version-v2.5.0/reference/runtime/screen.mdx +++ b/website/versioned_docs/version-v2.5.0/reference/runtime/screen.mdx @@ -16,6 +16,7 @@ JS: `ScreenGetAll()` #### Screen +Go struct: ```go type Screen struct { IsCurrent bool @@ -25,6 +26,7 @@ type Screen struct { } ``` +Typescript interface: ```ts interface Screen { isCurrent: boolean; From b48579892b612e47ead6d1c56cfba8dd90aee786 Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Sat, 5 Aug 2023 17:45:08 +1000 Subject: [PATCH 33/36] [docs] Add mac flash troubleshooting guide --- website/docs/guides/troubleshooting.mdx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/website/docs/guides/troubleshooting.mdx b/website/docs/guides/troubleshooting.mdx index 494e62bf..bd965a79 100644 --- a/website/docs/guides/troubleshooting.mdx +++ b/website/docs/guides/troubleshooting.mdx @@ -185,3 +185,20 @@ If this does happen, simply delete `frontend/node_modules` and `frontend/package ## Build process stuck on "Generating bindings" Bindings generation process runs your application in a special mode. If application, intentionally or unintentionally, contains an endless loop (i.e. not exiting after `wails.Run()` finished), this can lead to build process stuck on the stage of bindings generation. Please make sure your code exits properly. + +## Mac application flashes white at startup + +This is due to the default background of the webview being white. If you want to use the window background colour instead, +you can make the webview background transparent using the following config: + +```go + err := wails.Run(&options.App{ + Title: "macflash", + Width: 1024, + Height: 768, + // Other settings + Mac: &mac.Options{ + WebviewIsTransparent: true, + }, + }) +``` \ No newline at end of file From e72e4aa179c9cf8b24ec487faff181ea6c546395 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Z=C3=A1mb=C3=B3=2C=20Levente?= Date: Wed, 9 Aug 2023 23:48:09 +0200 Subject: [PATCH 34/36] add new programName option to linux options (#2817) * add new programName option to linux options * modify changelog * free program name string --- v2/internal/frontend/desktop/linux/frontend.go | 6 ++++++ v2/pkg/options/linux/linux.go | 9 +++++++++ website/docs/reference/options.mdx | 14 +++++++++++++- website/src/pages/changelog.mdx | 1 + 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/v2/internal/frontend/desktop/linux/frontend.go b/v2/internal/frontend/desktop/linux/frontend.go index 14c202d8..2f6f286f 100644 --- a/v2/internal/frontend/desktop/linux/frontend.go +++ b/v2/internal/frontend/desktop/linux/frontend.go @@ -190,6 +190,12 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger. C.install_signal_handlers() + if appoptions.Linux != nil && appoptions.Linux.ProgramName != "" { + prgname := C.CString(appoptions.Linux.ProgramName) + C.g_set_prgname(prgname) + C.free(unsafe.Pointer(prgname)) + } + return result } diff --git a/v2/pkg/options/linux/linux.go b/v2/pkg/options/linux/linux.go index 3726297c..062119cb 100644 --- a/v2/pkg/options/linux/linux.go +++ b/v2/pkg/options/linux/linux.go @@ -29,6 +29,15 @@ type Options struct { // - WebviewGpuPolicyOnDemand // - WebviewGpuPolicyNever WebviewGpuPolicy WebviewGpuPolicy + + // ProgramName is used to set the program's name for the window manager via GTK's g_set_prgname(). + //This name should not be localized. [see the docs] + // + //When a .desktop file is created this value helps with window grouping and desktop icons when the .desktop file's Name + //property differs form the executable's filename. + // + //[see the docs]: https://docs.gtk.org/glib/func.set_prgname.html + ProgramName string } type Messages struct { diff --git a/website/docs/reference/options.mdx b/website/docs/reference/options.mdx index 5eb5f097..af772c8b 100644 --- a/website/docs/reference/options.mdx +++ b/website/docs/reference/options.mdx @@ -105,7 +105,8 @@ func main() { Linux: &linux.Options{ Icon: icon, WindowIsTranslucent: false, - WebviewGpuPolicy: linux.WebviewGpuPolicyAlways, + WebviewGpuPolicy: linux.WebviewGpuPolicyAlways, + ProgramName: "wails" }, Debug: options.Debug{ OpenInspectorOnStartup: false, @@ -898,6 +899,17 @@ Default: `WebviewGpuPolicyAlways` | WebviewGpuPolicyOnDemand | Hardware acceleration is enabled/disabled as request by web contents| | WebviewGpuPolicyNever | Hardware acceleration is always disabled | +#### ProgramName + +This option is used to set the program's name for the window manager via GTK's g_set_prgname(). +This name should not be localized, [see the docs](https://docs.gtk.org/glib/func.set_prgname.html). + +When a .desktop file is created this value helps with window grouping and desktop icons when the .desktop file's `Name` +property differs form the executable's filename. + +Name: ProgramName
+Type: string
+ ### Debug This defines [Debug specific options](#Debug) that apply to debug builds. diff --git a/website/src/pages/changelog.mdx b/website/src/pages/changelog.mdx index 6ffd1d64..8b215c91 100644 --- a/website/src/pages/changelog.mdx +++ b/website/src/pages/changelog.mdx @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added smart functionality for the default context-menu in production with CSS styles to control it. Added by @mmghv in [PR](https://github.com/wailsapp/wails/pull/2748) - Added custom error formatting to allow passing structured errors back to the frontend. - Added sveltekit.mdx guide. Added by @figuerom16 in [PR](https://github.com/wailsapp/wails/pull/2771) +- Added ProgramName option to [linux.Options](/docs/reference/options#linux). Added by @lyimmi in [PR](https://github.com/wailsapp/wails/pull/2817) ### Changed From 7b098fd5227f2c87e8b1b46834448b777496252c Mon Sep 17 00:00:00 2001 From: Kin NG <59541661+k1nho@users.noreply.github.com> Date: Wed, 9 Aug 2023 17:52:29 -0400 Subject: [PATCH 35/36] Docs: add spanish readme translation (#2812) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * spanish readme translation add spanish to readme remove line * change Spanish to Español * Add links to README.es.md to the other language translations --- README.es.md | 167 ++++++++++++++++++++++++++++++++++++++++++++++ README.ja.md | 3 +- README.ko.md | 3 +- README.md | 3 +- README.zh-Hans.md | 3 +- 5 files changed, 175 insertions(+), 4 deletions(-) create mode 100644 README.es.md diff --git a/README.es.md b/README.es.md new file mode 100644 index 00000000..47c93228 --- /dev/null +++ b/README.es.md @@ -0,0 +1,167 @@ +

+
+

+ +

+ Construye aplicaciones de escritorio usando Go y tecnologías web. +
+
+ + GitHub + + + + + + Go Reference + + + CodeFactor + + + + + + Awesome + + + Discord + +
+ + Build + + + GitHub tag (latest SemVer pre-release) + +

+ +
+ + + +[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · +[한국어](README.ko.md) · [Español](README.es.md) + + + +
+ +## Tabla de Contenidos + +- [Tabla de Contenidos](#tabla-de-contenidos) +- [Introducción](#introducción) +- [Funcionalidades](#funcionalidades) + - [Plan de Trabajo](#plan-de-trabajo) +- [Empezando](#empezando) +- [Patrocinadores](#patrocinadores) +- [Preguntas Frecuentes](#preguntas-frecuentes) +- [Estrellas a lo Largo del Tiempo](#estrellas-a-lo-largo-del-tiempo) +- [Colaboradores](#colaboradores) +- [Licencia](#licencia) +- [Inspiración](#inspiración) + +## Introducción + +El método tradicional para proveer una interfaz web en programas hechos con Go +es a través del servidor web incorporado. Wails ofrece un enfoque diferente al +permitir combinar el código hecho en Go con un frontend web en un solo archivo +binario. Las herramientas que proporcionamos facilitan este trabajo para ti, al +crear, compilar y empaquetar tu proyecto. ¡Lo único que debes hacer es ponerte +creativo! + +## Funcionalidades + +- Utiliza Go estándar para el backend +- Utiliza cualquier tecnología frontend con la que ya estés familiarizado para + construir tu interfaz de usuario +- Crea rápidamente interfaces de usuario enriquecidas para tus programas en Go + utilizando plantillas predefinidas +- Invoca fácilmente métodos de Go desde Javascript +- Definiciones de Typescript generadas automáticamente para tus structs y + métodos de Go +- Diálogos y menús nativos +- Soporte nativo de modo oscuro / claro +- Soporte de translucidez y efectos de ventana esmerilada +- Sistema de eventos unificado entre Go y Javascript +- Herramienta CLI potente para generar y construir tus proyectos rápidamente +- Multiplataforma +- Usa motores de renderizado nativos - ¡_sin navegador integrado_! + +### Plan de Trabajo + +El plan de trabajo se puede encontrar +[aqui](https://github.com/wailsapp/wails/discussions/1484). Por favor, +consúltalo antes de abrir una solicitud de mejora. + +## Empezando + +Las instrucciones de instalacion se encuentran en nuestra +[pagina web oficial](https://wails.io/docs/gettingstarted/installation). + +## Patrocinadores + +Este Proyecto cuenta con el apoyo de estas amables personas/ compañías: + + +

+ +

+ +## Preguntas Frecuentes + +- ¿Es esta una alternativa a Electron? + + Depende de tus requisitos. Está diseñado para facilitar a los programadores de + Go la creación de aplicaciones de escritorio livianas o agregar una interfaz + gráfica a sus aplicaciones existentes. Wails ofrece elementos nativos como + menús y diálogos, por lo que podría considerarse una alternativa liviana a + Electron. + +- ¿A quien esta dirigido este proyecto? + + El proyecto esta dirigido a programadores de Go que desean integrar una + interfaz HMTL/JS/CSS en sus aplicaciones, sin tener que recurrir a la creación + de un servidor y abrir el navegador para visualizarla. + +- ¿Cual es el significado del nombre? + + Cuando vi WebView, pensé: "Lo que realmente quiero es una herramienta para + construir una aplicación WebView, algo similar a lo que Rails es para Ruby". + Así que inicialmente fue un juego de palabras (WebView en Rails). Además, por + casualidad, también es homófono del nombre en inglés del + [país](https://en.wikipedia.org/wiki/Wales) del que provengo. Así que se quedó + con ese nombre. + +## Estrellas a lo Largo del Tiempo + +[![Star History Chart](https://api.star-history.com/svg?repos=wailsapp/wails&type=Date)](https://star-history.com/#wailsapp/wails&Date) + +## Colaboradores + +¡La lista de colaboradores se está volviendo demasiado grande para el archivo +readme! Todas las personas increíbles que han contribuido a este proyecto tienen +su propia página [aqui](https://wails.io/credits#contributors). + +## Licencia + +[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fwailsapp%2Fwails.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fwailsapp%2Fwails?ref=badge_large) + +## Inspiración + +Este proyecto fue construido mientras se escuchaban estos álbumes: + +- [Manic Street Preachers - Resistance Is Futile](https://open.spotify.com/album/1R2rsEUqXjIvAbzM0yHrxA) +- [Manic Street Preachers - This Is My Truth, Tell Me Yours](https://open.spotify.com/album/4VzCL9kjhgGQeKCiojK1YN) +- [The Midnight - Endless Summer](https://open.spotify.com/album/4Krg8zvprquh7TVn9OxZn8) +- [Gary Newman - Savage (Songs from a Broken World)](https://open.spotify.com/album/3kMfsD07Q32HRWKRrpcexr) +- [Steve Vai - Passion & Warfare](https://open.spotify.com/album/0oL0OhrE2rYVns4IGj8h2m) +- [Ben Howard - Every Kingdom](https://open.spotify.com/album/1nJsbWm3Yy2DW1KIc1OKle) +- [Ben Howard - Noonday Dream](https://open.spotify.com/album/6astw05cTiXEc2OvyByaPs) +- [Adwaith - Melyn](https://open.spotify.com/album/2vBE40Rp60tl7rNqIZjaXM) +- [Gwidaith Hen Fran - Cedors Hen Wrach](https://open.spotify.com/album/3v2hrfNGINPLuDP0YDTOjm) +- [Metallica - Metallica](https://open.spotify.com/album/2Kh43m04B1UkVcpcRa1Zug) +- [Bloc Party - Silent Alarm](https://open.spotify.com/album/6SsIdN05HQg2GwYLfXuzLB) +- [Maxthor - Another World](https://open.spotify.com/album/3tklE2Fgw1hCIUstIwPBJF) +- [Alun Tan Lan - Y Distawrwydd](https://open.spotify.com/album/0c32OywcLpdJCWWMC6vB8v) + [Alun Tan Lan - Y Distawrwydd](https://open.spotify.com/album/0c32OywcLpdJCWWMC6vB8v) diff --git a/README.ja.md b/README.ja.md index f308fd75..85fbc48f 100644 --- a/README.ja.md +++ b/README.ja.md @@ -42,7 +42,8 @@ -[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · [한국어](README.ko.md) +[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · +[한국어](README.ko.md) · [Español](README.es.md) diff --git a/README.ko.md b/README.ko.md index 441b77f6..a87fa326 100644 --- a/README.ko.md +++ b/README.ko.md @@ -42,7 +42,8 @@ -[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · [한국어](README.ko.md) +[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · +[한국어](README.ko.md) · [Español](README.es.md) diff --git a/README.md b/README.md index 5910be65..dfb84a01 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,8 @@ -[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · [한국어](README.ko.md) +[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · +[한국어](README.ko.md) · [Español](README.es.md) diff --git a/README.zh-Hans.md b/README.zh-Hans.md index 5afce335..de306f8a 100644 --- a/README.zh-Hans.md +++ b/README.zh-Hans.md @@ -42,7 +42,8 @@ -[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · [한국어](README.ko.md) +[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · +[한국어](README.ko.md) · [Español](README.es.md) From 7fae22b50ceaa4750663f2289957dee0a1f5bdb9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 12 Aug 2023 13:07:09 +1000 Subject: [PATCH 36/36] chore: update sponsors.svg (#2819) Co-authored-by: leaanthony --- website/static/img/sponsors.svg | 44 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/website/static/img/sponsors.svg b/website/static/img/sponsors.svg index 039fdef7..87116845 100644 --- a/website/static/img/sponsors.svg +++ b/website/static/img/sponsors.svg @@ -35,59 +35,59 @@ text { Matt Holt Buying Breakfast - tc-hib - - - - Liam - + tc-hib + - Tai Groot - + Tai Groot + - Michael - + Michael + - Bironou - + Bironou + - Arden - + Arden + Buying Coffee - + - + - + - + + + + + - + - + - + - + Helpers