Flow.Launcher icon indicating copy to clipboard operation
Flow.Launcher copied to clipboard

Add internal model for plugin management

Open Jack251970 opened this issue 6 months ago • 14 comments

Add internal model for plugin management

Let us do not rely Plugin Manager plugin for plugin management in Flow Launcher. Flow Launcher will get into a very bad state if this plugin is deleted (plugin store page will lose ability to install/uninstall/update plugins).

Resolve #3555, #3236.

Additionally, now we support to select local zip file to install in Plugin Store page.

Test

  • Install/Uninstall/Update plugins
  • Install plugin from local path in Plugin Store page
image image

Jack251970 avatar May 22 '25 09:05 Jack251970

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:x: Errors and Warnings Count
:x: forbidden-pattern 22
:warning: non-alpha-in-dictionary 13

See :x: Event descriptions for more information.

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar May 22 '25 09:05 github-actions[bot]

🥷 Code experts: onesounds

onesounds has most 👩‍💻 activity in the files. Jack251970, onesounds have most 🧠 knowledge in the files.

See details

Flow.Launcher.Infrastructure/UserSettings/Settings.cs

Activity based on git-commit:

onesounds
MAY 2 additions & 2 deletions
APR 104 additions & 38 deletions
MAR 10 additions & 0 deletions
FEB
JAN
DEC

Knowledge based on git-blame: Jack251970: 26% onesounds: 21%

Flow.Launcher/Languages/en.xaml

Activity based on git-commit:

onesounds
MAY 15 additions & 2 deletions
APR 45 additions & 23 deletions
MAR 8 additions & 3 deletions
FEB
JAN
DEC

Knowledge based on git-blame: onesounds: 43% Jack251970: 11%

Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml

Activity based on git-commit:

onesounds
MAY
APR 130 additions & 69 deletions
MAR 43 additions & 62 deletions
FEB
JAN
DEC

Knowledge based on git-blame: onesounds: 62% Jack251970: 13%

Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs

Activity based on git-commit:

onesounds
MAY
APR
MAR
FEB
JAN
DEC

Knowledge based on git-blame: onesounds: 36%

Flow.Launcher/ViewModel/PluginViewModel.cs

Activity based on git-commit:

onesounds
MAY
APR
MAR 13 additions & 1 deletions
FEB
JAN
DEC

Knowledge based on git-blame: Jack251970: 43%

To learn more about /:\ gitStream - Visit our Docs

gitstream-cm[bot] avatar May 22 '25 09:05 gitstream-cm[bot]

Be a legend :trophy: by adding a before and after screenshot of the changes you made, especially if they are around UI/UX.

gitstream-cm[bot] avatar May 22 '25 09:05 gitstream-cm[bot]

📝 Walkthrough
## Walkthrough

This update introduces a new static `PluginInstaller` class to handle plugin installation, updating, and uninstallation with user prompts, error handling, and restart logic. It adds related UI toggles and localization strings, refactors plugin store and view models for improved async handling and null safety, and enhances plugin ZIP validation and source checking.

## Changes

| File(s)                                                                 | Change Summary                                                                                                                      |
|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|
| Flow.Launcher.Core/Plugin/PluginInstaller.cs                            | Introduced `PluginInstaller` static class for unified, async plugin lifecycle management with user prompts and error handling.       |
| Flow.Launcher.Infrastructure/UserSettings/Settings.cs                   | Added `AutoRestartAfterChanging` and `ShowUnknownSourceWarning` boolean settings with defaults.                                     |
| Flow.Launcher/Languages/en.xaml                                         | Added localization strings for plugin management actions, warnings, confirmations, and tooltips.                                    |
| Flow.Launcher/SettingPages/Views/SettingsPaneGeneral.xaml               | Added UI toggle switches for new plugin management settings.                                                                        |
| Flow.Launcher/SettingPages/Views/SettingsPanePluginStore.xaml           | Added button for local plugin installation with tooltip.                                                                            |
| Flow.Launcher/SettingPages/ViewModels/SettingsPanePluginStoreViewModel.cs| Added `InstallPluginAsync` command for local plugin installation via file dialog.                                                   |
| Flow.Launcher/ViewModel/PluginStoreItemViewModel.cs                     | Refactored for null safety, async command handling, and use of `PluginInstaller`.                                                   |
| Flow.Launcher/ViewModel/PluginViewModel.cs                              | Refactored delete plugin method to async, removed unused property/imports, now uses `PluginInstaller`.                              |
| Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs           | Improved plugin ZIP validation, added error result for invalid ZIPs, enhanced source URL checking.                                  |
| Plugins/Flow.Launcher.Plugin.PluginsManager/Utilities.cs                | Simplified plugin.json extraction from ZIP archives.                                                                                |
| Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml           | Added localized error messages for invalid ZIP installer files.                                                                     |
| Flow.Launcher/ViewModel/SelectBrowserViewModel.cs                       | Removed unused using directive.                                                                                                     |
| Flow.Launcher.Core/Plugin/PluginManager.cs                              | Changed plugin install/uninstall methods to return success flags and show error messages instead of throwing exceptions.            |
| Flow.Launcher/App.xaml.cs                                               | Added async call to update plugin manifest before plugin initialization on app startup.                                              |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant UI (Settings/Plugin Store)
    participant PluginInstaller
    participant API
    participant PluginManager

    User->>UI (Settings/Plugin Store): Initiates plugin install/update/uninstall
    UI (Settings/Plugin Store)->>PluginInstaller: Calls async method (Install/Update/Uninstall)
    PluginInstaller->>API: Show confirmation dialog (if needed)
    API-->>PluginInstaller: User response
    PluginInstaller->>PluginManager: Perform operation (install/update/uninstall)
    PluginManager-->>PluginInstaller: Operation result
    PluginInstaller->>API: Show result, prompt for restart (if needed)
    API-->>User: Displays message and/or triggers restart

Assessment against linked issues

Objective Addressed Explanation
Fix NullReferenceException in PluginStoreItemViewModel when executing plugin actions (#3555)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Addition of UI toggles and settings for auto-restart and unknown source warnings (Settings.cs, SettingsPaneGeneral.xaml) These settings and related UI are not mentioned in the linked issue and are unrelated to the specific bug fix.
Addition of local plugin installation button and command (SettingsPanePluginStore.xaml, SettingsPanePluginStoreViewModel.cs) Local installation feature is not referenced in the linked issue and is outside its scope.
Addition of new localization strings for plugin management (en.xaml files) While related to plugin management, these strings are not required for the bug fix in #3555.
Enhanced plugin ZIP validation and error reporting (PluginsManager.cs, Utilities.cs, en.xaml) These changes improve robustness but are not directly related to the NullReferenceException fix.
Changes to plugin install/uninstall methods in PluginManager.cs to use success flags and user messages instead of exceptions These are broader error handling improvements not specifically required by the linked issue.

Possibly related PRs

  • Flow-Launcher/Flow.Launcher#3786: Modifies UninstallPluginAsync method signature and usage to handle success status, related to plugin uninstall improvements.
  • Flow-Launcher/Flow.Launcher#3170: Adds new user settings and UI elements for plugin auto-restart and unknown source warnings, refactors plugin install/update/uninstall flows to use a new PluginInstaller class with async methods, and updates plugin management APIs and implementations to return success booleans; closely related to plugin management refactoring.



</details>

<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between a63c8b036bd4c29dd0355b39ccadeda5381f7880 and 236bff1c109c359905a1d416da04a5a00d6840df.

</details>

<details>
<summary>📒 Files selected for processing (2)</summary>

* `.github/actions/spelling/expect.txt` (1 hunks)
* `Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs` (13 hunks)

</details>

<details>
<summary>✅ Files skipped from review due to trivial changes (1)</summary>

* Flow.Launcher.Plugin/Interfaces/IPublicAPI.cs

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (1)</summary>

* .github/actions/spelling/expect.txt

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)</summary>

* GitHub Check: build

</details>

</details>
<!-- internal state start -->


<!-- DwQgtGAEAqAWCWBnSTIEMB26CuAXA9mAOYCmGJATmriQCaQDG+Ats2bgFyQAOFk+AIwBWJBrngA3EsgEBPRvlqU0AgfFwA6NPEgQAfACgjoCEYDEZyAAUASpETZWaCrKNwSPbABsvkCiQBHbGlcSHFcLzpIACIAMXgAD3sSbmdqeHwsfAAzay9sIngsAGUCf3QMeit8woxkAFlMNFI+bhqigBpo+2wBZnUaejlIbERKSAApNAYAawAmAFYARgBOAHYABnRkW0gMRwFxgGYFtbmOlAxcCkVsBmkKy5oKDDRfZkUSX2z8PmYm2pEHjtOqQADu6gQWFiXnwYMgABk0NgMAxYJQNDB0ZB/kV+MJROIpChkAQ/CQPsTcNilNwyEpUfJMmFsSQEs9Xr4AAbVAp4xqvFpcyAACm4zAAlMC+Vgfq0QTiART2Bc0MgYXDEcjUei+AxsBR/FcvPIKEgZsh2JQikDMCM6rgVJF7I6aChctTUG0ZSTIEpIoNACgEiDpDHg2XgDDeJou1I83tqLt+8eaHjB+G89FhYxZHhU8C86nkZKKiEdPguKNL5a8F1+I24tGo8ZBiExcFQaMwpHQtFo/kQY2QSAcDzMJwWCwq9HHcyOADYNEYANIkeTZEjUA0PHK5htNt1FBj5JQ9bjcX6hOWXMvRm3S2rIbI3ZjoSCwqO+ABe8G4kAjzq0PA/hiCaLI3AUsB7ryialMmPCppiACCfbqBknIxpASFWAAkv+KJiOhyD+F4zb0GSCZ4v8grKlceyav4uAGlgEhvMEw6VJG6QYECYLonGfDVtG6SZJWGBCT4IkYHWfDYI2zb8HSVDiJkyBgpQHgOAw9yDtk3gXGQTr3ocuDPC6CmwJgtCFjxS4GNAIT3kwUj+PQEk2UQYnuTaqqVPu3FApRdQXEeJ73t5PEPqW/4vm+H5vAh1K+fQSlyv0kVxjm0wqaCzDeOIbQeOIbDIEwdSiHgkhfPIELUhmoQDo6FDiBl2JoOehZRjl7bYrsoXYEoyCIAw/hkIgsD4LgyBKB8DrKfecZ7CQ8JBYqNFsHRRTPNk0x5n5emojlbxFnZ7jWHYUZYIc5ISPAy1RNQXCwKZ3CIBwAD072FNSvQaEwzDvRqYJgEiBG6oDsJghooM6pQ73cN4XjvScZx2RYkAAMIsBtU09E4LhuNi/048gzKesgCM+OSQQhH6+D6jjb51RBRBQf4t3LdOKDPOkxL+BG5CM7w9PSBxEj4F4t2tfGZr/C4N13epfBCEIYJzAALLGvV2MizOTNM8zLOsGzJXuussGRkACJNkBckwShUKo6jaFydlQAAVO7OHieICUjuxXMRgk0gcJ7kCQAY4c2CQHNK5AKtq+rKAMuIEZRGMLkJcLAiRMwb3oNkZlVg6d7Szwr5BVrmllB4QH0BgNsbrgaJRaCKLiO8mDYNGpokM+0jorQADcN41u9xe3lT+BKVJyC3Wg5d+vA9c29c8BEC0OAEP84gMOSt7NdN0jcOoRXYtPOVWyQ96GTndAj5QNx/KLqZqeiWARUC9YTzWC3YogaA2CtxxPlX8zpioPFqhNPA+8motV4hpS4ZVEBIBoHRestA5KdTIiPKyLozSRS2pQC8pFL6P1+MgdqdJnBRDxA3VOXFL4lQAaQNsWI8x4AmnwNAfYBxjHIuiHMww2RtEjOoMCckDx/xbD6ai4ZabMioe+fAPCLjHmcOGWQf9qCwOcKEC+RF/z1nFCAssV9kihDxItExQVACYBENEgpkbQU0wF8UU9C9ykHIFQXwQMLHwMQBKEKzBhZSyBMw1MkBLKVA8mEfA6BxbLz9FgxhHh6HhkYURU2TBDSEnvOkiMXV0JhHEdIN2kBPYADlJoZKKcyCJPZ4AhJuFIEmXNGp6MUjlUqpEzSFKkqHd24dI7sIVvdPg/gaZliiF2HiDwyQFMyWTUppJ4kmTMvzSIYhgG3hoIgC4WkoJqkYNEwEMRYjaF8CWEuVNgBBT0N0Mk0Q7kgj0L6N4/geHyHcnQbo151FmlwLIHqHC9ZNMKjjKImUPCzNYUYvg1tqR7jLPBPBNiFSLLqXUOy4d3DlDBMcsqekUGKOtjAyyYSwjpmSKkZSHgOnNS6URQMmQPDXkWn4ohLwEoovKIgWQ0zXx4MwJNXU8K9zoplCCreXDIAiNIkUKFgiPAGNUskCgxIgLZA3EaUIZUaDskoX5Ghyiuq0KwFqnV7B/HOIQuQLw+yrair9H3ZEXh4FxPoro5q0r2aK3GJM9igxGCRBoXwcIkRVlLzLDabASAoLQqZapC4fFIwJrapwjBfdH5QviYtP14zxWkPGGWAhQJJHNjYWdAtcdmijXIvEitbpFqlttWSdZ4xLUaSuPABSi1VXYqMB7d2ME8SjHzIWIFBci7iRub4KB9VvWcDDhHcOSFGCAq4r4f2aZjn+AvM1KIfFEE/1LraYBUC9wNzAAy/R3AyGvDvlmPuoRrEKhjVTcdd9RRrw3sob9wx1CUMIsyGYa50wUFoEExgyIUFlxpvLCElRNTttECwDwKIBwXjqFVcE790CmQpPehajaczUh0WB2QEHaDSt1rKooaEe4KEzPRBqKQbiYPuCyVAeDA0hCiEoR0BYoj7o43cS+0zXpczGE4niVbsQ1vGKE5eD1yTC04/Ab9UYcyjGkU6/AMw5YWmAXgmaqlriW0Wju8EkJHiYCaZbAA4jhWIOLRl0frA4P90yBE6IXiRS2uwRTjjWCsBY0HU0t3BS0h4HwtV3RSgqaiqYcYXH6KzUI6IvDcAuAIGB+aY7+r1JkCMFA2ACI8NZpSKCfO0czXwYtfAg5KtQNZvEuxxwAA4NhzHKZ7AA8jxfA95mtGvoGwCgPYiWdTY4gCWlVMiDOGbijNesDYNzBJEWgpBfOhDm0AndjrDnbGAV+gsRZp3jFPVTBdMDb0pozF4IYbLEjmppWkN0th5P0sK4WvjPmzb1c9QOCWxIJtTZKzNyhZo4NAmfCwckxaqg2CO6GWpTH4evg60cULCw6trcIlIMCWHMhKAbf+EgdABAGzUb0jJAnpDrwtaIJAWSubgtzlaego3PXRfwMSVayXSCMxuHlss5BBynVgCzaBr6aRIH1IOdCVcZX1l479uObJYUM6E1tinVODb8CwOQvg0TrI+RGGMPgmLZ4XFvVfClGQKCm1WrsmFqlUFkAYMC0ZZUXIAMvv1Mn9gRqU7qBNXGwrxI7yiM52Iw4fCjAsx6grB7g2Ha5nGYC+95vdUgMUdDJJRxqUQUoHVrlPV6SYuUL7du+5bI9ZkIgw3Ir80VYzXcVmriUE5MAoXtFQhxa+NKxFtt7b/rUEJ4Ubw5s8EoGlB6WBzYx+54jMZ8IdEtrgfwD02JhY6TbEOsAhgDAmCgPSHfW9CBeOUMG4m7AuC8HxCIQnDxhjj8dpPrQOh9Cn/AFADsYcI1K/YgMgW/GZbGB/PwNAeEBwfGeQd/T4T/dQb/XQY/IwP/UwAwIGaGbUNEDEb2Z8NUa4cTbcd6AAVSt2KEcQCXemoNkyIDbAYDegMGiDYIMHRiQhwlAO8UtjgLliZFyG10QDcGpXIHhGtglk3CwGFiUnEEgUQR4WDzJEWi5HoICWFHUUHC4C5CQjwHwGjgPlwCQkLkoAxlORtGFEvQXjLzdVCFYnyBVVyC5B2gdRIC5FNjUImjBHIIwBmA2wwALwNHuAAHVnBZ0iArDbMbDXV8pIAHDghL8uQSD3DMQAAhZ1E1FBEJZ0c2MADnAfKIWQygeQtSSERdJQtCTIBKWEQoPeTzFTOVbVQkNhapfgASE5bseZPNImUiQcfgQSXGQ4R3esJWDwf4JQNGSwJCd1W/QxFQmkUQXpWeS/ERS8KIYxXoTqOVHtUoodawG4OQ+QJQugHQhGHOSMfTXwPQggQwuBEw54cw7se8AAb0gFIFwBHhkxHgAF9IAABef8GfEgIeYUPELQ5ANQmg5xMErALkHAmGfAigDQQgqgUtUg/wDQSgygdQ5xDQXEuTP6RALkAwKAKwQ4ko44vsU422c47YyQ3wYobw3w/wuEQIjMCgUI8I1494xxL4vkyAP4wElI0Ey4ENNUSEgkxg2E22BEvA3UFEjAIg9EsQbcLEqg6EwkqUpg4k1g9g0krAuUsGOGJEHibuVhd6MgDQBIQBLwDgPU6IDg6Y7gm/Olegfg5wQQzouZEQ+ybEJtPMPsZAPKd1MBNJTmAAUR4kLHGlNWOi/CknwTbR6I8D8URLFRB2CNrkjCOnlgC2DQoiSyVEZjwVGHGC5WymKUvVWmEMxBwksSuDEx0kgEoyfHrFvliWX3SD3ntzQFMPlB9Hciki8jnWHIGP8ngVVFhEikvQIAlgKktASDaG0AiNzBzAHTYRQiAiOl8FbTkwUBcnBG5P3OvE/lbifFihRFZLBCwDmyzLYW9glXfTyVEiWlgLXn3OU1PBNxxBfjhWvB2mE0S0HNHMvlLNnUnlIWV1/MHFfkuCAiKUikF0UHR0vkDWAnvHuxxBHHvHrCKAcKSSCg0CEDmw/iwB/D/AAmkFNkwVETNWAX92KUExfIwDrKwDfR9F5U0hYouHEKTM/JaUaIaQeGvBN2mgNHvFWiHJyhHMgrHNLPkknJ4BfHvTbNkitwUCVOAh3mKWuUgtkprBkgnJkUfFNi0gPxgpYQeCKAQoChZD8yXV9HQorz7LMhrNOTKXYXKBNRn3iT3MYPFTAxSEkufIYMdRsLZNhB4XvF2VGEstTFNhiOGjNGI2ZE71Wwtl3kcuGLQFujV37J2RrkUjmNUmQlQh3P4oCqUL4XiOOikTStyFWgov/GEzGzjN8CktAt0vwHnN/FaPiTZFQXvFbPBEQX8EpA2O4VmNcimKwmmpWIWNriWI+0MV3DWMPXoE2IuL3nYDQmkH2LaOEM9XWuDS2u2N2tKIAHIXUAVZ4R5MgwJKjulL9/Kc8syWy1w2qEjrL2LsR4pCwEy0LpAOSuMELcz5ARQuQrSbTmAvAuQJQlw2DHSDSwAjAjTYYKA6DNSiArBX53oAA1RWRALGsK3G8gRzMAnxa020+0pGp0rCF0ymvgxwAQy/YQowddPiqMSDd4iCP8AlShak8nRaV0nlbGlxcgSAcgnCC4C8FBHKKIQ4OUM+DwQamNSKaIMYZwNEAAES+DQFkG6G5voCID5p6lQD4tNozD/H1RXNJGpQIA3mdEQFqhbmNvzlZRKQiCiGiHNjuL0QeLMIsJ4m6GsKX0HHpl7XTzKkzx6tDJyythsvClxkdqIGdtdCKniShLCo0BuIMJCADv7KeJ4ksJHn7Q6IjR9vGjhBZICKCM5JIDCJeBtFDtsyA34BvJQBjrwTnPjtyyTsIRTvwCdurj7Szu1PxOZL8LrpBsbuPMiPSOdVTsjSiVyo8GiA7JIG6DwWiCAgATvm6FIkOAdXFSzz4EUT8hyFyDd2ImPjySJ2BXMGmPmuesWpuuWOerWqXPWM2taC2MuIurul9KgGqXIGlW1yN0eqDLfKlrwi+AHw4kgAAA0kJ6gEQbM6oYE4tNF7xMB5ATrJrPBtqdjwh5AlBbrulEb9SIBUbsDIZcDjTMbCblp6hPgkZR1Aia56yKRmGwRWH/QiTab2DODGbeDg0PT5Zdx2a/SPAeQQQ4J/BuHmBeH+GvhNC+i1I91XUxBkxyd91SIuNFo8pHRv0uQAB9IKYUNOJ7DBhNalT5WgB69cO6J7fOcx8Qjh4UEUaxCUugfImQkEKUPBcxiWWgDh3G4CLxxafUXJY0b5OdIohURiM0GORW+QHCHWhGuajqik5qeQD454ZADbTSmrNBCIXuK1VEWRsxjxkEYUesEJp7cJ7QCgWE6ZHhS/ftGx6x3+tTTcYNQXJUPUaMb7W2JEY+72SCugafPyLkcZr4cgxS9w5S6eEooBy3ap0J5pyJ8VH5d0jOrmRi5kf6WlJATIKXWRjGZsZvFwYUYovJ5ROoo85AAM8nMs22Gp5aTxrmRpsJkECJ1pkpz3OJ0eTcTa3fFVbplx+gdXahAZosmiYZnwQ/GR22JkuELGJwSoAARWCFud/LqnoAFs0pcmDUxzfH5R1BuAbjisSXG0cQmnJztDVFkCpcyAzElO8MxeoloFxcoFkCQkpYYGFEYmYlwdtmgDVBmFdkgHrPonhD3tSGbkEStjVA2N+tkcrMyGFFerJE/F8E9vStGm2FZbRGpY5fMiyrYEJdJjhI4cmZrEoC5B0IdejA4aQkqHMNEBmH9uakFdNY8Ntl8Pcndc9fRFmF9eMKFcDYacWYPBIFDdoC9YjYLr9ejdlolL0yoUOLNAUlWgPAXkhs+bBG+YabMa2f+ZaY0HqEcR4WoDQHhulV4EKwtZyryvPqEODqBEWgQ2OL8mrqQ27exFxCwCQ0cfhGJfGv5zoDsn60zgrD3COq2ibLzCFel3ZbiuJjwTN1iWvE6v0vtHclNgDPQBA2ClsZQGaWnfoC93agcCgoasKoUnnnezpRaq+FoDUpgbwVCeAQLbsifrmp5lfpTPfpWrVS/rT0IbpIAd2KAf2KxjmnE2/iWdoB0I4YUZICUZUbYZFGxIoA4dbglGFGKYY19gBoeAcacffdcY+dqZlBmfoF+e2daaXDJNyanVebOP/r3leoyZI4YkcWYkhOLY4ZRJ1tdlJIONWYea49pJ48qsgEqUAWWeKdFZeBE/o9qA0GU7YEk/Y5k849Q+4+Ider1uSt/BygE/hHU9BHca+ZBA0HM5Gks/Qn0+k6OOMrQ/k9M4/KBBuK4Ws/JGrzs9E8c4C9+Hc/JMM/kDk65Bg94788gHxsoBJQwCC9s804c6lRS4oDS6i449i+M58+2NetNKIHNNU8E5C6y5Lcc/K8q4K5i685M9K6S5CJIAEHlqq5s6E407o+y+046669Pia887i4S8U/IIoC8B1sipUVoAy769C606KCxJm7m5vKisW7Y488pJa5K8uNeum68HrvuCxiUCW5q4G7q6lRO7O5IAu9SKk+i/G+K/i4U746YFxupCu+E5u7E5wm++oFgDG/24m4U4ZK1AmYScW/leC/++Y8rezxAEBP2B8DB9k/e8m6h/ma8DjebCC5OZoVq7E9y/y4vaR5lABerdrf/fJ7c929e/B+x8+6S6uZoBudkCC7LNJ7qZ+fLaaeR8BeQWBfKd25rcJfsCZy3HKG128/i7NFYjdDpfzy5exisj5ZcBFFeq1YwGI8gEACTCWkpXhSFl1EGAKVtXjFjXnFvFgVoVnXpLvXg3vEORmUTD7DxWVRuGqh5GmhtG+h9MuGHD/0d6Dh0P4fZgoRx0kRng8A90lmz0tmjy30s6S1ckCa0kf+V0S4+5qdd32oAUVMCgJCM91cKjX4OH8jNjNeVJmF+wNHQpVuS64DS+SjajdpZbxfOVEJKdV68MbmZ5vYNfesaId2aIaVa1xl22frOkDAPWgMBNkEEImyuEME2+14crT1LkOfsgRfxxZfmUVf5DMEf11ERjklkoqIclheNd812l4belqXskZl+/jd5ASVxAGYG9Zb+8afxQHWVxgFEcYiZI6uSxkwp5sQvbRTnggHZ6YR2NmU/p6iAggRymMGHwLg3Dqmt12NLF5hBRrAEsZ+hfIoK6x8AYhg2c6RNsmx9apso2AbC9hxUTDWs62joaVGoQFQ0BmA0MIoAEGFC6ZIoqA++pVlvoTVaApsVQsUE4EUgNAcABxjaFkFStiSS8NAbhnGp21ZqMxYDvMVA7kMP6q1XIAQ16aTdAG+1KTpLxn4oIiArwavBhmx6m8VeT/SAHvwX7wMaAHDE/uOxFAG9jeivSQGbyFaW9v+zg+fgf3cEr81+Z/R3q7ywAQlbYEfb3mwxlLwkg+8pEPokLD4JCWGbDIkiSTpoo1A+cIBhhjRJrwJcaFpSPg6lKHOIyaR/WoJh0qGCMHS9NLgvHzdJ4xWaUjVPoTBhSp9ewDfPiubzNYf8FAWLZ/sQLIFeB3W0bT1JIPFq1CMONcSoeowlIGRH0sSMsnl15xzo3wq0YYGMAbzisAAWjhCsAtVwE67SCG+CorFULUvaWoubWDIMtFAlwcWGBkoTKV/BboXZJcSyxKRbYFNXAPEEiCxAXwOte4cPWFA19bhHwzwXCCfDCYl4bwYepcEYwUdha/pK3K30gCbcMA23Nsk9koAXAAIzwXNPYG8KQN5AJws4VRXCp+RMuyKeBmIBv6IilWUENXMbj77yAB+QhTAPcC2x1lcgC8G4agAOGEg6AFwLkJMOmEMD9WkJe1gk2RLSiQQHrJNuG1oFGFz+wrbYZBSfI+ht2VkXIhgHkDkAD8yfW9NKi5q283IR8HJJbEvRcgAA2tHFIiyBuWVkAALpWN6w0tROpxFshYRyq6EHuCrg4GCpL+KQoocH2RJYxMS3zLfsfF2jQ5AyyhUDgIKBBCDX8/VOVAkCGqRQABn7ccvn3WZjEcQKFNODRkA5aCSqoIN+noPA6ghIOP9IsQp1MHANAxweAsSby+GrtTWQQmYLKyoEqjohURJFE6JdEG13RlQL0QRjXh5ZDwsQjRmi3mGuJFhyYZYWKUjFQxox1QniOUOkAE0MhXwYmtqQWHyMlhR4rwLkKk5bkiiDg0ela2eFMdeAPYy1kdyS6AjgRJAUESwHBHIiiATvMtF7UiAHIkuJI8YICTYIxDxS/RbOgEjPEe8Lx2Q/0MkPRpIldxONPGpUJPErjyAa4/wI0OYJ5DqGhpVIYwwwn7jiavDHCaTVXHnjkw1NWGjHxaGiME+HQ5Pl0K6K+lOanMNIngAIDG5OcdEYlicTcg4ZTwi0NWh6i4TwAvwmQcsPnkdCzBahVySyHqnkl21Cq8EfVDcBPpWJ/44tO1CQEeFWx+JzISyB8Oaz0B0Q68Z6JfiOCaw3wZoDLIqEmx4hdwSwE2FzDUCVBhwuMKcSlEK479lRMoAKVY1iiLRY4ZYgRrK1CC+VV6Hw3ugVCdQogMRtcVloAkuKZkG6tsdyAiHphvAOG0AOOgVBlZnR5xAk7EfqmtQ8ZIAsQeSUD2ZCXofgdEFBF+A8BLAk4eCNOrIG4BQRx8tsAAGRmAEgEZTrDrSQigkTJT1YpMuWbILwuanUGYE6Eqwx0KpiiWgEIF2h0Q36UkzCn3AHBHJ9oBYMyOtPPYdlxWfFTYaeyBpI4dRv8SKAvFWj/UTQmgl+joL3D1j5oEHQwd/Q2otjiGbYg6vEiOpkgjBAM86nB2kDXUvpKxUsRMUqy/VUAKDNBucOMnNCChBgDhsTTQkKkxO2M4vi0HegNc8a0NGms0Lj6i1xGSfSRp2y4lo0OSMDf6rJPThJdspzZUsaJNmHYgoyadeNO+G7CVc3qOUsGsGPljspeorYSAITKUwgguAuAalP5QpiCVTwC8SulzGEqI5LM8SJ6QqA+RgsEC18fMeWISyihogQUCxq2H7wUBLZMoMxtgwrFmMTcZjSutvT8jmyQQtsx8NbK9lFB7ZJsugE7MNC/B7Zf5LetBh7qKy/OgtfsKLEeD4U6qkAZqj8iayIjhohkM0PEhFAey7ZQURAD7ITmFhaAZjCii7NKRuz6AOc2oL7LqAFyMABFYuaXIcACBXZUoawsCF2gTRCRTWNXIlFgDSo9pkUV6lXL9l5yfZFsh2QliDlPxug6g6KGDC6I0YOxVRDCLIBVyDQXOqVW8mBPrCLRsZ0soZhemOSvMYoCOaIDLI7y5BP4BlM9OOSbT3g0yaQgco+EeTxJogkwm+VPFkhLM6pkMLUIw3PLxFe0jI7WlBDHZFDugSIMsJhEWgbyUql8CWaCkID25IB94YlpPJv6xRogedHSvq17hGFf5moaMZdkEhzobQ48AgWenHiKUQqMoRAK/JiCRtCF8IYhV2V3hMZXK5ZMhTxAoWfxqFUiJCgqBfb7yZZyJZGpwXelqo6xy1b6Y2N+lQdjBrYqGe2MOp9CwZf006n/UBnKKYZMiu6pSO/Z+QT5r1dmQoW8pC1xyGCsSXuGZmA1ikpitGX7yPy0NsZEMKMU/I0D4zWwoi8Pt4qGZNC6alMpmtTPgIp96ZqLI6koSBbTI6IDcxMngh/I7sRsxiJLCbKxSWs4qP7GeBJjuAWVpgNwfotJWgoBlj2lCySJfAgwzBsgkMB8nCUmH9YKABPGgFqMDYLx8Cswd5BYrJDMVtkg/JgXiFQBWKgFC8LkIhwNSaBsIOETxSCH4b05aAYoRzhk2I4jw+lFAYIL5DlTBzn4sFRpENG8JL4/IRjJ8Qj366bgZuPuM6FKLnTCguxnYDyno2W5vgGS0heCpkiHm5K459YQCvkH8DZJowqXeHu0oHHkwTlLENiJnRuqNFj0FdeJPvkpxLzigTSAsM4Ewhjolmv/O6UMNwEWtHQ3/R1AVhC61VHCSRMZWyAmW4QsSSzGURf19BAr747oIfgyNcJjAVcJ7OFf0QZFnLXpoyPLF4AHEns9e8Ra0GnGHBCiqYec9AOUCsUHJvCWAzZU/C74hcRswJBlXNgkFUBZgoqioPIFWgntzK8KiUaCuVVuEGVDcSWnXDYq2xo4UyXAE0pIAtKfmkwn8cwHymfgfuoPVUCPyphArOlweThXwDJUaqPUnVH4KfNfDUi0ZUaHdojIbmQBqRMgXuEqsenG4tl+8fKOwMmEPdlwARG5ccr5xSBkA5BGwOgziWXxhgtKWHHuCLXoNjkC8ItXhDwQuQcGZcCaGYkCDdwT60Qb6LAF+j/Rug1YMFpfnTGKdm2QcE5N61GZchKBkFB1V2KsE2DtwtK+5cDkeULxnldoJOohSBD6rBwfy8gVsJ9UgrbORKxIt0pZynhoVYqCiDcHuAztIAEZVNcJVvp3TCysiNJYmVI6ogTwKtYBAmPFQAoTo0sooLvN6kgzfgqg5kHiDaWQFNolCB1PEiDx3q52ygBdtE3km6T/wf8z9ceAGgPAuVia/7syG+WLqyo25QxAkqXKdR1AGza3DUn6TPVj0ATOhZKvGIBzemhcpJBGtpEsadiTAduBpErEtDJFtY3QXos/ryLmxZ1WDuEHg7mDjl862XnYPjYK8XxyvDwKr0mF4crchHSuIp3HZ4iFudAL8e6p8Hdi1NVxQcZBS02UAdNIIUCUBP03bcjNwmEzTKTiEkC6goi5IQTP8VES5NUvBTbYIO5+DzNQw/sVLTKVeAtRIoDhpL1YG6yZQpmkLQEL7Ff8ZgwABkm8mnU1hotsWunvWyI5ualxHmxAF5s3E+bEW14/IQHyxmtg3F24jxV4roU+LyCHcPajqWYlBKxG6cGmV6WkZnQBp0I5JndALV7gR5rFEipkG6DsBxZsUBeM1VAW4ZiW2RURBWMxDkkW2owVFVeGAhmIfgqUvcDNoQImiVOXMP3NfzcivodZinMkB8QlQg8q4WAMsrtj7meo7tkkxsscSIArlpUJ8gaZmPQGCAhMtY7EEcN/BIROSCAKQFGWuBMgCQ2yfYWcrRDJLw0rIT7YwOxB/rxtxFUiq3UwbqT65azDKH5SS71h9W94QETDvljNAftoyRqJ0z+rD1IwIUL9QNCcjqiUdXq3wKZmkDWh4yemCYMUH6yVI68I7fAfLzenaCpFomihgYJzEKKIZ0m9rUYFAYkAMZNW3GRiFjEkBfFMoXXbUEmEYho+FM50m0OZqhLOJPpDmjAx+F7x3NCoqZoC1ayNlbg9wcnP3mASFgNw3uY8CqmyWGIg84ULqq+Xvk8RSlRSpqZCH0mpk/5xCsgLdGpY4wgBTwEgKbUrQY7VauY9Wv51whcxrpqC/ctev5yNFrpwsPvo6mFim045+6S8BbgSWpqkltkHoTBMXJy0HgWKh/k8JtZxJ7SUnSYbsIVC38g22m/noIBfz6Imsc29qknN/Boy+5KaWzNdKJTaVEyQEf8Y6kc0LdV6MSe8CKED2RRLo/Ih9reTkhp5oMpa4pLuCaqz7qpVwOkfQF91dw/wneIjL8GT60jk9BKfrpsLfhkBR4t88lleQCL2BZ6MgNVptSwDVrx1mq9AN9urAtlgDjmdQAAAlegJmerIfigDZbowA+n0JeiX0lYV9YFY1FkC3krrgd45KdgLlCoBILgjeoEFrhSDPU0UKs+8NdI3AG5Zgu3O1bgcTDDBN90VSKN/ErULx/qaMhfUimX1lYxyh+r4MfrPBp5TYiSw0QoKMDewOQIYofrz12H3iTWbLPAUQJeHdL5uHTbjZegHRZwbgVe/ooq1dGKr5YtRS4syEYNbyHycU+DUgm/UfC/h4wLsWSCbXZBvkQolvkNFnpS1i1voa8ldHkBArwoV8wfNQHwLAZ7g96WPCgbQPVq2qOSEnL5Pun/LgKj4KXDLnqgq44h2hxaJMvFS+iKyZ7ZACKE1nWxg4FeqwzVTX21FAkFwWomchcPdIXc8+X4OlECgKgZOs8ZPVhhaI0abU+5Y7LWv0K4LHK/q4BJEqMXT02SIB96l/oiKjMdJEsTDZqDGjbhs+OiEY8wetiMpH9eIpkE9o0qyHyll+gNVsrKL46wgzkloPtKML4DTRL8M0K9KrHCao0sCsTXLvBlSadqyi/YreP2bdkW98QkEIbqd1wlNdMYhiU1oN2KjchGeoxD4DhCSUFOBYlguHCgAfdfO0JtLZZprDUD1RkbaLfh0I6rd9eJJQk4d0S6kmreIU2oKqJoHUnHer1Kiq5pGREnJutu8LdgZ8CUnvW3J01jFpmX5bHQ/AIXolsZO6BmTb4veGSbtXimU2mox3rSYxSDdOgeQGUHFoLbym/mip9XaRPcXkTKhWNBvGkRuBggrchElgoEtN1UyetFuumVboiUeVM+07bPhhn2D8JbYw6qQYKg0BwjHTopAHbhnJZzC7TDpp05eIxNUVMQbRUVOMAGn1hHDe8SeVihLxSqeE6MoTVLpE2fSgTP0+XZJq0WQyZNZg1XRadoZImNA2u/XUUDbMYBRFAS4Rm6eCUenOhXp1hM3qOoOydVCoL3aIFkC+61oKWa1PifIPMQriLyndRxFsplAOI7TcFvEScH1gyTt2WbPlDrxzSb4CQFI5fGpAOm0Fi+q3GAB2hhhIoP5J9d5LjovLMuTbPE0+MhIanhxAbSUeyaKCtLZmopqYT+ZpVqdHlXINLRlrjp6B6mfALkAyShEIbOI9FFc+OWI2YlBxQbKlaBeFYhQdteXPVOqK1WSSs9wahUDxi8AON5ARmB6MGTY0yr4RjwR82HMVX/dmVlWa+vgDLr4ZqAXA1SnkapiLQ+Kq0I5gcvoDXZVJmevMV/HIB14k1cOFVU0nKxR1qoDK6+B0UkxAkCwiAe6gJAhAsqh+RmAMyZnovxZF89ABkSkXfPEMrlkFb5sE2AvUrtR858C4SpbQfL+isVC8gjjPop7uUvgPjd3goC0opobFDQz4DXm2x/z6XH5k5dwu5ru9x6hC3HTgsSspW0FiWLBdBYdNdwqvBpmlrKnohe4c0zPWedWopqFVpGleXUZmMUw9ZVFg2dFLmVpYcKkUeLo50m3pcjKg87dadvrDiFZZPoMS23OvOUBbz0wG+I+rDlzxgFuhCleiz4aIAiAD6p+Jf2PUcXMQg2HoNpFFh6RArLAQqDJVzAEaXgLx4ICZPGjhhcYyhnfZFHJY9GPp662Ieht2PVLNQ+BjSjbkoZ/HSzAJxYrLsrMgmazSuvYv5ssEy8gtEPEk1lTC3qmcLMoXLTKcdAmnerDPV8rqZ9DiF0b0kRThRWM0g8ktQp3PnvDhsZXMtUtBGxycd55aUbBWtG6l2gqY3Ew2Nxm6+Ver42XNhNorRKVhNGmhmqEsiRjRbPJgOzHZrs35qgAWCXhgWxddDba7QmNNQ4mUNZoI4KhdNHN38ATepBE22e0JqHjFdVu2aZQ9m+8JzciCuaxS9umZQLc3HNnWzHDcW75t1JS35NkNuW6zxhuXEybwQ+K4jZpvI34trcXLHHT9NSAMOhkwEhxd1te3SbgQqCxTb9vU2pTtNoO7pqh5UG6hRQbUgCSBJuFoJ1t/m4i0FtWnhbDtkEE7cq1+aSzNY/60tUBtyL/LveNsaKH+SHWl+EuQJPsWlvul3b5QOLlyl7zCmlb9lkEEbfVt2a8bWtrm0lAs1ArZlFYpLYPZ5Qk2LNht5m3iA1tJdzbCbB7XPfVEL2EsBd4rbFtttu97botx26farsu3pZbt6wYpuC3L3dyq9n2wOKTtFAkbRp2UwltqAh3djmdjhs6u1L/3fAgD+RuLVAfQGZgh9ugEveCtD3X78d8mzBYi0htcL0p7+3TblPp3Q74DmUMA8gcWb8H9Qoh1D3ntsbj7vNjzWVvPtC2kSIt/wGLevsl8qtJEps/Q/BhIRzwjEq8cbtdMM0zdISgc96SHM+mui/Q4AjAW0DBoO9Iw/Vjv0mWUr4219+RGWGi2u9WAdAVS2BCVrwRSLMljAVcizosOWgipNESzOxkaOZSqhQbKUD0RyRhQqTOiNGuRJYhUABxgcHqOYH2YNwZiVACfL0flBOqFjuxa+WjA4nBFzG1/rtf6JGNfHtMISCCzkiQafY9w2SVJDTPxIMzDWJnQwAMgN6VDYe8cjse+B/zBlbGyXbXe5n139BQNjRdByUV1nfSqupxZjObOO31D8+JMe9FOE8clH/Dns4I/dOJ9PTojswWdC5R3nZGfT7apMv4GVBKA6kdBJcbpgMx2A8S/tn3Z+zuXepSm9PfufGdRouxOZkp69bKdFCgNDcYrLklqOjVCzEk+JEg1Rn3479/6unFOm6lUB8YByO4EcgRG5iMooGuo9ED4wuAW6nqUFyQDAC9sW6FwTWnSEKQMKEXLOJF0E3pEUhi9GUKgOdiHmpAdI0qSjPhEOjBjArfQk1NCIvOU4+8xZOc5+fh7HrnrO1iypuuoAUIdC35/27KOXXktILUrJC+le/6ZWvAsFv88rdqCaEeXsULkHSwFcpWJYgFpjh/YwAOr5eYawV9Kx34J2YLMrWMTkaAiRRnn6DV57jE5ldL4kcCzTCrSEQvm7Qx676tmJyeGHe7D92waTADVSA6IsMhjYoWmozsMCNd2RXXbA5BvViDTxRdouafd377C6/u+93hsqOMHqdk00FGNP1sLgG9pjX/anvcBtbsAJLdq6yuU3E3XL1EJg6L4/3W4abx0Bm5H0+gt7QEne5bYGXBXpn0VqwP09wgklXbAW7Z8FpHsUmx7mb4Ozm7zdJaDb4rooOPfreT3Nbubme/m5lJTPdo7bztzhG7d33e3rrj28pp0LqnItzl8t0UGre/3j3P9qByQ+zuR287YwAtyg6LfKuv7Fb7B6e87PnviHmL8OxA7Cq53o7S71tyu6lEdu5nXbxs4UIa3kTgPnUSZa6yqbdnY+vZ7raM5Ef9aFMjyoFHSFJi75jWk3So/OfzJkjBm60a1KWLVdkhNkhIZl3HO8uYhigTfLdJhCnVU3P7Mwty/9xGWFuRXbTGgLlecKFWWda53Bu/wMMnMAwVZaIkubtfSB010Vyd7FeJZqvyWtne8DK6f4CvlP7VxC7LVYOEItHa+74Z5afDwrqcXB/PEit6SMfH3rH6rux41fCvsrA63jxq8DasuPUcjkT+3ccTiekUa6211gAHAyezoqUygCaCcgjMd+pjp1pnxXL2h5edYVZ6Rbb0uvY37ejF7s8w/3P9ngwKp6G+kUN2sPVZ/6aCZIbK7wbMtvt/LcuIJvmwh75NwVtTfvvh3Dbs29PYtvc2jeKpzj1luY8quA7WDtO4HYLa1ubNE9k26O4XdUPYJUHyMDB5LhVMS7EHkodN4YCzfbwcHyW5u4hvbu43u7lUwO7dZDu63iYZr5FCbftffBOPUO+vaO+b3Z3291r7vZ1s82pva72D/cAW/FD0Jy31b46HW+32e70vbb1l5pLEnti+79B6W4YBHu33L7qt++4zufus7gRa93+46+g+qv97kV2g7k9Puz3sPhry+4veI+I7P7qO8CUm/yjXvc3973bc4dwxvvuEN78ZL83VasCrijp45wq0l94YnV0ip1sQ9sSJGfW7oai3zbSBN5geDVrSV5/as59iCw04+APmIth+inqfaLRfvNgSyZKBI4KFoWJgI9uNyS2ORQ7xso0C8D4Hyno97xLXZBojBZNknaI5cvOm6YYkujmJUoAxqIC+xbRI6wFkQnLwtRl11PG7wNohrWdK+tOwPBgDQN2t6DvQ9exNEMHIfIUiJCQGgXAOyH5/DO+zyHjiYObMH1SDQMDZ4HnEDDRAXRC3FaV0BiAsCC2+yboNEBCL1ArA1fnevjWKDQBkDNgHWtEEDBmvUxyKOkJgIfOnmmDhiGMg2T3CuxY/AgeP7UfehJ/h/RAS0kuTT8Z/cAVjYTCCiyhBi1UZKi/D7/0S5AQIw9cSO1KJZV8jjTvxvsn4P3qiXfkeqmEzlRRFNMgYANb02B5qizqi8sGbUAwD8gc5Zvl5huCusV5AyBgJH6s+tDDH6Qgcfgn4L+Q/h5DwwfFj3htg6/ln6tCIzuxK0yRzsOa+mShB8J8U/gKQBJASrByC2wAADoCAOEPTBUBAri2iIBklCgH9cNws9pWwxYNiBIGuAKgYCAN/kv4P+rFO44uIhGGdY7wSRodo2k2yJ3zvy9MNvQfCfEFITggVfClKVAnpFk7tEYqHmYrE9YFQYz4mXoqCTEAbhIp/WNTiG7aBEmkV4g2YJlG4QBrKG04a6dPpjTRc1hogAZEo0gkC8O8HixJCO/Znn64BqLKxC5s36H+psBZIF3IVY/+lUxJEzgXwhuBEZAkA2O2IF4Rwgs6scoKeUrgjiK8RAG4FyulerEH4ACQeBAZgrMIuhHKhLCZJGgmUjOS1qHUKbKi8MSugJQaVMCRAxwmAKEClWjqPvpDsMKJ8iXw6VIjJre9wAcjY03MKSClIYQGSqMWg7HuDgKYIBmxK4g9JCTRwaeDEGiwiVjPxv0eQdXopAtevdYEQx1ngjHg+AJWqLQswWKSqEAsD3DCgOcPTAzA6gU645maiOc57GcweOS3W5uNUFwapIoJq/W1Tnl7B+BXqH4mC4JrYFgMFpifhn4OxFuZ5EWASa5cAVALAS9a7AQoAOwKgF/jaAaBIYCQhxMOoBmMy8IgBmMimMXIEKv+JgRQAKwOrArADkurBoAywCQArAGwPOBzAnWMyEkA3WBsCdSKwDwgCAKwEsBLA84AsDaQnWMKFzADAEcCYhZIZABrA84GsALgAgGsCdYCwBsC8hnWLKELADkmsCbAtAOrDdYAoWcDZAcwPODqwSwAaEbAPCLkC/4kIUcCdYRwAwBmhfcNkAMAXIY6FLAJwCaG2hGwBsCdYtAEyFoAaAMqFLACwH2B2hTYEnCWh/+JADqwjIQwBzAKwNkAbAPoQwCTghobyH0h2QLQACASwCQBzAG4EsBih0oWsBoAJABsBrATYAvDhhEAJADzgAgNkBrA8YRsDxhaAGsAxh84J1jaocwCQCChTIQIAMAhwKFgmh2QJ1jqwRwMyGBhawBKGQhGsJ1gCAyoZ1idh6sLQArAJAPOBu6SgOrBshcYd1idY84HGGU4M4WgBMhtofOAThEYSQChYc4EuHBh6sCuHSh2QFGHyhAgIsA7hC4QsCOhSYQyFoAnWHmGOhJ4ZWGrADAF+EbAlIdSSU4KwLQCeh9IQuBrA8oRrAMA84J1KdS3WGyFnAcEb+FQAaABSHbhC4HMCfhGsAyE7htodpAbACwAyFJhrYU+GbgYoTaFLAAgFOAVhUALKEHh2QAIDzg2QAKH0hpYSyG2hC4R2EbAnXGeFsRqwK+Fzg0ETtDjh9EZACuhr4eBFHAg4d6EKhbIcJECAGoa6ErAK4QsDThxYQBFrAUYUoBLAaEYwBBhtAKsB9wRwJ6HTAYoWpExh/oTJFrAnXLRE5hCwH6HMhwoUaEGRnkurACAnkYaHdYRsNWHMRK4cOEjhpYdMArAAgLQDxhCwDOHgRhoceESRRwPSH0hSwLQBrAeYdOENhYEfOBHAGEQwDQR6wNMACAnWFyEHhDANqG0ARwBSEGRaANlEbA74TtAJRooUcA44OEc2Feh2QMsC0ACwHMA4RNIfOAkAlIZyEeAEkXOHzgaAMaG1RjoT6H8RCwNWFFROOOsA9hnkQeHXhZ4baHThTYe5ErAvYQlF9ko0V1FsRRsFhEchM4fOBKAPWCtFTRS4fSFbAEkUuHbhc4XZGyRogD1jTADkhsDyhW0QwAmhYEUqFBhTUfBHwR0oQZFZRSwNOGHAoMQqGdR64T2GihqwDKF8Ro0WBGMhJAJ5InAPIVFEGR64Z5EkRnXE2BARcwKDGzRZodFF8RaADRHU404WXgbATUZ1IGRPUeFFKhnWF9FbhCwJ1zwRM0RSEZhb0dBG0hDMeBERRtUQZElhFIc2GsxWYfKF2hKMZTiMhnkeuGyR0wGaGdYGEX3C8htAB2HAxSoWTEzRsofOBMh2QLJGuhfIRyGpR/IasCFhRwIGEshrYS+FDR6BJCEox2QJlF8RPIRbGgx9kX2QKhDAFGGhYRZp1HaQKwCsAExJYbbFYhEYUWFzA0YScC0h0EeqFGhfYJ6EExJAA5IpRawEGEixMYXZGLA4kXbERhdoX1GnRSwAeEsRtEQLFgRYobQBDhOOJ+HKRr4emErh84NGH6REkTZHaoskT2Emh/UesDShPobSHvRC4F9HGhpwByFARoWHOH0AEkTGEJRtEcRHGRuUYuGTgbEYqERx2qLeq8htYUcBeRO4d1GnABkVTidSSoarGdRdYQwCOxnURVE0hywMqGsRd4aNHVh6wDhHihzcVlEARM4XKHahMYWBEyRk4MpGfRvsbSHWhJoQqHdYdMXKHaoeYZ5JbRJwAHHERZMdqH8heMRfH+hCYdbEJhFoegSShOIbgB4hn7ISEa4gchfj6AQAA=== -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=Flow-Launcher/Flow.Launcher&utm_content=3572):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

coderabbitai[bot] avatar May 22 '25 09:05 coderabbitai[bot]

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:x: Errors and Warnings Count
:x: forbidden-pattern 22
:warning: non-alpha-in-dictionary 13

See :x: Event descriptions for more information.

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar May 22 '25 09:05 github-actions[bot]

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:x: Errors and Warnings Count
:x: forbidden-pattern 22
:warning: non-alpha-in-dictionary 13

See :x: Event descriptions for more information.

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar May 22 '25 09:05 github-actions[bot]

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:x: Errors and Warnings Count
:x: forbidden-pattern 22
:warning: non-alpha-in-dictionary 13

See :x: Event descriptions for more information.

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar May 22 '25 09:05 github-actions[bot]

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:x: Errors and Warnings Count
:x: forbidden-pattern 22
:warning: non-alpha-in-dictionary 13

See :x: Event descriptions for more information.

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar May 23 '25 05:05 github-actions[bot]

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:x: Errors and Warnings Count
:x: forbidden-pattern 22
:warning: non-alpha-in-dictionary 13

See :x: Event descriptions for more information.

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar Jun 01 '25 07:06 github-actions[bot]

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:x: Errors and Warnings Count
:x: forbidden-pattern 22
:warning: non-alpha-in-dictionary 13

See :x: Event descriptions for more information.

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar Jun 01 '25 08:06 github-actions[bot]

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:x: Errors and Warnings Count
:x: forbidden-pattern 22
:warning: non-alpha-in-dictionary 13

See :x: Event descriptions for more information.

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar Jun 03 '25 06:06 github-actions[bot]

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:x: Errors and Warnings Count
:x: forbidden-pattern 22
:warning: non-alpha-in-dictionary 13

See :x: Event descriptions for more information.

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar Jun 09 '25 12:06 github-actions[bot]

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:x: Errors and Warnings Count
:x: forbidden-pattern 22
:warning: non-alpha-in-dictionary 13

See :x: Event descriptions for more information.

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar Jun 13 '25 15:06 github-actions[bot]

@check-spelling-bot Report

:red_circle: Please review

See the :open_file_folder: files view, the :scroll:action log, or :memo: job summary for details.

:x: Errors and Warnings Count
:x: forbidden-pattern 22
:warning: non-alpha-in-dictionary 13

See :x: Event descriptions for more information.

If the flagged items are :exploding_head: false positives

If items relate to a ...

  • binary file (or some other file you wouldn't want to check at all).

    Please add a file path to the excludes.txt file matching the containing file.

    File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

    ^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

  • well-formed pattern.

    If you can write a pattern that would match it, try adding it to the patterns.txt file.

    Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

    Note that patterns can't match multiline strings.

github-actions[bot] avatar Jun 15 '25 09:06 github-actions[bot]

@coderabbitai full review

jjw24 avatar Jun 23 '25 11:06 jjw24

✅ Actions performed

Full review triggered.

coderabbitai[bot] avatar Jun 23 '25 11:06 coderabbitai[bot]

@jjw24

  1. After uninstalling pm, store no longer fetches plugin until clicking on refresh.

Fixed. This is because originally, Flow rely on pm to initialize the manifest. So we need to explicitly call update when app is loading.

  1. Using pm install/uninstall does not automatically restart flow even though the option is set

You need to change the option in pm setting panel instead of Flow general setting page.

  1. Store install/uninstall same plugin without restart shows error message error, should say already installed/uninstalled

Fixed. Now Flow will show msg when encountering those issues.

  1. pm install/uninstall same plugin without restart says correct message but another message also pops up to say it's successfully installed

Fixed. Now Flow will show msg when encountering those issues.

  1. pm uninstall same plugin without restart says correct message but string interpolation is not working

I cannot reproduce that. Please give the specific message.

Jack251970 avatar Jun 30 '25 05:06 Jack251970

4. This is not fixed- pm install/uninstall same plugin without restart says correct message but another message also pops up to say it's successfully installed. It should only one pop up notification to say that the plugin already installed/uninstalled.

6. pm uninstall plugin with option set to no restart, the plugin remains usable after the uninstall (can be triggered with action keyword)

7. Change the notification message title about plugin already installed/uninstalled from 'Fail to install ' to ' is already installed'. Do the same for uninstalling notification title.

8. Why are there two options for managing restarting after install/uninstall?

9. pm uninstall plugin twice with option set to no-restart also gives two notification, the correct one and the other is that the plugin is uninstalled successfully (and this shouldn't be shown because already uninstalled. Align behaviour with how Store uninstall plugin twice)

jjw24 avatar Jul 01 '25 03:07 jjw24

@jjw24

4. This is not fixed- pm install/uninstall same plugin without restart says correct message but another message also pops up to say it's successfully installed. It should only one pop up notification to say that the plugin already installed/uninstalled.

Fixed (I have misunderstood your meaning previously...) I have changed the API functions with return values to indicate the installation/uninstallation states so that pm can know if it needs to show message.

6. pm uninstall plugin with option set to no restart, the plugin remains usable after the uninstall (can be triggered with action keyword)

Will fixed it in another PR. #3791

7. Change the notification message title about plugin already installed/uninstalled from 'Fail to install ' to ' is already installed'. Do the same for uninstalling notification title.

Changed for both store and pm.

image

8. Why are there two options for managing restarting after install/uninstall?

One option is for Flow internal store system, and another is for pm plugin. The former is in the general section of setting window, while the latter is in the setting panel of pm plugin.

image image

9. pm uninstall plugin twice with option set to no-restart also gives two notification, the correct one and the other is that the plugin is uninstalled successfully (and this shouldn't be shown because already uninstalled. Align behaviour with how Store uninstall plugin twice)

I think this is fixed since it is the same as 4.

Jack251970 avatar Jul 01 '25 05:07 Jack251970

  1. Can we then change their title description to distinguish Store vs PM please. Also PM should also default to no restart iirc.

jjw24 avatar Jul 01 '25 08:07 jjw24

  1. Can we then change their title description to distinguish Store vs PM please. Also PM should also default to no restart iirc.

Auto restart of store & PM is set to false by default already.

I have no idea how to distinguish them and could you please do me a favor?

Jack251970 avatar Jul 01 '25 08:07 Jack251970

And I think they are different clearly since one of them is store, and another is plugin?

Jack251970 avatar Jul 01 '25 09:07 Jack251970

That's ok, leave it with me I will update the strings later.

jjw24 avatar Jul 01 '25 11:07 jjw24

  1. Store uninstall plugin with option set to no restart, when using the plugin's action keyword, query window seems unresponsive, e.g. remove bookmark plugin and use e google
  2. pm uninstall plugin with option set to no restart, when using the plugin's action keyword, query window seems unresponsive, e.g. remove bookmark plugin and use e google

jjw24 avatar Jul 03 '25 11:07 jjw24

  1. Store uninstall plugin with option set to no restart, when using the plugin's action keyword, query window seems unresponsive, e.g. remove bookmark plugin and use e google
  2. pm uninstall plugin with option set to no restart, when using the plugin's action keyword, query window seems unresponsive, e.g. remove bookmark plugin and use e google

Sorry, I cannot reproduce that. Could you please share your setting file and detailed steps?

Jack251970 avatar Jul 03 '25 12:07 Jack251970

  1. Store uninstall plugin with option set to no restart, when using the plugin's action keyword, query window seems unresponsive, e.g. remove bookmark plugin and use e google
  2. pm uninstall plugin with option set to no restart, when using the plugin's action keyword, query window seems unresponsive, e.g. remove bookmark plugin and use e google

Since you are using no restart option, I think your issue is possibly related to modified plugins. I wonder if #3795 can help since it improves modified plugin management.

Jack251970 avatar Jul 03 '25 12:07 Jack251970

Sorry, I cannot reproduce that. Could you please share your setting file and detailed steps?

I just did a fresh install, uninstalled bookmarks then used b like b <my bookmark>, looks like it's still tried to trigger with the action keyword.

pm_uninstall_issue

Since you are using no restart option, I think your issue is possibly related to modified plugins. I wonder if https://github.com/Flow-Launcher/Flow.Launcher/pull/3795 can help since it improves modified plugin management.

Same issue exists there.

Could you try reproducing again please.

jjw24 avatar Jul 06 '25 07:07 jjw24

Sorry, I cannot reproduce that. Could you please share your setting file and detailed steps?

I just did a fresh install, uninstalled bookmarks then used b like b <my bookmark>, looks like it's still tried to trigger with the action keyword.

pm_uninstall_issue pm_uninstall_issue

Since you are using no restart option, I think your issue is possibly related to modified plugins. I wonder if #3795 can help since it improves modified plugin management.

Same issue exists there.

Could you try reproducing again please.

Fixed in #3802. Please check.

Jack251970 avatar Jul 06 '25 08:07 Jack251970

@Jack251970 please resolve conflict from merging of PR 3795

jjw24 avatar Jul 06 '25 12:07 jjw24

@coderabbitai full review

Jack251970 avatar Jul 06 '25 12:07 Jack251970