From 4a78310f76d1639c32693f4db0834a0c5a971c22 Mon Sep 17 00:00:00 2001 From: Arnaud Ritti <77437157+arnaud-ritti@users.noreply.github.com> Date: Sat, 7 Nov 2026 20:18:44 +0100 Subject: [PATCH] feat(plugins): support detail panes for tree and list views (#2033) Closes #1950 Plugins can declare `detail = true` on a tree or list view (any tool-window side, grouped or not) to show the selected item's detail-provider tabs beside the list. The pane follows selection and refresh, clears stale content when the item, project or remote host changes, shows an empty state when nothing is selected, and remembers its resizable divider. Services keeps its single split. Released WIT and IPC shapes are unchanged. Verified on macOS in light and dark themes. Co-authored-by: arnaud-ritti <77437157+arnaud-ritti@users.noreply.github.com> --- crates/ide-host/src/plugins/mod.rs | 23 +- crates/ide-host/src/plugins/ui_points.rs | 9 + crates/ide-host/tests/plugins.rs | 99 +++++- .../tests/fixtures/commit/dist/plugin.wasm | Bin 97348 -> 97343 bytes .../fixtures/commit/dist/plugin.wasm.sources | 2 +- .../tests/fixtures/detail-views/Cargo.lock | 333 ++++++++++++++++++ .../tests/fixtures/detail-views/Cargo.toml | 21 ++ .../fixtures/detail-views/dist/plugin.wasm | Bin 0 -> 105774 bytes .../detail-views/dist/plugin.wasm.sources | 1 + .../tests/fixtures/detail-views/plugin.toml | 24 ++ .../tests/fixtures/detail-views/src/lib.rs | 64 ++++ .../tests/fixtures/endpoints/dist/plugin.wasm | Bin 78631 -> 78636 bytes .../endpoints/dist/plugin.wasm.sources | 2 +- .../fixtures/file-templates/dist/plugin.wasm | Bin 68048 -> 68052 bytes .../file-templates/dist/plugin.wasm.sources | 2 +- .../fixtures/grouped-views/dist/plugin.wasm | Bin 89160 -> 89148 bytes .../grouped-views/dist/plugin.wasm.sources | 2 +- .../tests/fixtures/hello/dist/plugin.wasm | Bin 141569 -> 141562 bytes .../fixtures/hello/dist/plugin.wasm.sources | 2 +- .../tests/fixtures/hover/dist/plugin.wasm | Bin 86790 -> 86780 bytes .../fixtures/hover/dist/plugin.wasm.sources | 2 +- .../tests/fixtures/indexer/dist/plugin.wasm | Bin 79931 -> 79926 bytes .../fixtures/indexer/dist/plugin.wasm.sources | 2 +- .../fixtures/inlay-hints/dist/plugin.wasm | Bin 88691 -> 88681 bytes .../inlay-hints/dist/plugin.wasm.sources | 2 +- .../tests/fixtures/jobs/dist/plugin.wasm | Bin 147779 -> 147785 bytes .../fixtures/jobs/dist/plugin.wasm.sources | 2 +- .../misbehave/dist/plugin.wasm.sources | 2 +- .../fixtures/path-events/dist/plugin.wasm | Bin 91105 -> 91110 bytes .../path-events/dist/plugin.wasm.sources | 2 +- .../fixtures/semantic-tokens/dist/plugin.wasm | Bin 88860 -> 88860 bytes .../semantic-tokens/dist/plugin.wasm.sources | 2 +- .../tests/fixtures/storage/dist/plugin.wasm | Bin 71114 -> 71118 bytes .../fixtures/storage/dist/plugin.wasm.sources | 2 +- .../tests/fixtures/symbols/dist/plugin.wasm | Bin 103930 -> 103930 bytes .../fixtures/symbols/dist/plugin.wasm.sources | 2 +- .../tests/fixtures/tables/dist/plugin.wasm | Bin 116488 -> 116494 bytes .../fixtures/tables/dist/plugin.wasm.sources | 2 +- e2e/pluginDetails.fixture.tsx | 82 +++++ e2e/pluginDetails.html | 11 + e2e/pluginDetails.spec.ts | 43 +++ plugins/README.md | 22 ++ .../official/ai-completion/dist/plugin.wasm | Bin 169568 -> 169102 bytes .../ai-completion/dist/plugin.wasm.sources | 2 +- plugins/official/checkstyle/dist/plugin.wasm | Bin 166533 -> 166512 bytes .../checkstyle/dist/plugin.wasm.sources | 2 +- plugins/official/csv-editor/dist/plugin.wasm | Bin 130585 -> 130597 bytes .../csv-editor/dist/plugin.wasm.sources | 2 +- plugins/official/git-toolbox/dist/plugin.wasm | Bin 108497 -> 108501 bytes .../git-toolbox/dist/plugin.wasm.sources | 2 +- plugins/official/graphviz/dist/plugin.wasm | Bin 126110 -> 126104 bytes .../graphviz/dist/plugin.wasm.sources | 2 +- .../official/key-promoter/dist/plugin.wasm | Bin 97364 -> 97368 bytes .../key-promoter/dist/plugin.wasm.sources | 2 +- .../official/license-header/dist/plugin.wasm | Bin 150780 -> 150760 bytes .../license-header/dist/plugin.wasm.sources | 2 +- plugins/official/mybatis/dist/plugin.wasm | Bin 166708 -> 166708 bytes .../official/mybatis/dist/plugin.wasm.sources | 2 +- .../official/regex-tester/dist/plugin.wasm | Bin 932825 -> 932220 bytes .../regex-tester/dist/plugin.wasm.sources | 2 +- plugins/official/solidity/dist/plugin.wasm | Bin 105046 -> 105039 bytes .../solidity/dist/plugin.wasm.sources | 2 +- .../official/string-tools/dist/plugin.wasm | Bin 162796 -> 162796 bytes .../string-tools/dist/plugin.wasm.sources | 2 +- sdk/rust/openidea-plugin/src/details.rs | 9 +- .../plugins/__tests__/detailViews.test.tsx | 290 +++++++++++++++ .../__tests__/serviceProvider.test.tsx | 90 ++++- src/features/plugins/backend.ts | 2 +- src/features/plugins/uiPoints.tsx | 3 +- .../plugins/views/PluginView.module.css | 9 + src/features/plugins/views/PluginView.tsx | 133 ++++++- src/features/plugins/views/ServicePane.tsx | 20 +- .../plugins/views/serviceProvider.tsx | 26 +- src/features/plugins/views/viewStore.ts | 12 + src/features/services/ServicesTree.tsx | 6 +- src/platform/locales/text/en.json | 2 + src/platform/locales/text/zh.json | 1 + src/ui/Splitter.tsx | 49 ++- 78 files changed, 1351 insertions(+), 85 deletions(-) create mode 100644 crates/ide-plugin/tests/fixtures/detail-views/Cargo.lock create mode 100644 crates/ide-plugin/tests/fixtures/detail-views/Cargo.toml create mode 100644 crates/ide-plugin/tests/fixtures/detail-views/dist/plugin.wasm create mode 100644 crates/ide-plugin/tests/fixtures/detail-views/dist/plugin.wasm.sources create mode 100644 crates/ide-plugin/tests/fixtures/detail-views/plugin.toml create mode 100644 crates/ide-plugin/tests/fixtures/detail-views/src/lib.rs create mode 100644 e2e/pluginDetails.fixture.tsx create mode 100644 e2e/pluginDetails.html create mode 100644 e2e/pluginDetails.spec.ts create mode 100644 src/features/plugins/__tests__/detailViews.test.tsx diff --git a/crates/ide-host/src/plugins/mod.rs b/crates/ide-host/src/plugins/mod.rs index 06e83b24d..b055c0eb4 100644 --- a/crates/ide-host/src/plugins/mod.rs +++ b/crates/ide-host/src/plugins/mod.rs @@ -1097,8 +1097,7 @@ impl PluginHost { }) } - /// The Services pane of node `key` of the plugin's `location = "services"` - /// view `view`. + /// The detail tabs of item `key` of a Services or `detail = true` view. pub fn service_detail( &self, id: &str, @@ -1106,9 +1105,9 @@ impl PluginHost { key: &str, invocation: Invocation, ) -> IdeResult> { - self.services_view(id, view)?; + self.detail_view(id, view)?; let (view, key) = (view.to_owned(), key.to_owned()); - self.code_call(id, invocation, "rendering the service's pane", move |rt, inv| { + self.code_call(id, invocation, "rendering the item's detail pane", move |rt, inv| { rt.service_detail(&view, &key, inv) }) } @@ -1164,16 +1163,16 @@ impl PluginHost { if declared { Ok(()) } else { Err(IdeError::not_found(format!("plugin {id:?} declares no view {view:?}"))) } } - fn services_view(&self, id: &str, view: &str) -> IdeResult<()> { - let services = self - .ui - .items(ui_points::VIEWS, Some(id)) - .iter() - .any(|i| i.key == view && i.decl["location"].as_str() == Some(ui_points::SERVICES_LOCATION)); - if services { + fn detail_view(&self, id: &str, view: &str) -> IdeResult<()> { + let detail = self.ui.items(ui_points::VIEWS, Some(id)).iter().any(|i| { + i.key == view + && (i.decl["location"].as_str() == Some(ui_points::SERVICES_LOCATION) + || i.decl["detail"].as_bool() == Some(true)) + }); + if detail { Ok(()) } else { - Err(IdeError::not_found(format!("plugin {id:?} declares no services view {view:?}"))) + Err(IdeError::not_found(format!("plugin {id:?} declares no detail view {view:?}"))) } } diff --git a/crates/ide-host/src/plugins/ui_points.rs b/crates/ide-host/src/plugins/ui_points.rs index 151e9ec58..597eb8b35 100644 --- a/crates/ide-host/src/plugins/ui_points.rs +++ b/crates/ide-host/src/plugins/ui_points.rs @@ -404,6 +404,9 @@ struct ViewDecl { group: Option, #[serde(default, skip_serializing_if = "Option::is_none")] when: Option, + /// Show the selected tree/list item's detail-provider tabs beside it. + #[serde(default, skip_serializing_if = "std::ops::Not::not")] + detail: bool, /// A web page of the package (`web/index.html`) instead of content the code renders. #[serde(default, skip_serializing_if = "Option::is_none")] web: Option, @@ -443,6 +446,12 @@ pub(super) fn view(pkg: &Package, decl: toml::Value) -> Result { return Err(format!("view {:?}: a services view is rendered by the plugin's code (no `web`)", d.id)); } } + if d.detail { + pkg.manifest.needs_api(&format!("view {:?}: `detail`", d.id), 3)?; + if d.web.is_some() { + return Err(format!("view {:?}: `detail` needs a tree or list rendered by the plugin (no `web`)", d.id)); + } + } if d.icon.as_ref().is_some_and(|i| i.len() > 64) { return Err(format!("view {:?}: icon names are up to 64 bytes", d.id)); } diff --git a/crates/ide-host/tests/plugins.rs b/crates/ide-host/tests/plugins.rs index 73c32a825..1d5991252 100644 --- a/crates/ide-host/tests/plugins.rs +++ b/crates/ide-host/tests/plugins.rs @@ -3676,7 +3676,80 @@ fn services_views_have_a_detail_pane() { let f = fixture(Limits::default()); f.install(&sample("hello")); let err = f.host.service_detail("hello", "greetings", "x", f.inv()).unwrap_err(); - assert!(err.message.contains("declares no services view"), "a right view has no pane: {err:?}"); + assert!(err.message.contains("declares no detail view"), "a right view has no pane: {err:?}"); +} + +#[test] +fn detail_views_work_in_every_location_and_require_api_1_3_code() { + for location in ["left", "right", "bottom", "services"] { + let f = fixture(Limits::default()); + let tmp = tempfile::tempdir().unwrap(); + let pkg = hello_variant(tmp.path(), |t| { + t.replace("engines.openidea = \"^1.0\"", "engines.openidea = \"^1.3\"") + .replace("location = \"right\"", &format!("location = {location:?}\ndetail = true")) + }); + assert!(f.install(&pkg).error.is_none()); + assert_eq!(f.host.ui_items("views")[0].decl["detail"], true); + let tabs = f.host.service_detail("hello", "greetings", "item:😀", f.inv()).unwrap(); + assert_eq!(tabs[1].body, ide_plugin::ServicePane::Text("greetings: item:😀".into())); + assert!(f.host.service_detail("hello", "missing", "x", f.inv()).is_err()); + } + for (api, web, message) in + [("^1.0", false, "new in plugin API 1.3"), ("^1.3", true, "`detail` needs a tree or list")] + { + let f = fixture(Limits::default()); + let tmp = tempfile::tempdir().unwrap(); + let pkg = hello_variant(tmp.path(), |t| { + t.replace("engines.openidea = \"^1.0\"", &format!("engines.openidea = {api:?}")).replace( + "location = \"right\"", + if web { + "location = \"right\"\ndetail = true\nweb = \"web/index.html\"" + } else { + "location = \"right\"\ndetail = true" + }, + ) + }); + if web { + std::fs::create_dir_all(pkg.join("web")).unwrap(); + std::fs::write(pkg.join("web/index.html"), "

x

").unwrap(); + } + let error = f.host.install_from_dir(&pkg, &Consent::all()).unwrap_err(); + assert!(error.message.contains(message), "{error:?}"); + } +} + +#[test] +fn detail_fixture_tracks_selection_and_refresh_for_tree_list_and_services() { + let f = fixture(Limits::default()); + assert!(f.install(&sample("detail-views")).error.is_none()); + for view in ["tree", "list", "services"] { + assert!(matches!( + f.host.render_view("test.detail-views", view, None, f.inv()).unwrap().body, + ide_plugin::ViewBody::Tree(_) | ide_plugin::ViewBody::List(_) + )); + f.host + .view_event("test.detail-views", view, ide_plugin::ViewEvent::Select { key: "beta".into() }, f.inv()) + .unwrap(); + let tabs = f.host.service_detail("test.detail-views", view, "beta", f.inv()).unwrap(); + let ide_plugin::ServicePane::Text(text) = &tabs[0].body else { panic!("text detail") }; + assert!(text.starts_with(&format!("{view}: beta"))); + f.host + .view_event("test.detail-views", view, ide_plugin::ViewEvent::Button { id: "refresh".into() }, f.inv()) + .unwrap(); + let refreshed = f.host.service_detail("test.detail-views", view, "beta", f.inv()).unwrap(); + assert_ne!(tabs, refreshed); + } + let selections = [("tree", "alpha"), ("list", "beta"), ("services", "alpha")]; + for (view, key) in selections { + f.host + .view_event("test.detail-views", view, ide_plugin::ViewEvent::Select { key: key.into() }, f.inv()) + .unwrap(); + } + for (view, key) in selections { + let tabs = f.host.service_detail("test.detail-views", view, key, f.inv()).unwrap(); + let ide_plugin::ServicePane::Text(text) = &tabs[0].body else { panic!("text detail") }; + assert!(text.starts_with(&format!("{view}: {key}"))); + } } /// `hello` as a services view that may run `sh`, granted or not. @@ -3758,6 +3831,30 @@ fn service_logs_need_the_grant_and_a_log_tab() { assert!(!marker.exists(), "a cancelled request starts nothing"); } +#[cfg(unix)] +#[test] +fn ordinary_detail_views_reuse_log_grants_and_streaming() { + let f = fixture(Limits::default()); + let tmp = tempfile::tempdir().unwrap(); + let pkg = hello_variant(tmp.path(), |t| { + services_variant(t).replace("location = \"services\"", "location = \"right\"\ndetail = true").replace( + "required = [\"editor.read\", \"editor.write\"]", + "required = [\"editor.read\", \"editor.write\"]\noptional = [\"process:sh\"]", + ) + }); + f.install(&pkg); + f.host.set_capability("hello", "process:sh", false).unwrap(); + assert_eq!( + stream(&f, "echo allowed", &[], &Default::default(), |_| {}).unwrap_err().kind, + ErrorKind::PermissionDenied + ); + f.host.set_capability("hello", "process:sh", true).unwrap(); + f.host.set_program_path(Arc::new(|| Some(PathBuf::from("/bin").into_os_string()))); + let lines = Mutex::new(Vec::new()); + assert_eq!(stream(&f, "echo allowed", &[], &Default::default(), |l| lines.lock().push(l.text)).unwrap(), Some(0)); + assert_eq!(lines.into_inner(), ["allowed"]); +} + #[cfg(unix)] #[test] fn service_log_cancel_kills_the_child() { diff --git a/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm index 87f0133bfbe89fa5b64c1126b87739cdcef61b28..ef28558499dced88af31c4cc4205337c0449cbff 100644 GIT binary patch delta 787 zcmbV|T}abW7>D;e|4sj*&WWpZvAHScrgQUiSQNF4HIqJsKx`_J(8nqb>%y>d6d55! z_=2XSWMZjhY9~;LO32Ks%3y&Qb83`y5lUU`qM)O6V;5d@E}p~r@xBl5d&WYlmm$^Q zVg$bNrHHMngeVzuw5*nyEX!>9L`o6>26Dw%!yy87tjy2HNXoG3F6B65q}7h$J)hD( zl`u+!@uvUgT!Kw?3y|umvmuV`-dz-obC5=N3?Hdh*Q&eQ@L};w*U(&J{Z*r6k>s5V zQ~rS8|Kp~CTQ{CyXywiNFyKD580rR9x zHe;S=B$p`T+k8Hs!Wibf4X>bi8NU=>&1X^m0`256H?5&2*;2!r8KHbVHCgIbRbtir zLLJEJ9=k-le|)DKpsR5+E+QH3T%pK=S)O`Gx( z1zmYT!BmG!u*#t)Uxpq*>d1H^SZu2o>7R1D(mdL`hj? zi35N2!SPX_!fRwkrn$EgF{je28RYF*-4LRJob2%KG1a=iis*3R0X*bGg&_$; zyl?LW(8tg2Z;9k;PYN(Y&oXtiuS`aemz0^oBn4e8AE%CrG%Bd@@QI4c5(2#F$WN8H pb{w}p*BGy8s|>Hl8W&FaJ^gR>hT#h-$WLw=al;5{*zZPl&L0@UFoFO8 delta 829 zcmbV|TS!z<6o${*=gf3uyqwC?acDf_6pk}q#&I+&vqr>QR6caU+kggUrxLP4G{PYi z^1+H0GHEeHUNbXoM?z2zCKkSk6hsngBp5}RP%xBTwv#XR;6t$a_u||C`dMoa`BWo5 zRsWX&n5PQ?X)3K42x5>JED})^H9X;g06T;b%nFHJvs49(YiUggFQ{kQgi*#N#fg*J z6s%uA3@>SR=mQ=`aCf-jzcpVQk5a@@c!gKYVR$*>f^Op5_t&mY&%j5nLFQw4F~f85 z*L>flrsnoKYSA4d&`O&(sR4TMhCT}3;E?|2sy#K4K?GW`H9CPlH0%MGMPf9;EVUR9 z3*jv;my46tj%%PWH7&^^r%3OZ{Rw#3OnR&~omnj(RWVh>O|Y~$6q{nsudu?(@iEPk zhm~dnxLNSk70!PbO|$GGLL-2H!Y(bm5p)#&dBpey|oWmYH}2Zew?1 zBl{4Wtr@S!8G`Tmx8fXv!^=rN9JZB4_AVpusMp0QGLeaN%a4ddP^7ywBdG&e_ItaH zsV=#VB@ZP(!|}LGL)UU^xDrLApMRUA#bsz!q%O3_*b5d3Tp!?D73I9Iqq*u3<% z5U&FbZAdu_(2qa17C=8en0f$U0DHC-1Pu6Nc!w2BQq44Fdm9hkbaLlY5vI_SbrPm% zV0Jmc9Xy>g$52sjK6KLFTptg8v}5mcfDT%@->o4$NBN>?fElzDN5NaVuh;}wTQY(b z<{An$-d)bDBeVs&ONoc9!!nO|#0rs@S!oBKEN~@hDwmttmUMumAn2%5H8Stlk2t RM&RAOIba-okpm}^{s83qG(i9W diff --git a/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm.sources index 59aeb5604..6ec88cb35 100644 --- a/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/commit/dist/plugin.wasm.sources @@ -1 +1 @@ -3f444f1cc3b7f495f26378594fd9f98418146cd8b2275310e53d4905d0bb5c30 +2652fb97735511f78576d5a16f685871bd7ab12df94795f14984bc819fe0b593 diff --git a/crates/ide-plugin/tests/fixtures/detail-views/Cargo.lock b/crates/ide-plugin/tests/fixtures/detail-views/Cargo.lock new file mode 100644 index 000000000..a4edc6e9e --- /dev/null +++ b/crates/ide-plugin/tests/fixtures/detail-views/Cargo.lock @@ -0,0 +1,333 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anyhow" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" + +[[package]] +name = "bitflags" +version = "2.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ded4057c258ba199e2d26386d3af3780957ecaee6c4ef4041c6b4b8b97c0b06" + +[[package]] +name = "equivalent" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00d174d5400e5e8fd687ad1049e2f578285fa914201b1af7e8b112a4546bd826" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "foldhash", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" +dependencies = [ + "equivalent", + "hashbrown", + "serde", + "serde_core", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "log" +version = "0.4.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + +[[package]] +name = "macro-string" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e7b3a5bbb2f63aaa223a671ea1bd0e7bc16bd30ce387324cf63995deaddbbd2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "openidea-plugin" +version = "0.1.0" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "openidea-plugin-detail-views" +version = "0.1.0" +dependencies = [ + "openidea-plugin", +] + +[[package]] +name = "prettyplease" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bfe0f4c752e450fc2faf62654f1c134747922825d5b04ca717b8874f41a40c0" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "syn" +version = "3.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563" + +[[package]] +name = "wasm-encoder" +version = "0.262.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4495a6f85dd94c411c749303efcbc5defade0b0cbdbc0541495241ab917a9b5a" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.262.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86ff6668190d9fb70372b306b4f9fe8930f0e2f57ce72e4922bf2f117900949" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.262.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "974d643b125b272607e2fff8012ea14a8328acd7621e4bafa7afb32500052b1b" +dependencies = [ + "bitflags", + "hashbrown", + "indexmap", + "semver", +] + +[[package]] +name = "wit-bindgen" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b85a987ab61d365382d25c7d47e26edd48941b3bf6e3fbf76eff918bc71dab06" +dependencies = [ + "bitflags", + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e122e390603abfacd548027016cd0113a6e2bf2f8ce6bdd3658b013456ea8" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84e26e13b9d972026778d2ffb7985736de116026fdc8d9464f966e12df2eb240" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16a008a0d6b4840677326beb4edbeb210a2f1b7d0183fb7cc33f466b90fd7fb6" +dependencies = [ + "anyhow", + "macro-string", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.262.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078def49fdb49cab405c3006e05793b3fdaf7069126ba6b9c97d01ec8c98fe4c" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.262.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f0dc051466ffe46787721fca3d088536f158ae400be044f1b1c386ba9397ad" +dependencies = [ + "anyhow", + "hashbrown", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-ident", + "wasmparser", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/crates/ide-plugin/tests/fixtures/detail-views/Cargo.toml b/crates/ide-plugin/tests/fixtures/detail-views/Cargo.toml new file mode 100644 index 000000000..92ccf31cc --- /dev/null +++ b/crates/ide-plugin/tests/fixtures/detail-views/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "openidea-plugin-detail-views" +version = "0.1.0" +edition = "2024" +publish = false + +# Standalone: not a member of the IDE workspace (different target). +[workspace] + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +openidea-plugin = { path = "../../../../../sdk/rust/openidea-plugin" } + +[profile.release] +opt-level = "s" +lto = true +strip = true +codegen-units = 1 +panic = "abort" diff --git a/crates/ide-plugin/tests/fixtures/detail-views/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/detail-views/dist/plugin.wasm new file mode 100644 index 0000000000000000000000000000000000000000..101301198cc2251a8c4e07fb3dda148d2effc67e GIT binary patch literal 105774 zcmdqK3z%hBRqwmzT5CV5_O9yHolb1%M%LclYQ>W#rMF4v3sHOZ5l93*@m%hA^L=ve zNz*AvS9khRRSC(JlP;1DgqO4?LQo#9MiY@pkN`oVmKY^sgs7-N&>IaZY7|gZR3!KJ zA9Jp?*WR_OQ+e>|y)>!49`iBgnBzUioGaS5c;!^&qSigm?QOY*I6Zja@a2o?<@=WQ zEvC`L+%-#chZheVIh;h1JJxJoK6m)Q+~saDYAi18J2V$X6Nis1?R@!>s}Ad7>%ifw z_Z>Q*%ZdH_4)32kbZGAKC~CfZ-vKUonnsPeg@q#vNff)Ii*6yEIC|)+R~$IJ^T6ec z)8X>!xdnB&*x7gVz|QifyMN!&eJ?w3=)lr}xy3Y%TKkV2UIMrzYE0%X+Ir+DfL%Vf z?*iY*xl7j`om<@VZO{4No-^Bsn$r&O2V-fiG~C|4J178RdTt!r_p-S|i|GLxjaqYu z_q_~gkEc=dWmhdNY3R-^w335!*Df}X?pv5Uyc7-904YlhFq)jZ=IFk|m#g;iw!gM! zCYBcF=5`)fn!7TI61udO#$4;@%s3S}E{5<53M2`!=RNIbFVjx|ytK&Za*szXbl z=I|Uh?fqBG?LYXkBiFd&QFH$lM-J?tbCXfy$kG*a3$D!sbY6a7?$G5snWwAflBnYr zk~%yMd){T9tXL9FxuX+qp#i=RU3KN*#fizKBTW3xg(I(AymsQ{2Nr;q>uXaz*wCK4 z{J@fpp9btAi86OIbw``-=(Ic5YF#hih}{`c`tl+R7a3((FpHF|;H^uxQ>4_|~Y+TE$)B+)hyzPRX)Uh9r^0!awb`}Qv#xO(4` z#?oAzJ2banbJ6tkuJ<%~Xy4IAz4yp;-x#H8);%klJaBk%ZoyFJu8lgEQ+;X9km{Zt z)sR#h`=r3$Id?VWmqhvGH@PSuC3-7Sr~J6J$?b)L=jJC@W2S<-RBOV`l+!A7*&WOnL3Yw}xZlt5TX)Smnn7xhOm;5l(;9S7+u?*B~_ zb;kWoO(L?Uv2} z(A-YJWWsLJZWs4mZFkcmrXvf;%KcX@@+4Z_vWuh6)%zEB?!RK+;a6CtiAC7?@~cdW z23i0;2vJW4jme&iwv8geUY5eI*?Oki8@oNum}1dUyR|U)@`bs@D_k^Ibc%|~+O5|2 zyS;6A=BS7n!In68MWoiC_?J7icGeGEIk$Ahk<0%_S>!n{J9K3KL5F~cEUu+&d;k%O z%uZFpH72*X=!{qHTRd>Vfg|VY(Vp4oeEW00?b{pe<`iHYGn7CiAr zkx)NT2MA4aAQ42bykhP!0Hx8U#j9SnxPRfm%jR~L73o#vV!iGcc#G#=c?8XMIgugoCu_MeWN==P16)pLs)6K zE1a8muXN3FwkD#n(*jBT1H5M?Oa!%K_Zh)%YS zZ^Boe9`r`h9pj4{fgCveik&Y%bQNT{!5wH1s%2^P?D5sAX>}VXx4P)8a#lPp7Rz~= zZf=5%CWevS`gXV1u(V;-G+@{qaBdHzg;aaRoF?pYu;Y?JC;JZ_IM+WdJIPMl$;Nec z!sLzVgr{XEo0=Onk|8>3&4z)TF-le~Kw zS$#|M4A8q_r0dpqy1h+t<}=c0Xt_n}n&VZwLf*r)vOiZ_A#a+1yOe z*(lttJ)!HZ%tF;}7}H4KXN>kOl1{rFw;Ytnpw_I5J{8lfc_>=8#SY=C%8br_d0aT`02RkocICAuV4BkiaD(|DFLQ7>E zxk~4Oj3b`MXE%?uYOkVrlaX#+Jnx+ZQDVjtsQB)&I z8mV&$UXlNo#YuOvk*4wFZp z#x0k$Fd`*g!K3pw$JAHfW=3HG|{vec#teT(q(IQMc{5E0&j6 zqR#QCus=>$_9xcWi4XdB_lDmG!tZCp?^izH-+wjSx2)2K{KGrKZ>MVWRCsddTYQNr zz4?4-p?C-~;PV0}->E@MlR~}ioHjd8OPZaEb z9zC+S^gl=4zWqn8ypr%!aNV{qTy;2l<#}rt53Vwf`PBr@7QEZPJ%qBZ`S!Id9y;*y zx&7DfKQtGrlyQ*g+Fff`ve3jxUwFBf6GHsIpI|itaKIb=;40^T3<6$t&M1~nJM91U zt)s=wm)_|iEpZg!zHVl;@S2!8zN+2R;A7dXt8_rat5=sE1%t3?2vtP~iK9Y4IHZU0 zf}>mF38Fk=hwuGr{I>Y&7cTs)`yKa5_n`Y5_l5W&_owb}-7WFIx?gjD@7@@{DgFod zL-CvAFT0cR56Abp*T%1jZ;t=X{fql&_Z9c+?w{Q2;+x_(#6J>$!Tp_k%zf4UyZf5^ zEBBA?qwYk!9KSlgA-*xbK7M`tCHF;lYrGQwYW&go*W&x)UyuJJ{_FU!;z#4ZjBiM; zPrevG7QZ2RQ}V`S^4>pB{~5v2`5IE^`1WP~7ZusTeshOi=FK9V&*Oq26fV2z)x6D{ zGjY4uiuc5ObeR_J1ylC0+iUYEem-~hr=7bz{_12Db$l!7>Q*MI7M!lSJx2?vTChJZ zPx92az?1Xh&3Tl&^Wu!3iSyzvKk<2So1gZ1amr8Yyg16EV#|EqD0ZkG9cS}?BpW(; z%lgP3zMfG4ly%-MZy!Y39xq%kwSgtMn~9^oJC_ORH#ERlqi*Ua?X_sXdnix%(@zif z+IgD0`Jy{7@RL3CPNFi??PUQ_uZacL(!$Yafh!PtKo<4i=BOW8AtI zPJ!oMO4Dw>2N2e1-Y%Br`|amX#oegWi9Lo?tQ&WVh#%L<8@;3h1`>}5a20hvsu`tN z!$t&%gAp}t$~1;lV`v=IkcP$(S7QjMXfPLzY7A}N9n9NX`wfkOKVb}watsZcW(;)e z$I#LkT7xk(m}LRy$I#Fin!QwG0C-JiLt}WkbJq#{A~Ntd8d2Jxz7v^fOwXTk+aXNo z_H*x9S&rtjulWfM510MJM@75Lx;vW*)aWALO}v{R{hLv+HR4Y^$*kF}AYvNSxu*;! zffkPgarq+c8xK&V%@|!LdyV=pHWz7jy{_~+7GsHIo#;5_u06ju+RcL)vMr(uB3^}2 z+;XRe)(0u=4!Do=2JEuYhV2V98|57Mee>8>s%ibZ>0fI)uj0v7Zm)E^uD#^J%J8thbCgaM0OKLn7p!@O= z;)}G{oIO&Xgnm-I?uRvi;#rXP2^&kcd;=Xvow3t&5?iM>A*~>dT9QV|kQ`|V!xB7P z1X;vYw>QC~L?mK=Ccs!yN)nhvvI7w^kR1gxfB>ltEpMyIN@UPeT#D7NIWNA% zp27qF4Ya+W<-TEG1QuU;IZ$wF1`yYLEXrCUd4ydIL-smXFbK3oyZ@0ze zjX$Cqh2W-@&_!&p6c?JNjf)EfvBuyZL}ICdj^6ti|2r4qCQ0wh<)e)J5(G0mcZp02 zySfxyMMdu0v6(cLk9sJ;C-W18#~Tg2esp%UWp}g%vBp)lJIef3dv_#Z$Fpd+R6wh^ z%T-nZ!s;tgDXpLc`oFZa32v;Zg_Y=FKl%T!UWn^F4m$i$qem;=%34h^sMp?hLwTCHHFriz$u?nXrMJle2XQHTh^ml*z zr&=$VlGy<(iZ2)}q>(JmXJ6LfJ;(K&StjU(+WUX7_b}%2H9a*TqqG~C8$-5u6!uZ8 z*-uH;b9slOdhwBxiCpnff4Lz$6-vyihObBA?6&Y&Ph9aHUz&c3-|?5-P*IJSRjW!5 zmek$(WKC(!*66pCeWx?4WS-2#+s0TnGTme@U=NSeSG-1Tl$H&As=Ly%X{=@01brn$ zH_T2SQCZoDakFK}xG7D*(-|6hoc)w0u8XBC`v+@YdW`{MPtC+zB)+*iJI;0|xxZ@f zP9#lu7VS#l;jGXVQTerVYT z^*ea%M;->*d5D->DM<24j?~d8iioBy;3mH2uG`0}+@fn72Z#VM(khw~BiL1&`>ABf z-+%lA|JGc@;YsJu<@TRG?iLrsB89sk%5XVEAzibryJl)W@c&XLa70E85m9Z#~A{{WSzRq+u0Y5hV?94(WU4> zevIJoS9$8$MuIZ0$QQ#xeV3Z@4{DetdQd4!kK4x)Go$vf_x;78V?8HcM8l)lf}?$alS@#=iVl48NDn7-~6 z;|=?Vh;KiCDy(9`Bju{yBXB;}Bb5(o9%(SM#(AVsQ1ihfl~pDZhv-K93^(GDazE^m zR(OpDcqL%`_}*dehZww7_Y@GinoyqzLXA)jp^rxMd(1NF_RiX zCwlcpA~h0XOt^R9P^;WkoO99#9{$}28-`$68HHt~4$EiAVJKCBO#5`0vrMP=8w&pw zor__q6f;W(L$PZfIV|I+-!2;ejc{Gsn;?e8o32bmhLXLKi`|A)`j!EPTp3y!Wgw({NVgFt5pc%c5y8tzG%|EQ=E_fdJ~;|5->Ww7CkD0 zv6&wzrppgNAq+FxBmgRKvO5hB{uF zcq$&Sw|l%Un4rC0hY6zCK{e8Set(MMlX*u5Ti3@{##GK#$`v}QQg7Nxh#i{aiJNYwkLf*wP?M3GN7dM9b%?CjG5xV zMEr*0n7Z!|M98BZG=wjn^F#EL7~Yo7eJqdG$v?PMfd~y>DW28wc^NwN9u0Uw)3U>C zk78!NHv#=m#(O-1UC|J)G>daY)bdPv-Q4NDVcZR9+ljUvv_0u*o0`4J4s_kl3Ej!` zniK-eWRb;f-o9L_yqUe%Q?=&(LS9V(-Ffl(T(#|L7ai{sona(V`Yw+L9^&O00l|L3 zb!-;zIk}>^#&dan%8Qb}^PAS+6NO4CW@Eli(6v2 z-qWJU1#uDeTmr*t_Grn3sR;|s5Y{8em5GXjz$9bsX%%G~KV~yRG3LIQ;FU{cNIgAnCJoC9@NHAq z?S3@Gw~^;tkF&tHVsFt4OHLzvE0HysM|F{f_!KV&kwul!$|kZJfp4uWd>e|3|9VUX z#+7GZFD;Q=rOZHb`H4czz^<{xTcn?+WQ@VW7+Ji%io)GN*j&oz^p>q+{EG|ipP>(T-1KaA!JtPdzg zlTu(mC!XA=f&U6rKs~fM$U{GuM5Ja;*8DWegY%jnfiGz z4g#QBTzfKrme2@A)jnPKC*+g0P3u-`28dfdPeMCXUvQZ_^ zirc*D9IPQ;gXZ(SA^|6}1Yae;9xfwxo%>ygCLn3xv^2AdND0J*f_ML#k_u_ zQpTcvoP|z&x2g5GOrLIa-4le%Z#`Ico}O7gjrzb`%J|) z28O-C_!JsQWJNm05M@7R#0x;1wU#W%2tvp(z{H*JMQ|+_ir7oz+Dy+d&wbyPCYhGS zx~rP>_0?b(i&P^n+%e-owF8Yw2KN+;K$k(ggK_6k=Td^g2D>EnJKli*>%DOaNosUMwNVkd2DMLbzGWnsY6{yAE9$Wr0jO zlk7qOy3lGo=sZ^EMA-oVG>N%rL#z2T4=9YyfJ-gr0Ui@^jFh?{?lsG9ylRmRb{vgD z3t&c}8p$N3M5j=e186ODoZnLDMgeqUlr(P4Z#O`8qwG znoCavPq$ZiT8V}cg&DjCrg#%j^*R@me16?vDoYbNmOOCT2Q?&SQkud7S5hgPy#VCd zHj%F_Lu3+AGrGnI=_d-%GtYVrJE^=T&UacWlw!r(mO&f7Zg|!rU)XDw;z27)r2J_OIAK8EA4rqrczj*8 zrlq+{Jv?H3F{@OEPu!7!&_6W>8BcdCl{9i>d?th)z=!gYc-cknaF=0fakoXXM*P2v zAB4gzKjd-D_zrgP)7p((PPL9&u1l+i{AGDl3RD4wM+|pc=ChyF5CMdEM!O%IRT%Fn zTplkKJCAAhsBNK+TvrNpBwHkz=pFvzNrLYnIYg-(0nlv-D;8`f??)*wC;`o{A5W_B zNat91r5vE-isB)DjFW!EgYnyIvZ26L9Rb)_LI6XqAplECkOCffkbwG+!h_^@@GeIe zL+VkDkHlDOft60O3_46Q=z)aE0Z+I9QqGJ_D;8RKP;QtJmSw7;C_LF4hWvyJ1DbNF z|J0WMYjaN)!YM!ZffSj*ON!&Z6DInlyA6?Cy@c3;CWizdg`kvP@NN?zA`I0ab6OUCxp^NZiwG#R{H$WaL zWq>=TU%@lDPNV_D0y!93nkJC&d%i_)JG$&sb}RS@q|6*fh7bY)8Xx4-G!XC-25)lCSDjr&an{=(x<7T?DxY+ z%T=Dvn_?_gx)hdu)}kRgO7?hmD*qbVAtdTAU$aubOiC5|wJ2ozLDWAO^xI55h^&2ONH@RlM`Qvi^DAHF8xq-R0IAp%BgNJ@wBb3gN|K+kz*eyVMe<6Tu)O}%~ z?oav}pvfC7oe#%@P9MaODSO3;He*2IgPzc8)?T zR?hryduE|M8F-!;%9)R|pANtfj&^X%7Ntzb^2Afog2pvVAW@<)mey&MQ)DLPh3CZ= z(GyB?*Y0GGrpSWKpyTXhkDnqMxTqA&K?sjdM;h2M4eXeN`y|}E?DZz4sjHb=rKwBB6@;vqoh?j5r7ZzWye8tOHaUnaoxbSc<0)JdX2~2#F{idNT(L%V|gs({*fUgH>9i3MVR7@Qx z5tN6f?^{Ofui3JK+x^tHY`iBU+v&WoMoBv!|IyFMUBo` z4iH#mmZC_64U`fNxvq@pDaxot{F^;xvG&7FS7fN^g4C%}yUEL9tZe8p%wQ`kK%M3I z%WB#0b!uo?mfT5x2zRk!Xwn|P7OT%?zhh_~tJ`-3-Tu2)BpxV$r-vGXWcFk*Obt6$ zQG=KA;)th44YWK$4MQ!jj~YtIYt-;#wJ_4dk0<5`DNfjIw?dRrVs4ggP+|vLM$%7U zLKt`=d#@P@us8f1(j6oxz(s2<=6$%bC!U_^nq8ZDXID+v1A%#onm#4wrR9<78ftlc z(^W!Vo32kz4BY-x#7x>=pk+UAct&8!13<9J>a@F=Qa_LW=J7~wEwPmISb{|upBEqH zhr2`kz;DZrUyR9D`P*w)phv>;mu&9rJ-+AS1ZzNTwjNYZw5W8#?T%kcEf%8Q2xym6 zVp6UOPtJ~sf}HQKF5QiwvuBs>jxXwxIAPsi$`8Q2#NS;)WoXL!u6kvlySn68thYQs z?CO$^w%+p4@~$qqN$V{SxVyTn6Rc5w7usZW2;g~_99*mN^~XQ+_;~n7zS_JC{}dPg zp@MPv7m-}VYli*Z%nYS=$@gv-NCfr5^Yi6?+t@V4Jh;%`G4%y9f0xYvHL$g6wux}= zQtO`jW(K6z%6>v*cpe1DYocUTAuO4;XfyjIakj{8hC&$i7Ep2-PjOdPF$bkimZi4e zs4~iZj(p?HAxZYGjAXb@D4`9GOuoOP3+_{m%~Z0GNdydqCqxpA_JsV0Y8$=XCYcnA z140;dmlEHo8jII%Oo`7Ho2)g4A=YLps_Mzw)whhPPGq~Sb$CDYl*-Ig)mUTg#t3Ds zf<-1?sNB>1oGPQ3x$FGkz)!>!3dV@0BbOzjKP-=EMNWnRcuH*J_M?V1+*w{)7}g37 zZ5fvJB6Ci$JTD|M`Yi%qZGrsYj<$?^8T?wms2Thxlgi)^qSewOR+NnamEEgfM9Dq; z7B|H*mhXuJH5%;Rz4cpd#3Og80RFtc>?z6Uhi>K`R1nvH^Mhix; zhfl<#q^qa*$2~Vn!oK`{EDrnNQL}h}wbv-js1b9Gf^o#t@XEI7Vw!y_#>A%a2V=z) zcSc{0<>So6Ux|B@`u%d;Bl}_|{(Ov+!SCl{8EZ4~!!bS#zn_hJ(=zcMje8py8p9#x z$nyu{epWP=vJac$;K8Z5x6wm;TkO4LOL@5?-VMG$5i(e)QVZEHs*(~~m<2;BvtW31 zc}6sJzQ5_b_&sr+J%6g1Z?yOVYo;DGMo=ObnX*chfEjyd(3C4pS60_`=WW;ICi(l` zCsQn9$NbJH>Yd4zd1JT@&HRkro)nl_BZaRZcswb1PQ({EJNXJaP)^Ag?Im-Yg_j~| z-ha{F+xnBkrX*fxlhe#uHzcdX#t$sb;`6H-U{QhwKCcEOWt}W5Cv|AeXd-oq3wEYt zmr`DkTM@X%N&l7p1fT1QT6l1A;%T1R3;d zqHC?@5MHaAGvQT}eI~rtY5?)IssR&UrSvOIe3ilscuah))f@tBRdW(x(o^J1pBLX{ zR3csu1wXwEO_s7T&-^0pMoi+>EU72?bU_6Llu|AgBWZCqT!XMUd&f=Qdes3_$zeA1 zqlJwXrUEO-A0C~9S=?vlzG{L|o~{Wt)va#hK}adXKB^jNp1zTX$2Ib>8Uc7Rzzp~e zyAvavhsG6th{9X2uzZgq9e@tPqFbDQXh=*D5s?HzOxR%w!(t*xf?+WM!b$|1m>{#e zAYq`-EWIbDH8PqJeThuAY4Ufuti*-ZT>EEwaiQ$ZQd~5K#060> z{3cGAu=bR)INY9>M;Fna5qem)lN2ps+7Kir;@jGw$B{O2gK3XoQeaqh4G?S5uhN_B zDqB1&vVUDntx*jIfpx2%rLOqR!8=Wsv#5Ld+q<_)g z4HTS+NUx9TbX-_p|es=dSz;zLIGzQ1)NFul~zG1)hS@dFa;==@(GJ7GeD5_0-0D?x7Y;*5JGz1|GS@-r1aCVt6`-y@3zeBU)9@$KbZ zyksGJ@DER_K_ENj+#1M)X|*VD5Zp|lX+DIQDUs!IO)k^qX0Zn5_35iCQ?;%+4WgT@ zI({or+zTQW_++tUA~}}&eS1vhO;~w`P6oJ4#+K<5%uSPvfH@>c^%QTOA3 zIK|6t5_xd}5TGC^!Am9hH41i;SAHY5?yVyuG*xsfgOE5SP)G_wX>WE3f#*}kK~t9fN|OYS&5kb(sxZ%{ zz5i$#gNn((hSF*)IJU&~@l#;l{;DZGDQtG2NyPb?u+p^kJ`MkZ;SGE9n|fyii-QRs zuyJD)*=NR2jE&E@y{B~+c-BZI*lW48x}}&0jH4fOJ9Xg9fbpq{g~e=BCB}#B|N9N& zH5n#WyT6X{NW%ryV7EV&>ud;8mwHngv!3;)82jz8I&&KASOBc-SVMbh`6=*&+oNoL zt*T_$vjx=CRhaje52us=eNWXbKvQWOZ>tL(vBgRoQmYs z%G@cL1hJO(&tO{nn{V&0;+QOFTA=J8kPY#}wj+ZTXBhPb7jqioNk}clmmTA5dIo}c zje#1py%{j`tjEm4Km&=a=?u>1h@rAF!axYjvy&B@&XByz*<&W&HJz|im`;l-7%rIB zK;X8aY?Wi;`DjWm2}B`2Qf^4s+9A7A{tOd(t0A6)a)ba;*Js3j6&=8YEX?N<7ercq zhp=-+_y#pWT~+h5Lp7O1Q4qbGEFCycRH=yWkH=L3(o94PK?FLjSNW51RRAm_j7M}y z{(T9()WJD4L!zW<5dw}j&ojeXz+~6V?s%3?gIGWfofEDRWzFJb5~4`NtWMR|Ox9k% zBWDW_5cyTD4ElxjGLs_Fw2r1Bbbbb&_=~6=c6)p_JM(!ScEw?5+bs7;Zff z_+*f$0Ro?okc8|K;poXiaBIAtRn}eWz`^J&)l3)77jdEKG}tc*{)$g>5SQp~w6e^K zvCpCR@Z94du5du0W`s^u6w_~gbMwAY>iD^JQOD{ftS3spWwr&t+Irf02~tvpWyBK<&ln#?a^MEFiMrR1g>r6ldf%0tO{uL4-JiersoD* zl2{t!9-}4P#}f0>;n)Y7>L$}8&qF#_iWjppK*tShppZ%Vq}bA9tP;!RKRGzrH2W8r z7W_(vqd!~93Q|IPXj|d*LZ_CJCJQL-(<6NtZ7goUB2o>jTe9%?$cDC-8*@q^p zder_w3`@(b(WrD-TuEaHsGZR{WRe%VptRX=lC9wkX)-h~o#m|2Wc@5*9j#er7U^8O z#!zwsaSEJd+iFgzPQTpWtzV41W&ILcc$L4s2Ap#)BY*E^>DH$hG|X>q)KUycmTXAJMYZHmuOSZp8&G^U_%Vy0+%6a!q zMPi!amBLZ#@oEjy5_i@@zxExW{6oAl2ixH8JW=V^Ycb>S` zRx5<7NjMxAXYqu%+r^?DKj#zBRxGJUelB8Bq@Q%fzS zyd@6ZY}l4|n~xA8QeN0OK(~=$CJGW$M)6-mQYd5Z2>w<9BBTJA_vyEZ&w6xGj9A|2 zLp??{20Gib3|}lLt!j}4rOh(DHu~_=>Pkc^S5<1O53=iNZC+q8D@pe6*4TUHOvZH+9_KN?s+38ba9Ki#PicQ^67ko*#UBCg$$v0gBOp} zeM`WbHXEso9V8|BV>of1ks+36o{V^=9f$mEWAgdQA%7!rlU$IvBo_*gKN3+s2)a2x zgK@D4Ega%cio%IA*XhGvX+6l>Ef&k6}H!B7!}CM)u>oa7leC&qfQr7 zGF;9&Jzdz?Xw1gOx@vuFMi*N&ruEas86urCz?;HNnj7h$ln+WqbV`Jyq~vmhTK8Mk9*cgqq)p03P$^!On0kFgI4&F4nH-qW zI;f)@foV1tkatKlV{~`kJ=RH+Ni%TK4i>9(Sl8)M;{J~M#FkIH9*6P+qkh@l@nAFl z+R+>Gx>NYjM{gi`Ij{)Sq_||2GtR@8u6kHG7)fyj=W}>DEOgmMlGrp^?6i@j5%x1Q z${jcQu)wMTXK%1^B$yb<|hCWxkU#$Om?77t$84x+RPc8Zp8SqDbXkJ zGaO;iu9qkOtn;qPRH<@o{3#DW(8=_P7Xl$oE|KOZ;LWsfc834H3R3Ad=bdgzs8hHd z3fCkuW;y#s&+b4m=s02&7B;8$uiAG7WV;qhiMhs~BUUoi>fgMfD4gF~IxVL1WYP1R zAuR^dM~*E+oa*FN{BSEb!+gz9&iqZ4!=SKoH|dxA6C&!9j4Y|SAAYQS{-JVFY$RmK zal#GO{iH^AtHZ?R{-o=53kh$A(q$cH4FHkd*70qj<5Po6sEu;P?~}(e6h=Y zvCAlC5eOBtbHx++7bQY8D?I1Wt?G&L(G#5w6`rKiakHgZ(s;^vQiwkhFhs_Tf*;vQ z$!IT|IR;`z(pV>jBT&NV3?Ulb*zT|!9ZY2o@IEbN^8OFwc|QuRcIITq*BIGEi-DrG(Hx4js0$P z=GzY1*ueuD$hETpo zn<=Gdo=kfSguG+eq#|CBNjkrXmq3>o(N^v*_ji}kG^P1lv6jqlpIc_RSGKmM27e_W zj@*fvGNQ6(!aap9DGT}2^P=sqRRdMb#UXsilI(=XinoA6>b<0@cXoVfujSu^SJwWN zL&w^mU3@jhh zm^{`nte%!b$@Qv?|2>esnI2l2(7)0|M3MX5-H)^G@!95pab!}ohfE6F#x#q027Q;C znz+Le)=m<9$0M$xzyVuoG_gJ zsW%h9Sdy__JivVaC_*05$V1epIqkfe!R@vEsoExWi=_n6yotP*&?{jXdBcdjMpzxF zM{dK2+fqp7<}9T>wOKK&9(d?h03Z}G=zQ2voxXUt?e^kI$x-av()*JDr7d9rsH6U= zK)r_6W%&64|AuG$QqCAjQ2mq(jJo}%0b^S|@CZU{+Yv$u@wj-?%9q>-CX5>m<)qQ- zxX!SlhMBGysN7HkGgsYNR(jc(apU;L;6^`^k{fBvxDf}qtZv*mzB=5vs=9F_{=0{z z%t$XAGj1H;7~Ht3F>#~hv(v0xRw_E*Hl)!W=p=meC%z6j9eLG~-K%-(+&JtoH#~RZ zHEA7$_4$@fupPc=@kU!BBN!oF4lf>}9M3sc+>9aYRELsgYYAB?RukvA+m}zLFu8sE z3}#^mjaWucCupTv9y^9^CJv#&vjH2ELoHB{jnFDglwwd=h3uB&@lHtP`Y#JMwU*&e zHbe@Ue1L8^#zmI@_xw?UR4}K5q2nx~w2IFMwiL4&B`ALW8 zjt~NS#j^Jam8Rom3Nm7>7JgEYBXTyZ$R!0xFxv_zVH3Z%gEaXSG`tdQXf@q6?L<=! z%hZXcwkG8d7q@A_#yw~~rd5vdda+YS0sT?V zgbx&2;iEj34z{dLF?Gd#L#LSTVRQU%pbAIm_d*fs!pTSMb}n8@W6rRWUQ#G zL|bB_E!qpP$W+OBZCyduAT8ze7hrR1=htgV9(gq>gV|s&yUmADpuRRZ=1|bMh_biY z^e_{fZ3&JGe4f9)`0}9acbd9=d_!b>9 zDxDpNq2{Av;Xow06Ora!wWzFGe&P%*Hk+2hY;Cf%uCh8glQvIRMP5W6lz8Wzu5M$_ z*3J_%LI$QU2tmTDr~xBb8ccMdKbh$*2n#=fr4<>~p2VOh1&lSXt|v|qsoSymHWZU# zDNsPz@Jo{Yt<8eR13XI5&C41cIaNQ%v$joeFx9z8M)NG?jO8X=qBCDe>HrUQnjk+c znKJ|~Qon^n$CD;n#)BIXA51snfe4x7K!oN}$Rjw8!;!0U_ICo)*SF)sT=o$UxJF9W zTbLNms*4o#Mf5C3#g{#2gwq@85kFsB0YQo;m8E`FWT{Q0U`LF7K=s1p^E=qc*!d>x zrM&#i#`5yYGGEdJ{VZ73Xrl8LH`rS_;0;DXT0Q+7>A3QUT&;ezOk+Jcxfh9-sxl(o9su_SSX6wGs^iNKX~853dI>j?}C^ zr!?fiL7Y+cB{fkJPdJpdU!mj4@wWIB?v+1`p zl|DbX{M_L3uLqa^&*1W5yWAY*@Pdd7ZPCd7(jIQAJKF7hnZ-2 zF<|z?U|f|SEwiC=%wTB z(KnSuQRfMtkM|=Qg=r}ip382wTcb-^yrMaN?0mdkhefL{yT#Y2%)ZWR(zweiKwwTz z#xjG+G-}Hf?Z}x}ocjXlO=3ThODIjNuOhVaE;|$yyPIbH`x%NY_coOCu3w&7Vr@U0 zW^Yg<*4`j(Vj!aFqVpVIso{pr*)H1c>;s5vzr=o;%%{!pXzR*bOhXNDLnP>;-A+4? z%1!{n9`D)h%uspCjo|f6(0X+=l5VO)lh^>#X6p#)`Rw@0rvTEQsx>Y8&6Ha-4W9B1 zx?*d)CP%yLZRfSW!a)`I9G|7K&m@R*w);k~!%g3AzS-Y=tKB@u-+Vha=eqNrM=|Dv z2tnWaw{x{}OZS(x%LJA}Npxb~5?nn_S(g}@wRTlf!#g0gleNgqj+g^f z7y(ykCduAtw3ztJXRO30d$QK*obREQ*SAJmLS9qaSg8}G*20DkR;o8U&H8*2Cu`~S zD{%*BuE9bTxjda`Y~_<8sw$FBwmEtq`(E({98EdM*<03@6y-UwZw->7GTNUW3MtRl z#pg5Ur$!;{uo$6`Hw6koup|h}Cru%%_ihZeygmvkA+J%$4?hJ8L9OB+APxwm*rA}4 zI1oB~ZL&@nx~WN++Tm*=nd(58^+SP5p8i9=hFV@9m6VXzsN~oJ@ zr8z~srbxBz(to^NK;_d?bHG@v;4cf(O3aabww9j5i+&pP9KNhSB7BHIEA=KVXM0z? zqI+{7P~cosj$JnnEE=?cn%BH`Hh9%^Y&vwf>2+*u!J@8!uhHm7htbmX9vbGIMP%~^ zYq5AZQ}*`s}h6?iW-}Y4CP?-wm<%jP&tS?PqrV4M+Z2R%k1b#Z^BP=?(cvaY>a6JzH zFPCZV%wysn?GX29-`9t9~L5)swv46d32C3+i&?>S3+g}92AZFp;b zYKWg;5-M=QMhq_nxK_AapCXf!!qo^zj7F0G^YMIO_Az`7kv`8|2w_rW*8jj43M!3? zg+bKo@g%@U93;)RN?D2-{DbUYH9tM!8fhFg8jVEXwK+SA_WsSs|NQ2Ey7Sf#e=hp( zQ=r|_38Sd^+mCYM-r*dk3Gv zAjxT)y>(2p;KiDiyEd*_j*@viXn%N2vp0lh;a2x;(fNDx*W~WG@vakMf9?OVMMguG zlGG*w&hShUF}UzlAu?ogD$1!Bp>(|o!*|G%ObC}ys*UH%kN=Jf7s%<=xYlQck-8cm z*cRe{)P{l}*iBxDePj}j@gIyrikU*mo60~lX(H`P+a!eVBk@yb%naS?Zm`j#9M=3E@bBB&U)f^EP^rw6?0mWnPm@J(bgpWo)eaQX9 z>4qbT?`ezS_>izA+O9D;k1C6n*{t&gNOQPi0g(WaOq#$sLE0!`HP-BsZ^Q6|GT$tY^g%a?g;qoHJV2C5A|QK zYrj*`xJE=5)RZk++Cymt2lav%-T05`Wuh?It{%RuSMho>Zo^mWV8e2x* zGf#4-XCn3N<3ck7@Q$abSH`&6=7ZLGB2iM>&9bbq>?`4LG9L1kgP4*ag4zE@EE4b0 zKS>-2#3zVw-S#VbdYp3V#&4*ki6JZ8$R4x@$Q(@|ljJ21GhfOZ0DQW zNAc+Zw3qxMB&Cihbl0>*cIONq`G?n_M6rt5v6*bY8_6_aA5)J0-SFs)~&;Y9aO_dhwJC z^7JdFLXE&2VlLnllX6p;O)dZRmj#E-?>e$;9}uf;9z(`B|S-Bv5H za;ug2ZBgCH_gj&m8B6`~sTPvBQLYR>oUSr)O}qj#1c)6$ijYrQ2*-LbR>X9bFLmpO z)Q7$$3j#H)-57o~LCS zn1HZ44h*EJbgUBHe`#IXKSICSe@A(hj;?p1y0 zTEk*50=>f)3RjbqYS`)c#>tzr(=hdmGf5~4Rj{0X6%`$0nkAiGFK$azAYVLY>D>=tF=jJm3C9!jJKz+^IWH^!aMl zJ*uFkptc?W*uI}%0H z1#hTH`Wu)J8kl#a$lTCRdb=tih|IQ&i#tZDIbL(#AiRS;&H98)9xyKT#*E-)25frl z;b#V91srMMC7IMmox6?luOt3jrX3Bv1pHH_d1+9SJWs+RGyWpPxFO6s=TbpRg9@L2 zq_MlKF-ecR%f`&lN#}Q1hnV*(UJMk71R4+2dWWgR>>s?EQ-T-6)gQk9MQzhb1QsTIfC;`}@#Dy`1;#p)JL;jsNt@sHTGh}sK zPKCU-ztlLQ&b@r!+qMsHH|i^(nqWl+93ij>r4TM6(55I4WTb!$$<};pQ@GoHQp1q) zAQ@XpdUB9K)F;$|K-YJsuCXwX-td~k`0V9?)5WvQdWn21=PYhfVO-A!7_XNo(OfH0 zsg}=~+LUu6nHzZn)H~~frBo-?99W-qjvX{w*{{g}k3Tf*kVT$_137=#lQURdMD zy`&x-ap(mROLp6TM6H|tNQ;&+wp{WO32(k(MbzWJ$zI2SK3D6T>fD+P%xjWqoPP}C zC{``^amsv#QpJARtRiTma8QQlGDV4*+Y1!YmHe_LGrIx@2&(M!8Yu6ikI9}2*gR?2 z6fW&u(Sf3Jl>#`K^t$SDwM8^3SnwKrRRRdUa+rbQiw2eaWi=N2r1VINM4u7i&$*=x z`MgK{?*&q>aBt-l9nT)otA65T&q*Jfu;O{*i7g)LJT5zzLxxkG$RE*w;H?>YhPQTj zhX;)!o>IDuc}9MLm8CCztSbAQx)r>$<;)x&OnpuABkNHQzpT>o$!fBmai^thXCT~G zlJk9IBqu}lk~4%QKI{hlkqcasnq;VaJd~2+JzjXolq%KOSG=9U$SW0*YEmD^wn%HX z1z&t$)3#vCLd~wATcaWKJu4bMHUxR>NjOjq3Qr=;<W(|^E{cvz;eVii=xS9US}2P5FWi?{l~pr|163*b>^z2|%uNV1vd*{2O= z9I^qQ=Z((!aczGy@VPJ=(*`JD5w1mpw1G*v^V$8PvZ(X=;c=Y~zl;m5;>R@}$BauD zmP?{>iK*!<$|H_g0AtsJOQ!n$T9`kpCAWDGpp9quaL@a?>) z;wZ940=m-9m*N3Qp5kL$!4jxo#IKNs*T5_$LxK>55K=4r4i+@O_&+IbNu=tvsf7SY z_K%t#>M^KW5));`brOFCVIOv?gz?nEK3%}}y%)^;A|-h*{1e%x&bdS zTD#s)QDiDiF7u_x7XTIjQHH4K>r{Deb!TCK@j8=9B*L{`V^MdE&44k(L{>IKRI?eP z5u1T>)htJy{}VO@8Vm|mPWE^r;frWDiyNdr z8{2OwFG&N+B_nS#jm6q~Hx-I#e(zL5r%f|>FtOB-M};D9cFP9Y6Ka(&0`ro)5Tp!rkrQE% zH6{rPt+J>%)CN$2gR+Xx`UMP7#K|Vi67oS<m`;_2@E3pmzDJtAJ*L7+nACDq5F2O@pvaFGB-P-%+Pu%*3_uhTu^{=O?=H3TB@rf^d;S(!g_)>J^iM`SH(^OpiyvcpA zLpDF+$LP36lrxyt76`$87mJvVhu9^pFv*0Eibnoum_|}hBQ}+G#-U6NoWNpA=>50{=h2o zQfz60E18_KHB~QQl7Krj(<<&ai=6cy@tRKwAjKm_zT{2OI&3^I3d@@Zu_ZvIzIIWm zqxY}i5S1a997^WAXok$zJ+HhWWr>Dh^wtfi&XtnuKPrg(&H^uRm{QJ=+G0T_F=EjW zYA?MnA3%nHOVNeh;GgAw)uiywRA??V7HfiCXB%8=l3PDA1UKGTA*=IWk@vy7uc;Wf z{VghD-k{Wof;pwoT)AEYhhn2Le)poGHcC4vmg7(k-~&Ds-O2t*)WHBTq`s`n9t>0w z9l*9EVz$1ZBXg|yFNO_yIk-9>kFYKRQ~!lEm)o+mALP*f+6QgXWz7ECp;9YrmHJhe z`n)`M9TS2amrdyf5*8bZggAD;x%V;t$7eGA?@PAcevp+MGVv?}mH=ZOV`1BA2;dw7 z%Nuw0N$AffC@S=|z0D0}=IuLQMX-#CrxI(3VUV6Y5drE8>+mrLgHuQ*r6;x8igr#9 ztp7tZ(l4F;pwDwARBW&t3D{MlWmL+WLP1=5-KJOGVn*9QH~h6xBT{R2oYjI-*<#6d z#5(CzB2m+BaxwcWuNNeFIr<(>MDv~oek~6$1i&8<_54CW}hxBQ+qh z;#3lXQ5+tK0J>&g+od^Ww8bof-2@|mnSk{z{jtHJ8@$v`ifim7Di(x$Iu|VeNf?8fHZrZRBneg1{+O))JD^}*_qh!h5$SPBUe0; z)OjKq@I*Y|iIho%@g9dKB64aY`j)K=(!5KloK?G0hO6m(0Mn4tPKr?MD74}qcivD3 zGFU7BVZi;HtSre9Sqrd+WuhRzj`cV=o*ZzV__tW7Cg8T|Ncg1qD!L~+)U5C{Ii zc#%yD-u1sn!|xULo6hq;{QOqImR`1Lz?PhSAb!N>H+e5UW$TCJKns57lvFV6tHABb zFh>g`I524>Uu_o!WTRsIAy3V;3bGaYccoTAjgUlBt}a>PDX|ZlC-z~I#Rey_%{}T< ztS#lFW?F-0JT;fq6`JCFFaOtiC(VIPv3bjDRI3cE@_%APl~QUn&^l#^c06VLou2`( zKn(LjsA2!{FmHuQT&;!qrePl7O3W)MsBa$$(e@EWp)c5tVjja&RSfgBO=%V8?R+M( z06gw3F$$#V$eRlH9%;UWd?TBQ_S(2-;sWkPCTlb^4)?gpHQZC#PBE`=ZyS><+}Anr zph*jlWrKEfG|4a+xOnPc9-sXUb1yf&ieMVgm%MH$No1~cF8@08737TY?mKy>&YLpv z?&BE>S~w+zVU+zB!!|S%gb^<6YqJL^pAsyCTUpB1UQtM;FIuPCa7@< z1y_96v10l70!rBFV@is4gnodGbILqnthfdIUhffhuZE+WWj$ZvvBwfcm92*I5BQF> zDz=J;tBUpx_e$?nq!n85C0()U>f)$%!u&8Wx&vm^X&fxZ|7$P_W|f-qAfggR`&13m z_d3ff42I%hp+opUzL)~iRksW*vlC!1e$FyUQ)~ku9vRf^J+_?g^WwA?W2tan8$T0T zLwIfLqg!mxz}cLgnrf-rG^l=bh>*r@9(Acum(5+2#)=UHJJf5`xjBA<0JHF30<1Od zZ2bUl5y09iO!zqyz`z#*YXM+MaY<^wuSy93iVK(BVO*=YR{p7+Rfa`(#IWer4GT7H zs8dI$N=#$A1A+(G2xzJy<;gA{J^UZPcr+m^gO!4)^Aj9=YAff}u^Y7&g4h-{Ozy4X zVNC!$EK{iDVGw^oG$q6r#=~8theBW!fRCkb1ONLZ;;p=GQM@@r=)|77lkC{fNjYO74}7j?*QlxD}k@@M}(SiYSm%3^7S4luohn z6=sE;Vyt>|ifx%E_{B2#E5Dd}>_Ku^n>gL$g*}jsKI}0-Bi$+NQA1@|86TkXV{WiEbgDgAeUug} zqGGwt8Yt6^*w%yPcJ@j6o5k@Ln-_75t?AqP+va({a*_R+3WT8)6v#er59rd?8ugQT zueGO^xn*>Ux@d~ZpgZ+XwS#)gac{l6@3Sl5tt-pqw|)}^9`uP2!N;!+GN|3bAYVX7 z`j_Lh%Iu57QXYmv@MaaOk|>OFY7u-sp^#HQ#y~7{nAmjq{g@qt=#lfv7ob6c$uQQr zvbSik>Pf>2?mCS!^uZ#_z^{L24f_c8G&E^vB2p(9=F;`#cZ-%t`ZuDpq<=kUd0u`= z_Ez67JrgCgt-FfQ_7Ig)$95L8U4djWU_|~t^Jd){TEkEtwxfMZ%F6`Q2eQY5@y`DAwl2*T_ILE71xE zXfF_+Xsom#^R)9{#uK*;kr%Qs3>r4fXLqSr8Kv=_V1d2o?iKj4w2HHLsz9gn@3HIF zSS9jw?W^=0Z6X%ltD^B9{SzukD`B2pv0@8`A%ZNjM>aT3kT)-=#JO63=OcdmuvyNxK9?T-}}w`kE?o5w7_iJ`2*!jLFo0qa^<&Li11G= z-5~oFRrh;cM6)1*9~L}e@jxbt<%ITA$r%EX>Frv?0XV+?VJ&MLLE2~5pasG*q1W)v zmL(HP6HkSAkdGLwknK^+?Aj(nIL70Gu@I>51Ogz5GEm6Spn)n3M=MGdxs;`O zCoWKh@cmLZJaZ??5U1cJ zI0d_toGD7blO#=4oMmVV|7wqHOKb0LwI@Q@8O%982YFRaASeJkZhh%h2B44 zrJ3bWI`*ZF@m0PWC+bMzS%(FP-q;`2SI|@6BtbN&!R&)-D-hFWQMrK*bZ zdu(WYpxWN(fD9T}E>Qx@%V}eY&;qS@jYGj+r@*0ZJ9* zor%xMe%ji27UTBK3u@n{bec`-?X0x1#nt2hAzZ=CA_=RO?3~dGY3l~oHZ99(#gG;z z#@5zO+lBPp?0m4Snw=lS-u3eo&VdGYEWKW21SVSLUV>fEy|ib1wkcZGyi&3EUgcCp zxV2K0L9k1efmIAn%=%EqVwM@GKt*aHA!7xEOFN2ZOB8?_>Dm`OF(_yiZydQdE$@rk zemdKEJ>FE!Y+qdteBpTJLE4t>yxti_nQfH|FxrMFGx;> zmIsbV=aunrqGuB30~*V0@1s~;|1_<9Y%0=sUKI*Z#95)R1d{C;-C^xMH|~HCBwi_7@4R%#su}buB`-}cDNaV^n}ko_xdefxO>O{=7ZP4q@DXxa zq*OKTMoucOkODGj(za32B;K1fDaqq>XH9ZdHaWl&s?=up%{IH79&xg~u#A13Ct=C; zB>Ju8h-5dbN^WBVVt(n+h_QlOynnhDOy@kM7JhVnFxXh%QV#KtB_cY%5D!xSv7aM9 zks^$E4`GGP!3bo2f}E0W^lpKKeiazJ+e{vRDhSEMTL?8G!kqDD_7f(Jr2d8)jfWdW zGR5}M0dRq=Jzd+VdeQ$H?XCuv6gABavvc}(MbW?<8fIfKF*8PiJQ`T;&h}%(d&Gxb z??^i@{ewCRTP=ql2HEGbpEb1m>cJ0p+0WTSI<_?K&J|`~m_S521;opRD2|)CC<$QJ zdz5`hHTzl#me_l@?zD&uz}hyk8KG!;5b~E|bK1}-`yA^Bm#%ZYt9l~QLx#EkXI&#s zr{g%nBmb~(7Jq02mh2w?1_Y@C^i`a_rv`(R=;Oh_86N=27yk%+0MZ!|%PPyu#88)) zbAw}R#|*B4G<0<$6~I=k+-4*P1Hp?%nhoNjif?h1!EBgaObOZE}}9zO>)o&9|E z9vYMnlHKdy0~)BVy{}BO=V>-f{0+o8;^fEWj%M$$_8=vJR(wZxzwU_|L{gp-ZxMFb zJaV@eZ-1-!QT_<82pEu6DurZM@|T0V63j8xO|sunbG+gj51D3)?|8u!kgJjmcLv}a zWWtQ6f;D(CtPacxP^oFNO(LrI@!j;p+9n9WmhL&g=7%nV6K*YG`H@eDOzu1?sZkM& zf?mh8NrAz!0uI_WZna39LBS+hh$^G@b<0EV?#z2~rmsFLq{k?oc%6eLFifC{d{wL` zHHtU6-jd+v@!Op#QcRoT9dt)=4Y4w0w>C9OZ!J~V~Tx%VY zCavYe2mVvMS|8VAT1fLm+@s zT2q&v8g&I-3GGNci=8OE6i8KsYQ!#{Ui}a9D9ICs z>_OWIxCZB0aT9Z*d)7|Fq$93iI0vwu*E&DZu#k_@guzIpNrsvUBvJv1;$lP|t=fKg z&w{Cho$^F@kKEUfiUFr}EX2@p5VPu7t-|dhRJ*Wd4tBmTQqNP-cj4tMg?V75(1_Vq z1@yYeuHJ*}@R?eJ7>3LRy`)~55pOo&r;I}0zSDJTF+(@1RW+6Me}Ou`Tv05ziOaC$ z10NAhih&u6FUhfg{wdKPj1WE`y7xG{i}_hzK7rQL*`KU27QR6hxtIONAc#E8qsNMe z-u?UUZXjUc`p))SO-nYm`)@~)R_Mw{pe-&RA1po{LEGU~>L2%-Lx2;(;4FxPeH`NZ z)E(iVmGGN!%j3Is%kN$KrTZORH`akDcS$!%Mp3W0gB$tW zT;9#waCx5+3Wifz1AN3r&gy z^wH=FR^Vn^cFu-8KiLAE1q43r^B_XRsKi%^p}!pbrJc__RCvfs4&LsR|<&w1%Rb+Ct$xy|~}p zO0`B#xvj|C2BAN*p3s_-yR!bfkde2pjf{Li*;5N&0Qc0aKJ1Wyh?P~34r*q4rVubO zq=^nPe4@vsG50DXXs85)I?u`9Qvp8Ak=L5xt{gbp$KW! zD4yL@E;rmokWH16;+sXvSHGg49whG_E(*UMKeVDw|%Wm948cLgM?06c-GZL zdW<>E`kfbWe0bj4N^dAJ+RsTJ*Wyk`ZZHYt3mzm`sa>&BK6y;jJdB&XQ4tDjj6SQC zd8iQrU|uYu(KAE8&5MG%T6f}zT2aS@E(~rhV4}xuwW!=wTgony#1Cr7WT0>92~sXZ zJQEmK5syaWO9kSY5MdZ+Q#ugOgoq;&@n|J15DzpnL_BsMh=+|0BA!VaA0ZR+ zadYk08+lx^IxmqIWM>1d2|IYgOAKz6ODkUIg_noocpg{6u_0+|cr_^xMJQ3ZS}>_p zhy z-c0Y!v*p4<0mNy=1}vQauG#-BZDjx!QGIBzL@Z}C$2) zBIK*_nsWHO_?ngoUc_Z-z#-@pDWoA_XJQazLYJ!2Zw#L`n!Nd_Bv405tIc^(=FKSQwr5%klPt9o8Yt*~z zwKukRH{OLZuk5yFTAG$-x<}nTT1}OW*O*i)kP3!SMG8_ep(vbSoRCzKDoj!lq)31e zASoUd;$VWI0wfTdq>Ona&hP)7dvD*{-6QS8E|L`5?djX+p2v5-^S#e^&y6NYm5A}o zLN~KZ))#BTj$;+q9?RacPhdh3Hk#K2KB}r#l;_8jZ?fANlbrot^~afvb+$sQ&_3IHUyg~f$!9du02gaP1-Gor_)B7vqX_|!VPr37x6CVj`zjwmg2 z#ZeFVHPVjgM)Aq4&R8fScz9!XlB%QDCh3fvp+2DjY^XP|%}*EhlxC31Ppw7Z)&f(P z*W8C#z#MjyQ!lk;qzy>CQLCBP09q$*;L4P0r@>RWZsiE8I`}+=Hq3EnH5>LA=3MYo z8NC?JF7I+F%Q~W9sKzL}gwDG}MQ%AFFLC&f<4UC}2qW0jby?DV`DCNfR3wQs@? zvd8CGd~-0EMYz7gGS^>{!Yq4WDO7}i&l&~ z={X5y6BjGVA*)!_!;GBN96?jXh@3@*l4bTFP_clqMzDah&H@IfOk75AwWPSL8NmgU zW7xHrjxxJ3C7Hd9+^LErSV^nE`z=G$$_=1IxDp7!)|&(=mguFsL?)MlhuTZ0j)!Pb($I?neSe$Mae=S&1(-;2e2wghsjD zI2hfq0kXBd@~v1^g88^}E&1sBJ>m9t@S zunB>QT#dIdDlfLehh_273yslgY{gxtAgChX1ga3n z79vc>&@dTpt=vo;6fs%eWPaXK#^m^CCH8Y-GZs&5Mm=aoY)0-*>=o(EWRXyEz%e(V zJHZCy^{~h>VHsB#2m<)m3{h z5!r+x5!+RQh@~8YE0PYQiI^MrC1SB^f{2;qFcE_QnIED5C47WLOj%6C!!ad2OdrRT zAjX64_!9^tj40s~43aSZfsyb~ObHxlUHFpwXbXa8&9Ag(X9eM7;=xAVico8@6w;4# zCUTYEEBXa?6fkt0jwTN<2xsI|=$qn}m}Hv*CUE*9K0_bM*0FbsW+zCs};1-;KVjWWi z3;NLhDB^{y(5%*5K~vlamK1fjcU*90mz70viPdHVWuRpN&1$5gat4XQk4(-!w3L#RWDj z3G&Y%l znlxGxy=o?qd6YICTFbFKz_4<_$1byBniafB#C+cYJM+Cl1oVv?L<`V@H-wM z3nhtNB_xU5bFEs4B1sa^i2zayBuO8icH?0GMl~ZZ-q3=6R*Ws80s6z`fqb|~N5xsj z5gNdFYe09!$gBFcJcOpw(v$Qm@uGblv@PVpp|C(k5608g>eDn_dZidFlz^<6<6DVK zCh5pGw3m$#Da33WF#=snp~+Tu3Jn5INjD{n)7lgocl3I4{T`%f7tzw4kfJj&MN?)J zt*G;xqiCp4cD^Iwc-ESKXfk9%8jZDG8odJR%R!^2?d+to`)a#r(nB=b$IuXsM*1wC z7c(593bVPREQDcIhZi%T>R?I|xzHWEsXCgBR&|iNBo<%xAi93h3%__Z%p1~laD_CT zav$S!r$Z46>&BYS{5KOZ()I>3`pyz9OkoV@J6Yto0z?8hF4H~lH&Vr6Q{zxejG7f8 zX9xucS4qK{y(k5zT^cDkTezIWsi;+xM}fN$s=R?5Aw!74cj+g9DQC#=L?M_#RPtZ~ z)#Eb*or**eh3IqX1OwthlB=o>05a(9XE zLcVKfH0IZ?(0d|yp;R1F4}7H_Y~A9U%mYAC_d=a04Z}KINr@Gwm|wHguRu1TbE*BC zAp)Xs9?`+xdpW<-%oLp|hJ$72|Lhciv4Dk0vf1xB}M35wAOM z4FA#{6Oof>5Rw#S|i7ttf+6Rakn1oP%l3sjH&_fg}*a`U$=52Zt z<_lDDz;InEe{0-=5geNky6Z%3+*|p;S0*(4DYH~+(hwa%00{mg4^^ZHJGAquJ!UDk zp`iqyP-JG(fSr#8P0xd75|y2uPdgE&HAX3k`N1;U0NcsPk~^VQWQi~Cg!s@ZqVa%L zV^I zyVy|7m^B!razmOT1|#fzi`Wq*kL`S}pmIIvEU-d5pApS)l<*7feCk2veSF#t+4*)O zT6C7(FcTa0>Gd3C*s}~0;082i4lJQ%jIqTP_(x<981@jiVO3wwupb<1lwog!>0K}M ziM+AF5=*0Do#hc3_E5dADW&L@S)vq1OV`m9n_h4|uM!#dbR-hC-qIu-8ur`?N!Yoe zlFgKbhP_3h60Yj&C1DJE$r(qp@vQr3$CpJfL6os!pGL1h_;L`X8TPh|LUvL}ly;RM z$}o%-O?rqZ`xr_SWq&pM^WtjQuor)ZM%RcKmI7Z<42zwEzygQPuvav)H>D6rO3c9( z;&cEFpD}<`?4e|lx0El2^Tm%bT zn|W^$tiFM7&-!MZfiHkb5R43bTR=1LMYRS51NFxf*K1huo|wzmFPU==7IC^Dqk+i> zYE~+DELGiB1tUT#JT$%y^EJKpT%l)d5T1i0NmtfLwpqh{^8;j64TS3;x7w^tQs(sp z?;r^#K5d(UGHp5@)su8|u=usk|d*#uHUq3DSK836vXmrSTBkvdMj- zjGru%hR4?n_Caxvu zKLyO8=yc#hvrO-^>d~uA{FeLvsLx#u;LdRIc_4%%E<~=emCoJJ*i!&LdhM`Y^rLo= zIgPMJ;&XArS6Z0pa(6){(keU~M_2UkD7TwJx`TE3QhUJV zL?iEybEn4CaB449Rbok#buo4 z;Gk25%w6B=G%;I3-l=X8P_Cz`DAFIzG@Kt|IGi&hL^G9GGjfO~s9x|ZB{ZwxgtHe! zI$WI#&hQYvvr-^tCD*W!?j{NXF|o^wYG!YoF}AL-PCgHaeFn!HF8VFMPpkb?4f;(53kdF1#zlt9|>hs3B3B+w7l@V9u^ryeO&pRA}gQxuUs2JsVx zQZ$NjNr6W%UNL&%C#&`?f>avJc+Hr{lp%bFsC2VJF=$x*iN%UF4qv+RkR+Ui8qi6< z_k*In+G%k0UH?Rv(Yq0TEdAb_SP(jNxW5bdRVKmPEy#x@6H#4^86W9JWuvT+4~Xolc|-w~V_r34xnKOaEpX1Afal(0 zCOU(hUA8Y(*N1v3BNIdS;w!pB!xDzhs*%_w>3We|#56}xzN zxZ{s>cC+8@^%s8>^u=7_$T%omgGrL{;1|a-#l$Y#JzDBGKB47SeGP{O3|HN-jkzOa zYhPKK6{7zZk+6}h2@KP(W3kAC8IAYEVNjZdZcTj7crsNuB~wMX$bJ>^q7iFk+Ec`K zm=)<9Jq#TcS)vuSq@-#{Rf=+9Eh)$v$%+(_RB8?L;#?D;V|<158XCP=3})_{sS+N1 zq!0z=7Cb;nP5h?W49tvUgTjNfXeD6~9dsu@hBsb>qBn77n z&s}l{*|yScO7$@3#~kEhwHV5gp!TPq5Thf$V{!U-GP zWwIyvVp2!x>w9GE+RJl_9Pp%<=bWXKNuqRewSTQ|d!aqCXT3{96;^1?FI~>6quNi! zwWy=_c`s+Gp`ZDezu7=6f*nqbir$rRp8?csH~_%hdw`$&@Q48p!4ER=dxYMg#c6>hqCo=fqhQQ&xc2KUGUSY$o6WGc=`P+q;ARiS|fVYrpBW$hp(=>dwR?u1RXGrpT?0o32v-w!Aoo zPve_eoTtF|3^emU}_W5O&ID z*l?!;8Qw$`cJ~+Kz&$RZ1QN#V zV-!os6@%*5ZRxAA#G4^4&(R8FYa@`gVL4!$pQzp098izAql7w;1Sr++VtcTn&JDp} z6oX}-{60vSml8>v>%}s*u|T;+Q4$AbVuc~D^xO+0h?!jP*e?m_jLXz^%K%~jsn_wD7_rA{EU0{_wRS<4?GB}H{9R1Ik9UwX-W7}{oQw#BYXKfKEb`JheDt773$KZDRTD< zA%xwoVvE4ccx70d5{I}+mVk1E)vr1$*oB7%#D^VxY5q{Z{(o@wtvx}sl(=zW4i1o# zwDfOPekg-IrG@YR#|?Y38CwM>2#Pc*meCV(^5|?Y z6=5P}F_F|4CXy9_*(@fKiZGF^D9@NSQ$mf{g*e%nE8+1oI8!d`Ab*oYc~_XhE7nqE zZjv7oo*on*BE)pD8kl;HPz2sQoWQ_+1;ER2XH;X#Z&c}TYIt@Kk&7!A^P$4m7N+xs|qiFB)q(1 z93jujj=PZDIFFHHQ4x8t2T$2D;l)xVYlps5F94Z0tz)M%RJFxFDa<1^>|IgJq3R_R zI()}1!o1d~T7I6K7#DToNWbFLo{wwwzO-|z_9J|2uY|-Iw6X#02A)FE_5pVDw9b_B zWaHaH+4QY^Qpv&A%NQ$=Y@4ByR0FM&;>TXkJMI8S>zg z#5AW00G6Dn2PwhiP$RWVwb@i{gjBLF>u5-^mC(~g!w|A|)jgO`29-oyuFCu2l9M2( zzFMgK*SsYfL(Q}Z#Ujow+YlmcgrT1BV#CH<6$OEueWwMa4K)!S{7~AL3g93;bov2w zZ&Yfei)BXaGUfp!XH53UxdcPVB#Wv+=Dd22C*hs=p^M4DdW$=vhPuL-!k&*90lC33 z82}?c8MJ5J`Sj#kMD3s#Vqx0uCA<5)=Np$=q3r=%VGtH7=EDd@tqMXJJdhlU&1!$h z+Q2vkCniJmFag;5TmiWgOBV?_l2XA2JT&PGe(VCV7rfi86>bB1{&vR>c2hQ)9cjMH zJtx*jw%e`4z}_H6uo*W{4DCcYhi2Go7Zr*lcZto-+Lu23r-fTw+V_pxhhNKXaH5lN zj)Mv!aj20Je@d(n57r%QMXH`nKrfvMCtySn;uf`^9X%24<>wVlfLtuP6?TNii#ih0 zkbc^C1*DV0%m~O#dRx3!+6J|LYcc@S64H1c6qtbKm@fB9JW*+h6;Q-ZIX@AhQ87V} zY*5A|s6OK#V1h@9M3H)E5YcP`T3y+?qG+NHP3dR`AQS;j^bY-5tUTiZ6eXHCQ*Q$I{an9^;fs6g=m!ha75^77*JR%Zjk z)E)4J>P{Yx%8hQ#-GLMP%$~D0hE2TFTkZ&cx>Hyg>q@U}D@K!tX%pC#vy-@!z$O+l z6a_Yw@nu;z*f{FSn2m?RqGlNF>QaO#Z05s5rU4#*OmnLG+~ZvmT3QTmJx^=s$;?DG5xu=4O-RZIrt zg4hq#!-qqWAT|@G7_&wQs0Ehz+R&r;BLhKs1%mV<$$JKZ23u&E@YAqa3G3|Z~@xy+_ z9m$2!R6h|-Wo?|lugAuC6M_J-Fl#j@5GKMXz_+<6>m)9Ag2Gwf^Bw8jG;c?qjw5}s zM)*#v9}L3e6(c0sKF%$*L@diJF?UZQN{Rs6O32a+AF~jih1_Mm>%q-ih(g~ar`|k| z8z(Wyt|$@=K2@$2Do7r!b7D=m(keVq7SS0VTPcT<99lLMx>LoQ)ne#VN>GQTg_~^b z-N&sIbmmxwumOZ%qZpskpc6!r+43`~Dj=PoiTptVGroC}dUg`Xz4)EK6#@(4dFQ(G zGg-1?=~n2SLLobBPfBEhB4n3(cG>tEMng~K?_#w%r4a6a2>pZqg)9E6fA6k{+)xTv z+X>I(0y!52d_VC~t3kZ**%MM(SDqWkYmjcqa=O+%YMMg(KKk6_XA=Jc!^m#kTceNC zD3_&8j=E^GTea`w%%75C8^zkkI5WJ+F+pIZP&;))v{4(AHP1PQw`#3-j3KW>S;#oD(sgmjoqb80tGWkI8#R1493pISO{ z#Hq>q^$K7LOkm^#0^(ncVQLSeaVZBb`^AUW+{?akV^}VU7{oN1%_Xjh9B>~Mrf`7? zq?aif`x;BUbfxmR2Qobu8}TE;Z~`vp1f0yz@WyA{jch3SI9nVyiM#UOW%Xsx-Q-reA_>fLhreU01AZnNF0-u3o(>aFVy*CuR#cdFW^ zRr^}i-MiNAR9*iRZ8Tcfd+Riua5w4u4K*vh*w|>S_8M#IqTcN`Iz0jM%0}ZF@E)ml zn%CERuT-zqn;VU_a+UF}^?l^>U2sx;X}!~^ zuT|gEUafCbU+lFzb&zqpzOmh?u5EXkt?N}LU%%FCbgFBOZm+YwDsTmbq0+nf)y$xK zvA5pdtamS7=xld;+glfV?e@m%dcE1|USu(@ZZu}<_0H=0rNx>0))v3k>YZ1ct&1DY zs~6Qm-`&otU8}HD@9bQxZ)~(zt$4M)A(Sz0_u|!Fr_s2$S>L+YX!SZf7dlEn%`Vp)3ybx|#{A0SrL{}T@c`Z4nswjZ>0WHM zFE%=zcIV=Dt9j?GblQjd+Gg*qbd-dyyVF{|xVhbH+_~6lzudDW>wZ}~@4O1KZw~hU z6Vx+G}q9;?p<5WJzQ;+b^3KeJhL8$5yBQ>dUtq@I`y=t#mj*ip{sw*{IoG>@>DI zFE`u3DmX6~X(8kcXz$QwW3%1asoK2irV3Cpci&mPy3=cPBQ?;y+1%QaFuqz}z1i#3 zQFU7g=bnms?P~pYySY}~YWI+dP2_l|vAW%nek*%R*Xli$Y;$L`Q8gj=SlF$aHd{@a z^yp8lbKX^`-mRRk)~~ivO|9$Y-C*34hS3{y+=ph9<_#Vz-(4s>26vs`s5M}3 zOZ^CXYjYtU>_XWqMU5W0n|Y*q_U@i@{pL}}e%U(~!H1q|XeQQEJTx`>%GD{;$EuCB z>x~QR4Qbfw6HipTjg4y;S|aeUY^FLl+z7>V0i}QToSLk4d+tZO#WXgyuQyxO-p&@+ zD9F|J<`(6x-f$<)wL8_fRiCQ8PSz(U5?T zR;+HqnAK~nV|TrJwSldI=5F*bA39Lh?M8iLYrTGzf==UFr_o)1pZf~ybl+!{AU|q# z8&cBsDt&C$dycp|^=7Zy+(c<_YGOv9oknlF)6zP(LV9_1y#XH98`W(Lu+GMgRu*HS zQQxetL77+_*R<}fIwZK-rk`fme7n`Sv*pa8=f3(qMo^pFeA{+Qb=Tfb%f@4(-s-DO ztgcty_th`H^zxInr{4Y2`)W_Uvr&&TO+x}DaWcbB$Jjk zD7C;G6HF4;0pXo%8|_!AXLgm^bkjhG7Ffumw;LP4xO!{5$-0?}udm&%w^oJ0XWK8D zReQCu)0UNqP3x@BewAk1S*Bf<-YT&O%}!X&d$N7!ZEHKNYOS^N_K*`->)Ty`YqeW5 z+bwLcwUJDS(YAWCkGRLmZXI5P0wcnyLQvKAX0wMWdw%y7y0*Qsfi){5vI=glw!4jf zzZc4mGqql(X^{_YmhbBJwQE?F5Rh!Lmpdk}wjp3MidFl1qt)n0Y+o4zC(S5%LJ{9C_x%@n^;$^83>v3i>2xD>FMc{)6@AN^WgOK z@v-R>+3D#=P9Hosy?6iF>h$zvc{+D?dfKDb!_(78&lL7dOi!QT*R)^J-+jlX4;+5r z)Qj6Txc4k3>~#dO#5#fpm|Lq2?`f=NB#2GZdtalwz0otcq%s;^F&xzFJtu>`+UxCj zFEl!vO#~+n!&;-&Y^-_DBX}HFYCimMD?*!UcYAdm!2mwN{u=bPig~{i-wB1V_l#;Z z?lil-uJ<)&_+!0SH|iZ60j=8_3dCfbwKU9{uVOIV#_RH)cg~X2WST~My955OZg+RQ zXIr=qo$W0-JQ&)&#%2{;Z=+v}k}bTBP7^-Z#@=CxZPL%S@IsIs-A3c4_f)6d?ar*> zwbAcJvvrg9^|hIHi$*p>*R}U_G)u!GJ%h8S+O3xJ9$?9CgGJu~PmN9jbyAIM^7+!0 zuZdN>ceRnP%`U(}9f(J*NNsJ6zPf17Ds{XkJMEhg(pGb;;XQlt`EWg>B?!S53%F+S z61Y43)cW>U=vg^t{hu#2?nuBJUx3kf+-aLKRE4Ejj4b!V6FZ?6#ck)^+d2 zoz1IlB#L1WvTtwM;+s^CE4{?xZ`NBo)%F%s(y%to5W&pJAi)=0?KHO_C}54(>`6Sy zf!mtvDoP*o#3_AGl_Equqgln|=EY-ciMwiQ@-s0)Ok8WMziw7vZEw?gdlievdl3bN zmI0j*yF{@q)(aizroG**wqHePfY=n+)xcXfwm!9`DK6bO^ z7&=4}J)3q|^WN*!e*$4~x38iCF$HCbh-bsz;@d(=f0dfYjA(|QTL-5Ys!qQ5C-kBr zPh(+Rh}o$fmI_=oe{s8wNNn6$ zZ8X*x>Agtp=6ZVz+f%|!gFjW@s$XqxU?dp#bkS$c)uvc;=-+nmocGKAZ)ATod({8y zx!(&8XaB(a?u?&V$^8TWoBiiA7qbs~znJ@eZ-3^&%uo2gmMMBaob&v(;PZYXw;24j z;OB#x%zLt*&3!ERV)kUNnEQvpyK{$vJKp<(w`D$``AzR%WRPc=dh1`Gt7yo>fS*$jD zh=S0n`O27vrkFoi{h;&$jP=U%TNYw^4Ev;0-#UBll`5*HUVY^`Z0lECZ0d<8CZE7W zU0rWUX6I)YW*29dW-rYy&#uf~o|~PUo133om|L7%n!7Z&Jhw7;d46_&Zhn4# zVSaIbX`Z;y{L1|0h1rFFRm}fyv*>I>H0FwE>pxN&7bMNA;Nsa z1;IW4CBpZ1nbp6<7}x3>DCf?00|(`)#>NINiQ`b*(2fjhF9-@=?X@2!4*bQ^W@f^> zMe9%co_CDzKgmvbALRRUeBPV*oneSl;`f1^=bhpA4)s6G_xl6So8>!`sPj_6^Qh+i zM1H~>=Q7_KJNnLZ{eQz}FL3CeVAE%U&ptlFsebS0bAXR< zcAoWk58vMlu2d&k?-0Ka^Eon5ew5!@`{R6m6dY&`)R+E&GH>GOg!dWfMExEP*Wd)# z(fB91et^$|eDtr#M{u3uQ{^+sXNr&3O0etR89op3d6VKTiPHw_`p6^G2E&2N_zpIq<75~%qG#~ZLCX3M%x$j21 zn$H}cXkPPNFYsC9v&82TpJhHPe14%a;c4E&rTz&|E5|0hgTVR{*Z+}^U^xz~@8MhX z)NlQZ@N=2#Bp!LvBA$DVYt1!U&rfqLoIU<$_#unrOFz$i-UbX$@Oe8Q{rf8S75}{w zUTF?*=HE}Vo-fc)_!a*@$tPNqr?`Ha&pY@;|Fovh@M(hkck%rlEXE$b-_1w3e=na; zAD{3F2PeD|p9&xE8%mffYul^1$Nm_Xila5wX0GmJ#)**3#387{?1lNor3-TtD!q!I zkH|dnNeLhrCxZAJSjD%yP-K{~<3^ zE|IsB2~3FR{4Kv!D$JJsS=!BczCZ5;{(_hB7rm^%u&zHE4vkFN^x zRZ&;o#oZ9+4PUqQLqy3KZrOsoua zYN3aWm&p)n;CBIAnQbO2W^*H26fsO62~J_C9Q%4qX7lrB);jI2Z|wJq@+tUW1Ed7w z)GUO7N6*if{ft+1L#n5%9O%gfLjoRp%y{|Y7JGm4;#B`!{)Ep&4}bk;gZ;*} zZ;b9;xGGPunB!)D@VVd#-_INw=sarTWp?Ss%Vt%_%jNemerc@P+S=~TxLBrOcr?FX z<>Lek(l@5_mrxMQ8u80t1TcRWeXn#X0yovCEW6hF{`hGuJk@yX#*0epB))`2%2S?;c`5 zo4B(ZGd2(5?|g8Yc|I^Ok#s$8EPs&Z6MN%gH&L~p3C_^|!QI-sir#ocf=j_6s_(tt z=*=Vo#onHL31ZokCG6ER{0A@w6|KPAo8QCTv65P`J=APj6?kVaRr;mgM4ke#Tn_6o zwpGk}!2}f(#oj)vS&51uajTh2*QD6nA3@G@U39WveaC1pV7voSmF3_VRSpbR0S@nA zRA*&$9SwCTe+2Lg`(sL+VaMMDg8`TKf?v-BfG~VtCe4Heh?>M<9&`I37yBaM%G`y8 z3$y$E6N(`vt4I=c!@I$OSL@y8W6{q06%-b2GW(-av0+%4Jror>M(l>=xd*I#b)$JP z#*tB4ct8K(@O?)iVTHo+xI%(F!ka}0pn4abgr%i}aT8mPu(<3%RAq`8BrLC_%0YWr zJ~jgMWPjr$Ku>kNXLN=B2zw_(K#`4Ic1ekZwAtdDS(UI1p_s@oL9PD2d>Ffh9{SqJ z%f+JG^Y@Ld647`WmrQ9H#iA%DKw%go9LyqsJ>!LaBiPOQFkJ*cdizIln^hr0&C9FG zfuSm_iB;K4m0%_C%LyD~IUL1iI)>Ufj?y@R)o>D{;Q?%h2Qe8=VKG!$A#eZw!f9Ru zygqfqKjojkk}*Z!jn({x%xdq>MQ=9W#EA6wJvxf*HVhMY>sky?5;D*sGqBn@`q+f>e$o|#mB=RUJ0|O(bC?E?j(Oy2=H#K%~)0x_j2}A7q&gaMfPfY zZAYz$ByY?#)|$QSk5yznj$;HAP6ao+oovut>*g?J8XMhg6D!LrG+Huj);?4|%JMp^ zct#Q2nHbo@<9?@*x!Kt1=C|rBSI6P?txd(<3F2SMUxeVTkX{VhI+W$ZU1nLAiS? zmzB}!cfHc4f~kc68~iAm<#M%s2ahAay545<$FF#~HhY{MzvPu4@Vz6+&Qr@YRygc; zGRZ0CYyrp1M|^MJP_vA;r?3=kl{-01;EnCgR<~U45$4^PA^6nYDP3!_AF1n|tO_QI zT4lrdP=6s+>?=Hz-O6s|xAxvD6vALXlgert`~zNADD@9|S>pAZ{vpp1lfU1~uJ<-K zsMwz;!HbC`z>eAu7fuFSK_^pS|77E8y>ry4@JOD$+unB9D-X7Ep24xgK~`^YIy>d# zzIQM=M&ExpQ8*$*YU+81njMG9?hu8=qInSaX5s$c&>57$NMl3E3S$E&QdZPRPm`uJ5Zf#N>qAj}l` zB|V|Z^sT=2lJN^q`M2_Lmv&eM2q-1&@0C!YGuPVWI8a!ifi@_)EV(@-Z6bMjw?|EB zc`iuP8ET;2$q)`nab<*P7~*6hZ^ojQ?kn&_N&QEU-OHS5ud zXMeWxRXNYOsRZs~1(qRdl5|w3_}QO$=5*|;KIBOe&aW@t@aO!cp$T2mgqFRP${sw$ za1x&HUv{v@^&PAWuJU76IfM_3`tjTsGU&F$De%L-CQ^lAn|)DXQhYC_mbou{mr~_@ z!FnlG9t+CMa*BfE^4ZMFuEOu~2>JF{s?5o#$A`tr+fqeZ@64&uf}xs%x6k@dq~PsS zOlC55BeA$sDbO67oKE$wUKGuk%~Vs9?sqbqN%x`_vzb$=g$dc=bgGL!fU}v&$~oUV z{W?sb+(FcOc71B=%nkpm`bLjw8`0F;y}Mq1(@e4RgWWl$J!p)DsvN85((cCCy_%Zc z^H6B_JY35^j9r^4Z?vz^^xD_2Z#4K-3FCz`l=3r+(a>PuF*a1bl2Q+LN~)Ls!Xa%B z2V31vCTSp%$$W2-l=bPv(^S>sL6KoLsB#~_X76MtxQ5? zMD|C9G5q4N@)W8F`$&1F0F^2(OVaO6&JOM(Oqmv){TU-V14;4mAr(zKZjNztYwwU% z7zuN~a2#Pi;qQxNUrcp-y!}H`*O82WpfZ(-f_;d#q-cdoE%-O)6&}p4AKE&6!$0aD z9P0dtcg)0O*da3Yc<$G6cl>h1VP9v5$BOD@DSgAcPOyd)(+zEZbR-)hc8KL`@^6Cb?tF}&d5!%@X{u|<+xWG`FTqlL>~v4zWd1pyu@J)`OfLw+$tu1w#EYD2n@>y#=-f_@+! z3J8PjSa^?;-Y&BKC7osVN|#F)J*JTo3xO{xM<%TYj-}JcuZ7Na7bxX4lJFmodN8@2{f% z#=P-L#rHDm1B%>}>+mBN$=100L!&4tB0{5}zP!y$?JkH%Q`Z^ad+^>Akvr}cj%KzV zUZ1)Wq@^9}U`mElJGuoplnEO>^%HDYw3VbdUVR!W=|G~+a2o`yXzRPtHk8XQ@(dHDGrAR@ZV5uB@>GvC(fey z6_PGnxZ&R_5V+!DJ0a5i*s}fX)^FRdJ&ItoJ2bhC3_`CWsY;Px8xY4{QZ(RU3U~b*9~CIgg=l2M_Ge{Uo9{Ta0Mcm>|4; z_}(k}e9Dc9owwbcx);)XWpF>dD_=zrC9(MM?#wpQy&1t2Ih^qynB5a66U-<@*#B;l z6K1^eXy5mO_I>^HdW1l!~8Ikt}&DkTpsQ{-i}M`Y1shj8wVf1chh(u zZKy4G4&A3Qpe1IO9GE+YM{H{zVZY0^w~oFcsy=pK`aJ%YDe%Nwpum$~4hnqW&5+Q8 zZ=Nzv-Dh#{Ng37qG`=TgOum85v#B?=b9VZ5jo=i_nKw9sYxU3@iaI^~CPPk-yl%(# z?3?gv&kbQ|chB|F*Wo`*zai)0{Lttl^yKN#2-u5};FY`U&CRL>R@tRu%QoCp_b+=S zt!4F~mwzmkqc@`#Gd#bHJw-M|GJS96TJz5KmjC-1Z~sB>MEaJsVk@MlCs+LYreOs4 z%EHKuO2WvF$ic{sPQl2JNMlH3U=&6qDZsg8PC3b3yhr{;X;k_}d1UrQI>{my4P&Eo zFUCi}oKRD{Bv!<|?j12Fn#VF_;{JIT`-~d)V~?}QGdNw{18jC_!9Q2XJ?ITBn9RG- z6CPe~3t%T|1ox$g%n-MPf#pOm*^`6*mvgdQ#40xgqM!&t%*Qkpn`v|Ng{k{xqs+}0 z-QuP)g68H+ha;;mX|>JGmtFZl#?9P(B~>0R%iMgL8k#Mmz`6PH6Cq$^`3#subMt%p zQt&&Y%j zY9a%~$)8A)9C|$)ABPtP`wdCwUOgXqeG$~7LoURCz)!<_?0)g5<3ma?9V1G2cj7() zhm%7X9ib4?T|O{`(GgAjKMedM-Y%|>e?PlFFe5$FH`23_VGhCNqHE|PKf>NEMEPAs z%inq(`C8?BWoT7iS5DU0U>4T+h@`7MLpfATXYWuU^O^`ZdH03>`u;E}=0F@*J(vij z9#UBAaOB$mY%%kM_h4^li0%?{Fp&uqoE}kiQ2J&@Rq6*YocPQ>G@_?r8Jz2foARed zv`9+i!l-#9gmUpP9YlgOA(u;WhILs$g@S9>ltIMnk*L~$oE~#w?(w+8J;xF?)3SSS zI)8d1t~n&l_oZv@AFSCIc?VLt+6RwDgNI$l!u60a6$|KLnSVH*pt;FW=I7k}k;!Dk zSh6Q2|Iw+DRZ_zL*g#hF@zLG(Et0wU6N8!1Cr6Ky(h&~~HhOT^MtvlnvdoNXoR%?} z$jO*W1kX;p#Xh5*!-t}W1|D`<6^|t9optrj#YFLFYL%wbt9yO`H8X=#SPV0XmilRY zm-0e$>rtdxGl8PR8*;a3}l&L5BX?ss5Hq4(&ZkIo8o8`|BMMz)hkK=#I z&*r@OLH)R^-i@Pc{^DSpd+5}-Rd8Xj)ktj_*Ut<|xl!6MuAUv5$Ozr#)Lq=>&#l+N deD*)LUc=`, + removed: bool, + revision: u32, +} + +impl Plugin for DetailViews { + fn run_command(&mut self, id: &str, _ctx: &Invocation, _arg: Option<&str>) -> Result, Error> { + Err(Error::NotFound(id.into())) + } +} + +impl Views for DetailViews { + fn render(&mut self, view: &str, _viewport: Option, _ctx: &Invocation) -> Result { + let keys: &[&str] = if self.removed { &["beta"] } else { &["alpha", "beta"] }; + let body = if view == "list" { + Body::List(keys.iter().map(|key| ListItem::new(key, key)).collect()) + } else { + Body::Tree(keys.iter().map(|key| TreeItem::new(key, key)).collect()) + }; + Ok(View::new(body) + .button(Button::new("refresh", "Refresh details")) + .button(Button::new("remove", "Remove alpha"))) + } + + fn handle(&mut self, view: &str, event: ViewEvent, _ctx: &Invocation) -> Result<(), Error> { + match event { + ViewEvent::Select(key) => { + self.selected.insert(view.to_owned(), key); + } + ViewEvent::Button(id) => { + if id == "remove" { + self.removed = true; + } + self.revision += 1; + host::refresh_view(view); + } + _ => {} + } + Ok(()) + } +} + +impl Details for DetailViews { + fn detail(&mut self, view: &str, key: &str, _ctx: &Invocation) -> Result, Error> { + if self.selected.get(view).map(String::as_str) != Some(key) { + return Err(Error::Failed("select must finish before detail".into())); + } + Ok(vec![ + Tab::new("info", "Info", Pane::Text(format!("{view}: {key}\nRevision {}", self.revision))), + Tab::new("message", "Summary", Pane::Message(format!("Selected {key}"))), + ]) + } +} + +register_plugin!(DetailViews, views, details); diff --git a/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm index 4e4f1e858b985ae9ed2139797b81e274814a5c74..7692e5b065b75e448b19bec5cd31a5a3e2eefa6c 100644 GIT binary patch delta 514 zcmZ4fjAhL;mJR1Q8Lw}?z`2=~n~8~uil(uGEyt!8T3M1p($?fuTlM7@^@R{^i zwuo`sljfTHCb9d8>pyV9z_wF%Yll#Cf6t^PUcfm;0|SEtXE)gG|3WJJh@lh z0O+oL>T7{yj)ohMG}Mr0x6BVw>lw++$>1ySY}4m2vY0jWvvnOD5N9MT1Bq_st60{EUoCCmZNQ0?96& zCdM_Jd37~efyS5{0WII0VKkSGam8jfOAAKE<(uuTelRnx-fUraf{}6AW=4li%#)>D zw3yR?ktU!nHu;RRA14cg0t5FcMn-0k$mV31?BxQE@|MmY4=FNTJ^H@!pm$LG=6kO_ F-2p^A!~_5U delta 503 zcmZ{eUnr|_7{~X0U-NIWWgG3RZST%nV@*la5MgrSii>kPqI9klQMgq`p{ytmCG5iC zHD)V3Ioxr1F3#!r^RASl&~DDPI!BV9%U!6a@73q|em{wHRxF*h_a_e*e3r+0L%u8l z;vh*hXY@)i@}cooMx2(+Lr77uxRx3$y|(D#bZYT&ZT9PwBA3az&DwQ({&aV7W{i(4 zVc=AN3-3epQ2YazyjpS&Xf$Z^L*r#z98f7_uY=0tb`4mgh|5VavyCE-?)S?UoFiDG zQD?>;GNj1m8W2pxmBD0+3#Of9tD8+9JKjXTc@+AtC^X^eL5yxZ4s7$YM@5br4u^FG z679Q7=)`Lkwkhuuu*+vYJq(|LaYffu)o)Viw^AXBUX-NBgu7Mbu-gs;Yo$r#C*Eol zx#^dV>H{B0^#_sQ8~+y|N!5Wak@JB`#JQ-vOfNo-J}Y%r+Qr&nWi%UGY^VtWo7__S wPsR?{H~a)PIJ@ycrn^ud9f$nf)-oG2MOW6_cSbE&TJk@7It!oq{%_l-S5IWew*UYD diff --git a/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm.sources index 2a197f645..52a837bcc 100644 --- a/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/endpoints/dist/plugin.wasm.sources @@ -1 +1 @@ -26ae74bb9df6f88bca87a31d20fb00d52cd9464047df3525d0e47b5bf6b2b2ca +cdd58d817f507452ed192e3a19071bd56740efc70c4a965b0d48e5b224fff1d4 diff --git a/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm index ca73c072e215c8eb1a304530d865e35792381b1f..892fa6b6edcf012364320a48a4a627433324ec8c 100644 GIT binary patch delta 328 zcmcaGndQo4mJP)mjI%eFa2#jhU}EB8W@Kby-0aL7&CK|7@_d0j#_N;$1ZPTZ*);Fn zhi4Dg@2GE8VAf>ja9Z5-cgFsU@A?}z9}v97$T$zEN__Gr;c7f8C%cIhGftnpOJov? zB1RPBCfAC2Pu?J^2vi6%@uetU6KlnCCPzsqOtzGn%s6-QSs6DVxl%@&k$dwCu|P&3 z#|kJ}B@x58X!3OlS;obize+3x3D1@?Vw}7AoK!aBW>xkO&VG_vH7wqLVjEi!sjMd`dc-aWb#? zWT0^i#od5pt++HJ_hu7W0Y=6plU?N^8JBFHFK5HbxM1@gWeY~ed7DL5OIR2eZ|>4O k0Sti6!P-|A3Cvs@CsOBl+W0|{XJErZp(UHm&&{<40C882tN;K2 diff --git a/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm.sources index 436aa5dc3..6d3cc157b 100644 --- a/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/file-templates/dist/plugin.wasm.sources @@ -1 +1 @@ -24b3c81c74355174aa2fd484677bbac38020ecd119aff419d0479a942e2e4dbd +44da806d4e0d4d370534d108bd90406bcc475bac17cf69d0d323d341b79deb9a diff --git a/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm index a679243d79363239bdc749225e267a2a9981025c..112bfdbd8ad2c9b0a3f2c9cf70c078dd641af858 100644 GIT binary patch delta 691 zcmZ{iUr5tY6vub&-C|=K`~8SbHkjVu?9XOxno#Lu5@aJnD+MWXh0K4n{ye2F*h^2@ zLmhpnE&KCxmHh$Xk_{EZhioVn5kp8V%W5r>=wQe@QTut4?@9=xTn;QXIu*O3*(FVT;VQ)>%^Fwk&PNW z(QLyFOhR>YH5rWHWJ#4?QX`Rw#$pt?GOYF5h?>(KVB{mEkF}s;*v)XS(H-kLBvlmj3cGfH$v?S5$h^`@7ey~f66@e|%d~O>?+{C2l7)T3vGT?&Oyf3gu3yb37Ft|h8h+d@L@`)Dl zJ(h4X=z{k+(b9;AeO_#BeJ*`0G)d>`FwmxlPrSXYh7hXZLmfR7KH&OLBfP_~h;#Td hG!1X~z;X4u6dik-gxQ_u)X!9=dT!b9uwI50|8LN&6TAQb delta 715 zcmaKqUr5tY6vub&-Qp+P+HcS{bnNGEKNq<*U06wvWk|Y*7?sA#WX3d6T2c_~q1uB& z4+`cf43Yl0<}Yi_NlYWBF!`l#@m-4KTKP>Jq@#6)>3H=-@;h@utOG-^%V#9ho z(av7FrnI2qHMfkBMj6N44KRXRJq~!lyq*LIYAhDh7>FKUH(D{X)52d_=WPeFLz7dM zOKKsBqb@u47E6MdbDOf}?T9Wr2amcOtfR~X@Cak&L0;!;eXPJ2pm2|!sCY^s!7O_- zX7226_OU&OdV%w%YyKE=D48B`wTUVZb#uolfAK$g7nj*p|6u_Z@a>Vau)wO1wgBA6 z(O)Ox0ucce9LAq&?>+h3$|7fcDpS~VHFD_ r^{|W`yneu$$P4(y`p(7gieB%kdSkfZV&(CQ=;ecJL*vzE`04)(Vj&-_ diff --git a/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm.sources index 768e2239e..fedec7ba4 100644 --- a/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/grouped-views/dist/plugin.wasm.sources @@ -1 +1 @@ -0bb069928979ba22a2d6bd977108d905ff870ef981aad6ef4930834ad5c35c35 +6d61b436c76c26b7edf444c89c8e71091ca7c5bccfba9ae79e770f70f8b9013d diff --git a/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm index 3e720c89dc77f875f94cbc7752fc39231110a9cb..612cf46bb7bd493db1d39a5064e0613046ef1dce 100644 GIT binary patch delta 381 zcmZp?#PRDQ$A$_4#$%f+1-|ewKHQuqYbwFi#XR{yjL76w_G_f}9KW>Y>9f<1Z!@$i zFl#b%IQ1RtSh4uo=^gBo3mwEZPc!?+!8Cyw<(mr~l9?EPPQL228;_xzS3AeCvK(e+ zWSPEBl~HVRzbxBiP0t1LXwHy8IHR>CfR}Od2M49i++L4ZnBFl>E>r_KU462ae>pyz z_W0{CvfN@~WS+iHk5OteTi`Sl)r_c~-5%J-bQofGbkIB$m1x1TJs delta 368 zcmex$k)!bv$A$_4#{qSm*j diff --git a/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm.sources index 42768ddd6..2d8db8996 100644 --- a/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/hello/dist/plugin.wasm.sources @@ -1 +1 @@ -da7c5e58d2d26b7613a8ba5b50d4ec7788438f186b4abcfda90a9bf0c34ab591 +b4fedecefcc934cd6ddc49c3ffe948468a7603930a47c3594be85f5f01758fab diff --git a/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/hover/dist/plugin.wasm index b6e97341e29724eb2b1336c32abcf78b0fd8a879..baee49a890785565a6f958f239eed2d3e9c092de 100644 GIT binary patch delta 402 zcmZo$#`xT6ljPo{c;JC)Z$;8CP%*e>Z%(%IqSAd0a_v8hFd5k|N^9xOtytS%v z|KXP#t|+%EuxK(%I2~{5+1|Nx=I^A*`-T28p4z-uIE{nx>STU7@yXUQO~}fbHJLdO z$~WJTF=J$$15`K(x1z~=<#i@cQt-fI-W_?b z$@YqhlP@YMO!n89%s7AYV+}VTxnDz?k$ZEzVjv@svk@ryQ7MLT$z(reS;nQCbCj2Y zgoRX%80T+xRpnyd?5@er$hcr~xKU>EZ9cA@#KyRIvzCzsBjcjY$;LmJ z8JBO4F+ah`xNx(or4KXX$<0MJ8jPD)IjS>mo@Fb*viYLZ;(Y>9p%2V`4zEylXM8;E OMC!Lk+glhJn*sqaRH9e_ delta 434 zcmeyfl(lUc>xT6lj4L*8;JC)Z$;HgX$jHRZ$h5hiSAd1_=;Q^0d5pg&^9xOtZhNum z{*t%*Kc8o4RbbI%mTz=&%0S z<(rpli83-S-Mm*jiH&j5W(6Y)M#cr3BaMGBGcMa4WPXB?asFm$OCM&&Q=2nvG#EE; rw-aF5Ji%6-ar1Gf#rp)C(F7=eI^adQ_hHw)u|$e0fq{Q=ftvW_G+mL&61rlH3n%OA`f!0IxH}mcStdKC zN^ZWYWXuSZ;Z#wW?5PqXzXGI9fx&UbvI7kaSqe-FOak-3LQIYdrv&1CU%h*+c`xuFx=LT(^0hhBg!9!p*m|f*2=j8oEtB zuB*$qX!2LxNXA8*{q=mA85d8UYZ%G77;Fi%qrv0=1Fg-PMiUtsmrUMm9Lc!^Dq%7? zz)oYctH})}##Ni;%+K&LF5mpx#e$J>*=7~DAIyyFH_LjRU}Rjn`I&diN&%sWO-b`q UB~`CTT0CpDTc5wV>gz!#0Qxo3bN~PV delta 532 zcmdn?fo1mxmJRDU7$0rkz;T*|pNpA^kr9YM1QQd}<}O}t7RIBKrwQgUUZ4D4SbVaK zP?OZnn_mt;II?{9J%&~VW=&=er#1J^cI|tz=E||n+l9;-8Rr32PQs&V@+^^J#vPOS zMDZ!wyi-(?lVv&+BlG05GbARzlPgCtkrBn-$#wEMjMIVE%1!1}C_zz(>Oi1E@5wB} zikq1fH!`wxGBUDEe%~#z*+s>Kk#X_lN>zo)o0SwM&s2?(U)s>nz@Wh3xMJCX28JvJ zCIu#ed0-(XN0uysWt&CRmV&hGQa1vUZ`J28u9)1VQOLM*@*fRnAnBm#%(!ZD3y@qn z`Glq^uHEdV=gZ8vZt@JnNX~U&7ce^-O!hX=+N@$Uk&$yfRLErV0z;|EH;m00 z*KZau;b3N5zFE@z3@_u7&Cgsc7#SCBmUsKX%(!N=gx3j1#)X?7dbg|;xT#aip*GJf TPA5P3q4MSxZktQL9&`c#+^5#4 diff --git a/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm.sources index 7b1eece32..4165bb01d 100644 --- a/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/indexer/dist/plugin.wasm.sources @@ -1 +1 @@ -0c0e4f3611971307268cc8e2cc6fb96734923f10dbccbd8950639d86036c682c +3f49e3bb7f523103f70a39087e96500b5cd806ab60de60fceb480ca54ad4aa1d diff --git a/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm index 365ad903602d0fc0a99ad091239e05d5f1879b75..943a63cefa0eb4c2d2d01603d9c9bf40d66320ac 100644 GIT binary patch delta 342 zcmeyoh4tkY)(z`980T!>z;T;}lZlI+k(rT^iE;B3USk%<&dDbP^B7-FHW!*IIcMLD z-cK{P{!(mJV9{ijaN7QG#ltgq{x-XBel9eDjq&Q_3dxzsikLN-Igk|TNSQG*&Y3(% zR&MenNs-A@r4w)~o-80!#59#@GJk;BojEqY+*DL8UF|L@rPDPe+<>oUgF3g)bH2E1B7fqJXiey~0xk$@~ zk#Wi9_1Y&n7?*FZG_hc0T()_W=?`YcRhw5^o?v8Lyt%}>?2Len{4&M!SH382H_$rs Ol`LrS#S8dMFvSDOg zym_hiNl*~wn^-V1F5SGs^anHJ%FPQcPcSkr+MH!wc19rG)Kl_;*VdNPF*hqzRxR4Q K{R2B=We@;vDV;|E diff --git a/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm.sources index a951825a6..8c1c7456b 100644 --- a/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/inlay-hints/dist/plugin.wasm.sources @@ -1 +1 @@ -c09efb8c9d0be262b7a25099639213e304fbfd5b0b91ad3d80672fb8148c0e4a +f3290c6ef1e794c95d3e8993aacecd58566e2ba690f966f52613a2dbdfa21dd5 diff --git a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm index 261df6af6b1d50a13e93b8c646369f6fa131a0d2..8bbe87f6d5505b2111da67c7951032b3901dc85f 100644 GIT binary patch delta 1119 zcmbW0ZEVw36vq49+qM6;C@me(Y(xHC25Yc zXtZn$<6JV91ABovMeG>agu>~v!WkUJlF0-Uo82|0>y=_;f8=Kzc_p|y1e&nKT6L6SHa|-Y| z*XR5x(ZkhGW=foLKia{3D@!R%ULL~1OV zZ&SHf5n2*f&0rg#+-KwZ1E+KS=X7;D0*`<`Sf0sQD-WdLD+;XEX`-m%VY?+Neg^|I zZ&lAM3bX4*msV9PDzJJs^+0tM<>wbm-UE*Fb-z)dnpi2^I5kkr!6HEflePg8;`j&4m~Vle=pJMkulE2|CoZfU7p!gk|_%n)JD7v@(tM z1fRw*j|AV680C^zP6(W57o8 j8E+i2=Dr&LD@apU7B}_TyP=h|WZZ@hQ{S@Nu&(_F3h1r2 delta 1176 zcmbVLe@xV69R5DcT`|SNZ z@AG-y&-=W4$95-Q*qt1@X2q}Ky7dp$s&UQ%29@0%pdT~KZ473{aCgcbGlvO)$`>gx zF_X$wOFRQaZC0uQ4b+l*Fy;24q!4F{#V_Tk-?2@TQsxt=k{3pjf*qJHk~iyYQ_F=boNir?VmnZM8~po3}1<=q9ovBsw*x- zSiDnwlOrfzU7pV|P7!;S*=*5Gj#0&>jf;rgYFKi`?RG0E+@dQLZ#}{kxj6urc7>)N z-G<-D`Pjg{j?67FBKy=Xsh}r0(p)l>x^(V1LJ_y(a;VyADu4VszN75YJ@}T6m%c0G zLuDNj87^zaCnEC+0~U*Ty+zhe!c{1{k;xGEEq@VdRK2n*cm9nt=G?e#uX6!te@VV5 zD(^Dl0*$ZgyGOU=t9p|SF$(ph`6f%C(!x#qUjY^w!rZa6M0WpWcrF|(@ zKK(kA6+@dCXxQ0+uZ4BJ3O3=UfFqxrj&y3M?-V1?ECjAnthtF@b<-OkRf_GKEesRX z+R~IfkY<&OFV*es z&BsYm&|AU83&9biWuf#=hm9#(pJ?u{<#d1l1KgnK-oZ)?(5k^=Z1m+4(tURdV4>K6 zUF;m(!O4F14$cXCc!_}~Kiwc|M_Pa`3Z8Goabl519HFMjCA=>RqlbXABK+CfX)WdV jXzO&&lySjkkH7uqSml}YAk;NT@@37U;7r9VOm+VNT@|Z= diff --git a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources index 174a21ba1..ef1c5a1f9 100644 --- a/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/jobs/dist/plugin.wasm.sources @@ -1 +1 @@ -7c728e98b1e1d4ea3d03831c263298fc4792599a81138e40dfd4c48ce6c4a47e +7e95ef2102982c48740d664cf050c86d2f7015d438e30376c35c5a97c2fb8c1b diff --git a/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm.sources index 0bc51a89c..2c433f90d 100644 --- a/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/misbehave/dist/plugin.wasm.sources @@ -1 +1 @@ -d8626558aba036e4d476df9929c6e16089dd0a1e43101b48dd978946889c7616 +58bcfb533bf386c0f0179e6775be834aa2d30f1b5e88e7ca00ad662bdd35699e diff --git a/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm index afd0a867f4f517cf93e57861f01710f82dd640e5..84a342d639ef0a1214dc1b5887901af2451edd32 100644 GIT binary patch delta 467 zcmaEOob}mp)(sw9j9r^Oxt!Rzn3$NjnHd?Gm>DNe6;NRkVBfr3AdQ((XR?yWB*xW~ zw~FL3ewnNyI#p`(l=;&?e(Tu(i=kD4MUz>=>C@DC{R_6XzVq9BNz{yyam{2-@kpk3 zOp^sdL?%~=ccW-v)@0^D(jX(z!oqlP@ zH2I2#!sKYZ1Hd4V(RTxq5A~$kxVbwS8CfRhrbupXP&Z}-ivHITpL|+_bMhCB5XOy@ zJvH?hH*K!aTndts(>7vUy*W^ui+OW{K0hPl+Q}0PA{p0ieq|ua$hdivQ4$;DhRw+q z7L1JRH_x&B!OXa2^HkdtjEw6x$Jwu8pS;LjYciMnjLm1<Y?_0Nh&*Y=!vro8#Gs2L;U=E+>*k&JIA zzmE`|Tq)j-tejbsnFC3=oJ0!?%K;`v=E>>e=9A+@1t!0h@xY_rUsi<)Xncvh9gy5C z@5wZkY4ZIrvB@F|)yTRSQEZufP|;!XO9gGFWlWP}?n+HIP%KAQjOrwy;-ie4H@7Rb zvM}D7%&V>eB+b-~Hm}tPU}Ri7`Jbl3>e8g4*xf`;toR(*a(#x0Yl8bmT~+5Fx>l#y}cW>%vlHpX?EGb}6^ z8P{xHX!(Pgant5mwkH@FS8q UTcLJdIZqYODsQjnVN4GP0Q_*e?f?J) diff --git a/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm.sources index 5da119f95..3af778b65 100644 --- a/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/path-events/dist/plugin.wasm.sources @@ -1 +1 @@ -512b7d41868034322fccc15f100c85e9f53335c22aec4d7492a14723b54cd874 +12e92a08e3493a282b811592d1f044f293d6296b36b4c8e3b25ef80c5aca022f diff --git a/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm index bf350cf23bb73c505e3b9ac634bbc56b43164eea..ccbdb011fc65f26f00bbe98cbcc0200d1c1299e1 100644 GIT binary patch delta 395 zcmbQUjdjj8)(suJTue+{%#4gojEsz%C-J(nN-bS^XXT<33l1{2Dlls@b2!~Qv}@_T zmD}#`sNeii$de79e2C;pMtt(-(yS=*jHu>M&Xe_;yg+6PJ|psEGgv0OD=SPspfQtD?s`b7#trQJJ7(8rNE@XBrp#w#N^15C9rbyBju$aeI2SsKytV0UB=a$XR4_) zZQh~D&&arB@(Ha-&Lv>=%#H?=AL?sO4$*$hxN5V7P75dF^38iqEf^V>ZT@EVgPC#7 p=J!@77#Wvt-eGh1l)zFEb5*CNCdRmh>z?@D+_z)jPX!?=9%9u--}6`OCVECoq5s2Q;@ZD?p<;9;Dcpe8o?yxKv=RhuWOt20gh zrZ^d>pi9XONM2Nu-MmASpOJCR<2UB>do)1PB1bq-n_%+?kNG08&^Yk_x`VX-us!Y@lg8J?MvAi%Yy-m CW1I8< diff --git a/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm.sources index c4f8084f6..2b0fb51d6 100644 --- a/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/semantic-tokens/dist/plugin.wasm.sources @@ -1 +1 @@ -de7a217d3931c62387718b231a2c895438a210cc2e2b2cbb374312a1cf86a68d +eb481d1624b5d96488925f15dfa773a74c38cde490bc0c43b9a8caf6631168ce diff --git a/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/storage/dist/plugin.wasm index b76eea9cc3e2c382f2547f79372adfd228e282ae..eaaa37edbab1911cc3859ae45ad2437d67dee2a2 100644 GIT binary patch delta 390 zcmX@Ln&sSTmJJ^{80T*O#KF(X!NkPP%*e>ZxS5kLlbL5~4|6*c69ab|BV*m<31SM9 z=LtG9UZ1={LVWU1!6xbc1CJ*heSduVONLejW=&=er?zb^OJ=kj`hA&U^Hib7%#8DZ zO64X`7c0T1bh4^=5##j9GsGvMsA5DlaB_^K*W^A4MWD(J5~wQCtOlygo@^nlFj-uF zGUNQotL5E*WP!XiBlqTGl7Wmsj)b%V%M3X1`@)8X1_mC+ z$pUg>n~%u(GfsXjITgEl^3uj!2$^5Jly99Z)iO(rpYV&GVK(j zN=kK%o`_2JQ_wXGAid07#(9&u3gRO6xx#wrt3_TpO1=ZHyD+7 zpk(w%yh3NpFil>WW7-^}@(f_~55lMX1vs5<#J-*RoZEpDO(Ceu4UP45iBTcxY>^-i z$_HiyafqIrg2E`9=G|unxgQ4N#XFx-iwXF}d_jdaMAp^T@02fH;vwM}$Mqalj zL$>z-d8u^ytc<)gYPUsl;<)D!IdRN0@>0b^L*0W=bdz68;sHj8f9WC*V?-<~=AjMC z%j3aCoaKuEm&mdGy&T!ByH=aJy{6!5ugQhqJA1)N>RYSnznp^1wGDFU?2g0E z_RVkxC)$eviN3?mld&8s@3L>txeuu_|+YQS3V-DdtxyZx4k2lQ@!;4I^qz k)vNoAna0=lS9kuF2j@q6^5K+kr+E(;fgdT`1Fo$90Oj4UjQ{`u delta 1880 zcmdUvYfMvT7{~jZ)6$j}JzUCd5)KzHT#7~*7lpz>Zeu10Y&b3-bm+#q!Ehs)iBakT zi-@qoBNxFqnVG?GsqnhtV8jA0&aq3_T&6D3EKxU2T*l@$L&)5FPI(pl!1tY`J@5Jb z|Ie*`+POZrxjwhEzJk9FIL^QWuLb$y=$%t8j1ji_aP$E@TrUq$aXOt2NV8C>0SlQo zl>zi)v0px%B7J__dE*1S)26aY-l9P|jvJow{eJ-R@~TV-cyQf*YyM)}q% zTkl`(`TFX2H%f^!Xv=c)s$erf56KmGEa#dEd1;BvNAS8QHL%*8O5P6Rp0+G%1D!!B zWI8#*5uD#Ikc8QQ;i{-wQ&63nh|=im|^+Gz8eeqY{@5O2vX#ANg{gdLPSkY+GA)?~iMGy~O4OuNOX zhEg9!@8Zr_Q}OI#&5LP&GpeT%o{TlU) z&FJ?yK_jj)O|Hx_?FOTA1TcDs@X!7Qcqr*8bYjq^Y@Y%7s}VJl&MFKlN44ODnUn^4F16(7KUOR} z)%z{KQP!QBr5{lkN7=p9pMyVDo>Wq2zq~CXCvw6WmqAing;8=Z?IWNm?dcm`D{KU; zPWQ!|=}k0U<(3&3#MBIVjw>1G=(!=Yj-FR!T|)na92&PXAud8$eNiPDt)U=HD9J$> zqU)%lFx)D*ej3|=!;>ch@W+G{8fQvOKzky(YOXY3OXE5$Nb=_#HiV==H-q7G04+K# zF+`jFI|mo=;d3Q$ffVMRqTP~zo-gOYiKThPdZ$v4m*TLxA`;K+@+Nb6eW0IQz=;UC zfw(_!HQvwng2~~67eGI?plx`p9WV5PDdH%!(m!Dm_~LdoAbG1e4$@qs@lx5s6e2I3 zueFA9!k981CyXk0UaELvsCj%89OO<(G{6w?E}Q4!91(UD@PJre9u3{ZUOo@-32EBh z%h8eID^~L`M#^6QLj#|Yygg~M(OwfujihGW4eYpQUnSVd&3&%`oX4#Fzfcr&U>gup zd*C4t<7Draxw=#@BqFexd_5W%8Q^Q^*@=Ar^NsO diff --git a/crates/ide-plugin/tests/fixtures/symbols/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/symbols/dist/plugin.wasm.sources index 88a446fad..4173f7d66 100644 --- a/crates/ide-plugin/tests/fixtures/symbols/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/symbols/dist/plugin.wasm.sources @@ -1 +1 @@ -ffe6e931db4d0232005de934fce7090ae9098e9cdfd1f9e8b7f6243abe3d3ae9 +be318451a7ea7653bfd40a5624aa0951b4fb814c8c39a494ed3066c7ac8ef35e diff --git a/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm b/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm index 84391bcc61d367e1e0ed1d10f08e0f51179231a6..a25719642722a55c24db9e0f18bb69a923323257 100644 GIT binary patch delta 1056 zcmaJbb|VSbhzj z9OE@QQ0W<+(SjfVFu=Oq5ha zo@I)FkGRn^0XlKNsa@G3_X_Ut!;~qt!T#XJSaM$C`O- zNTEE%`mhvbD+9qZ_>q}f>ei&LXXhy>@5)9iAyJw^;TmBZU9L624265wg zj(I)9O?gIxufnJhU6Le`x9aWQP#2;=G0G30M=yg*c+L`th0`W6(S>U)i)n*%mLO#w zkR0Y_|Lfr{C8aJ#8u49ZQgGc+rRImtlEQ9eMkZEyQp~Efi`V$(ITvINv{AFc#p9w9 zfi!kR`}13taR8UG$Y~?{-nj^O#%4e#e;1qV3pG3;v4KG?*RJduPmkTngY>Fz>phz7 z=C=71ySLredv_45Q)vgPFbjLPuOo8ej^IB~I6?f-jsy+M&csK1QpoX`y~zMq@$A00 zaxyP%Ib7jwX#)aW=T8ni0I23=8K5Dl;;2tW-hHxL@;9hI$V=(wJM%*gq?^GmdJ+^; zdoLF6%=c4y02K2LzW+cJ(j+pAmuBe!K66)gqYCz6IGTNoAohC&3uXGrD!P7=a2NV( zBU9%x4P6I#Q$YcPE?nxcX}dgB!5WFMH3VB7J?yK8jqS%ZFo=5RYK$u~LpR!sY-HWZ zBuh~r`|d3nK2-7t5woGkqka!*mnKS?@(;m&kC2I}Xo4(Wj1>T%Frs7)*}{?~Oi=LF zk|=ov?TJyc6Hn?H^zxw6c|dM$8H((ugx%Gv;2SQkSq*)7rltkle0%MSCee2A&F=CE Ub-4+z(;9U*dSmJn?9h<(3-M8;8UO$Q delta 1054 zcmaJx`4@$SPK!OS^F^uqsJr;@VLD7%6yQ>sf zt2Hf_MWJO`yOw%_$|RpZG9oH_8HDwtA}Y;H)2z00?^@vxyIf}G%zS*`%$(zJXbw3v z4K81>QMWIsbu&1QBLD;lA$XHd4bW&sphcp znm>Lp(7>KI_saWQT51zY1px49q!Ol?U#TqoDXScF`~dC^e@VKz%IX;KN6Y-ikjb)!f3l?|Yi0t5%nPUa z5gmkahDIJ#tcgC3JS;aX!ZLVTAG(|?mBV2w>cb#i`ay)vxI+}7PDsVo8!2!CEl5wnklze1(tTF|)U zjE-QtI0u)d=qJvA?TZ5Fo|Ghj&*(}G^wX;Z6|Z0gm04%uT{u_V42@_N)0k?DxPn=$ z7zDnwGnEHu!pCWO%*Lj-!T{}0FVsUF%~{(_;1ZpkGvLS2p2Bg)J-)e5Es1i;;S_1pwh%2Dmhe$=5py(iXCZ(aFYJ0JC(C!Q zhRd{X_b3Nf>GOSe04~z%{h;+Z=>uAPX!J*S$rt!U&z9a&(dM4Ft;qx@0)k^QA8J} z7Jwg>uowfUCvHzBT6P?xx68^13}Ut;Pdz9@F>Grz_BaN~xPrvKaxMJ8S;yAnk_r=i z!J>*hW<7;*I9xGIetGG{2|5o0+F?k!g(0@bER4rE-m1KK@}~tG?!a)cQ^d0XUvZ&x z1G5h2O4{pW_x_2_uAC;jfD<|bAL;z6#lT#_DddS{#Szy!_=&6B>tO`Xx$nYvy1o8s c3*VD4^!n{!c7i@R>vH|Orf1i4EYO_)8>4Kb+W-In diff --git a/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm.sources b/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm.sources index 33c5cbdbd..1ee2e8c2d 100644 --- a/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm.sources +++ b/crates/ide-plugin/tests/fixtures/tables/dist/plugin.wasm.sources @@ -1 +1 @@ -8d42a25cd250041ceb6aaafed66ac0bd38ff1717cc450d6175517cd3d01738c9 +9b4b83d13abbfaf88b04dff3ecc1beca7f12805fa651b53f1087b6e4ff2f0e38 diff --git a/e2e/pluginDetails.fixture.tsx b/e2e/pluginDetails.fixture.tsx new file mode 100644 index 000000000..6841320f3 --- /dev/null +++ b/e2e/pluginDetails.fixture.tsx @@ -0,0 +1,82 @@ +import { useState } from "react"; +import { createRoot } from "react-dom/client"; +import type { ProjectInfo, RemoteSession, View } from "../src/bindings"; +import { createMemoryPluginsBackend, setPluginsBackend } from "../src/features/plugins/backend"; +import { PluginView } from "../src/features/plugins/views/PluginView"; +import { bumpView } from "../src/features/plugins/views/viewStore"; +import { useProject } from "../src/platform/project"; +import { useRemote } from "../src/platform/remote"; +import "../src/styles/tokens.css"; + +const remote = (config: string): RemoteSession => ({ + target: { kind: "ssh", config }, + root: "/same", + host: config, + os: "linux", + commands: [], +}); +useProject.setState({ project: { root: "/same" } as ProjectInfo }); +useRemote.setState({ session: remote("one") }); + +let removed = false; +let revision = 0; +let selected = ""; +setPluginsBackend({ + ...createMemoryPluginsBackend([]), + renderView: async (_p, view): Promise => ({ + toolbar: [ + { id: "remove", label: "Remove alpha", icon: null, enabled: true }, + { id: "refresh", label: "Refresh details", icon: null, enabled: true }, + ], + status: null, + body: { + kind: view === "tree" ? "tree" : "list", + value: (removed ? ["beta"] : ["alpha", "beta"]).map((key) => ({ + key, + label: key, + icon: null, + detail: null, + parent: null, + expanded: false, + expandable: false, + })), + }, + }), + viewEvent: async (_p, view, event) => { + if (event.kind === "select") selected = event.key; + if (event.kind === "button") { + if (event.id === "remove") removed = true; + revision++; + bumpView("fixture", view); + } + }, + serviceDetail: async (_p, view, key) => { + if (selected !== key) throw new Error("select was not handled"); + return [ + { id: "info", label: "Info", body: { kind: "text", value: `${view}: ${key}\nRevision ${revision}` } }, + { id: "summary", label: "Summary", body: { kind: "message", value: `Selected ${key}` } }, + ]; + }, +}); +function Fixture() { + const kind = new URLSearchParams(location.search).get("kind") === "tree" ? "tree" : "list"; + const [shown, setShown] = useState(true); + const [host, setHost] = useState("one"); + return ( + <> + + + {host} +
{shown && }
+ + ); +} +createRoot(document.getElementById("root")!).render(); diff --git a/e2e/pluginDetails.html b/e2e/pluginDetails.html new file mode 100644 index 000000000..c7a3a6c0c --- /dev/null +++ b/e2e/pluginDetails.html @@ -0,0 +1,11 @@ + + + + + Plugin details regression + + +
+ + + diff --git a/e2e/pluginDetails.spec.ts b/e2e/pluginDetails.spec.ts new file mode 100644 index 000000000..b40d3c44f --- /dev/null +++ b/e2e/pluginDetails.spec.ts @@ -0,0 +1,43 @@ +import { expect, test } from "@playwright/test"; + +test.use({ video: "on" }); + +for (const kind of ["tree", "list"]) { + test(`${kind} detail follows selection, refresh and removal and remembers a dragged divider`, async ({ page }) => { + await page.goto(`/e2e/pluginDetails.html?kind=${kind}`); + await page.getByText("alpha", { exact: true }).click(); + await expect(page.locator("#root").getByRole("document")).toHaveText(`${kind}: alpha\nRevision 0`); + await page.getByRole("tab", { name: "Summary" }).click(); + await expect(page.getByText("Selected alpha", { exact: true })).toBeVisible(); + await page.getByText("beta", { exact: true }).click(); + await expect(page.locator("#root").getByRole("document")).toContainText(`${kind}: beta`); + const handle = page.getByRole("separator"); + const before = await handle.boundingBox(); + expect(before).not.toBeNull(); + await page.mouse.move(before!.x + before!.width / 2, before!.y + 50); + await page.mouse.down(); + await page.mouse.move(before!.x + 150, before!.y + 50, { steps: 10 }); + await page.mouse.up(); + await expect.poll(async () => (await handle.boundingBox())!.x).toBeGreaterThan(before!.x + 100); + const dragged = (await handle.boundingBox())!.x; + await page.getByRole("button", { name: "Toggle view" }).click(); + await page.getByRole("button", { name: "Toggle view" }).click(); + await expect(handle).toBeVisible(); + await expect.poll(async () => Math.abs((await handle.boundingBox())!.x - dragged)).toBeLessThan(2); + await page.getByText("alpha", { exact: true }).click(); + await page.getByRole("button", { name: "Refresh details" }).click(); + await expect(page.locator("#root").getByRole("document")).toContainText("Revision 1"); + await page.getByRole("button", { name: "Switch remote host" }).click(); + await expect(page.getByLabel("Remote host")).toHaveText("two"); + await expect(page.getByText("Select an item to view details")).toBeVisible(); + await expect(page.locator("#root").getByRole("document")).toHaveCount(0); + await page.getByText("alpha", { exact: true }).click(); + await expect(page.locator("#root").getByRole("document")).toContainText(`${kind}: alpha`); + await page.getByRole("button", { name: "Remove alpha" }).click(); + await expect(page.getByText("Select an item to view details")).toBeVisible(); + await expect(page.locator("#root").getByRole("document")).toHaveCount(0); + await page.reload(); + await expect(handle).toBeVisible(); + await expect.poll(async () => Math.abs((await handle.boundingBox())!.x - dragged)).toBeLessThan(2); + }); +} diff --git a/plugins/README.md b/plugins/README.md index a9b2c0ca0..4695c798c 100644 --- a/plugins/README.md +++ b/plugins/README.md @@ -851,6 +851,28 @@ Scripts get the same as `openidea.theme` (`{ dark, vars }`) and `openidea.onThemeChange(fn)`, for drawing on a canvas, say. Variables are only ever added. +#### List and detail views + +With API 1.3 (`engines.openidea = "^1.3"`), a rendered `tree` or `list` view +in any location can declare `detail = true`: + +```toml +[[contributes.views]] +id = "endpoints" +title = "Endpoints" +location = "bottom" +detail = true +``` + +Implement the same `details::Details` export shown below. The host requests +the selected item's tabs after its `select` event finishes, and again after +`host::refresh_view(view)`. The list and tabs appear side by side with a +resizable divider remembered per plugin/view. Changing or removing the selected +item closes its pane and stops its log. Changing projects or remote hosts clears +selection; hiding the window stops its log. Other body kinds render as before; +`detail` cannot be combined with `web`. Services uses its existing single +list/detail split, so this declaration never adds a nested split. + #### Services views `location = "services"` (API 1.3: `engines.openidea = "^1.3"`) puts a view's diff --git a/plugins/official/ai-completion/dist/plugin.wasm b/plugins/official/ai-completion/dist/plugin.wasm index c31940bedde41fa4e61c8450ec1d03b42cf1d76b..a628301c07d09f53bd761e30b13e4365dfefce7d 100644 GIT binary patch delta 15510 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 o%-r{Dc<+tU$H3zi0wkN%-bRpsY0e5gLl>h($ delta 15814 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 SiN|3m!%hI<_#E0d2Y2 z!7k0K`-bAY&BVpQ)U(-LB0o$JT?8c4CE{gs(Y3k=EjWjh&7F3CD9MuT3fp*9qeiM zx4V3KjV863PhYs}qX$2?oqKpTjm~ARrmr%rn!Eo!VIMxES7x95cTrK0^}H6BsI<^T zk1Q$FpRS`d`7cjQ;AXC!(1okOs;p+vQTFUO8Z5}hJ^ImdYEnXY+eLKm>2l`cir)eQ zZJzhpB=!V(F)ufn!7WzgeFF@WHb1QQNv&MYzkzfAtMyu(ChY<-u|C3&mr_(j355mt zLF$I_!fT6^q6XkL9eCD@+rnj)ccP7`xJ2&Pip$U@vTYR+(s3^hLRXenNXWWuaTY$H z#;rNhIk~kF`ZN_QHmS0h%2u~zipr$YdFf`|ds4Q_J|Dl*QF}e^(o>Gz27NHt}5M z7X1Xo(m6*|v}{bkZ{qyNYt(2E>4)|+jEU~U;~Wpg=}%waXrO5wPohOE>=+0B6xPrC zG|cG`@m~fstllBmx7HwMVb?6lS>JUk0X68foUCH@eWvtyh! zIK&g@dw}0*wD%>n)5^XS_-IRCrF_5Iw@r?=w0{Mp(|%z+e1Z)$B*^JB-)xnT;ntvx z58vv5VQ*+M>MXW(W~51N^Q$)Le00ovT*k|N+Zc9>i+9{y&VIwtM!EM7y$G+!95w=b zX|aEaEZORJ%7MoRa^a;#fo1rG-VG$PJ94rCqdI?+ZkWCctdptc5wqM^jnrUR42;xp zsZ(}8Z3^0yDvlGg-*$`SnN!V3A%TjWZ9k^HN7&AX{FnulPESk% zD&^l%<*7E{d!`&u!W=HYz5+cGm5L;kdafj42Um8cVvb?DywE0Q;wH68YMLTUk-9ye z>c^4FJY6yl?C{(+qBa7Jo{bsEiIw_o7K{z(W(>HwH~m81wB_sCONQKOo&%iSZ2B9| C***LK delta 1463 zcma)4eN0tl7(c)FT)6iF(&0jY@^!?>3yXCXL_$$+A1G54!ie>?nWl~w*W}M_*aUFrULU)o*#`HeuY;oS|Y-+ErRdva7 z^s|S1yW7Sz+uZ}zv^{|KyQ6g_@TNYxhZS5{7z4gO`bseVSj zZkR#VUI(Vou_qG9G}Auu)&#TJbYte5XrRSuXD2fMtIwZIpUkkG=VY7$2I>B6f727) ze3y9{U617XM3$9(!>Fk~frw$aljWc zaj$FhFKoz0pH`)^ziqs?sz}Clo@~#9IMzEB!!%7|IjUr4lC?T_lB7z?2xV4$DEjEE zn2j+SuW;%gc-4YQTg#9}?dzA5WkWHu+o^uT5!ocEd}XBp{EX8eGn<{htt&Cw>|W=x zHJzFcrBLqCaK3u$=P)`RrZcIhZa%%T&BPpbUbd|W#+rwS#fKOhOsvMv;~Msa<4^A1 z|FRCX{IO3CGTh{C&0{id^VXIZWz_C$eF`p~+BydG^OR%V0qh?eA3Z)8!0y=i?Njpw zg;Gx^3Qoc4uL9wq&~t0y;G55_^8Qg*I{HMatFr)q@!0btG8?w>$nQIW8}$1RuVF9E z>5j!cD(Nm0@15Q2Fv_3#F&`q>+Vd9f@!LH$;o>`0Ty=@m_|;1SzjUn?5&In8?saBX zK2@*ktOHW1a*y`*eIfAt>+2Zy@H01e$YS1wo;6}W z=M7b1oVO2E$)Zfw@U%&2)ZUQsr8vTLFr(3(r9*rWlO?S<6gyC(H7J-86kC?T3@Vgb z2j5;}hL*0N7+bwqBI?~o6|6zn`@T+@nT1RZ5Yz?-{jq7XmScheE-lZ5BXGKhOelkU zWdtrTtkNz=;c=}p3WeIND5SVMqEIhKM0=ZJs;uf%A)^MWdgWucD+X~)TM{E!EpbQz zwz+?b$Cg0Uxr>ru3DG;f#e>td!bym6H_yPu3(8C5GiH?}JlB5sv+#~HlIMWiC9|t_ F{{m-)N+kdQ diff --git a/plugins/official/checkstyle/dist/plugin.wasm.sources b/plugins/official/checkstyle/dist/plugin.wasm.sources index ae1a5e838..cb4c66f56 100644 --- a/plugins/official/checkstyle/dist/plugin.wasm.sources +++ b/plugins/official/checkstyle/dist/plugin.wasm.sources @@ -1 +1 @@ -55e3306fc2ff9456d79f02b63712c7f83b1fe4e75fec051f5fb96e7fb766066f +0bebf24cc46dd2dac9c51fffcd4b9186f7e575c2d552e8d600c02fa5fe8fa9b0 diff --git a/plugins/official/csv-editor/dist/plugin.wasm b/plugins/official/csv-editor/dist/plugin.wasm index dedb8a9b27217aed41d7c53c95ef211ccb4edb03..5fdecfbedc4fa36125b00514ff3bbfc317582b4e 100644 GIT binary patch delta 951 zcmZ9KTS!zv7{|{yb9VQLt{(HYZRVbJyO?EJqM69%3iV=CMA-#0=ptk$_E3seu7yQl z5Pn|EY*mz8C6CVTT3ga>i&b0eDd?e~B8(`4lIp>*S)o$rVPL-hZ~pV2Z>D8R*EOY6 zTlL^(*Y#=Ia56JODWw1e@J-Zi%!m$;BVkkoDFXCVSRgHcpe9j0W&5HhD5PPop%F&$ zm7zrJpg@~e8zB~Di-@t7M7+4L%sBb;%h<=4&KJ`{jY3yYLvGE5r@tD$JNw-@Zb?F` zu@~C$lkw4fQ2Gxt-y#Emlf90wBXEb6nrZ;t_(L&6FB;78(1+<}6L{Dzb32GW3Yxzu zy62nDI-QMM&Jb?8W!Yy6KJ>0qaBp(${0*~G;P2!rGE5M1qOope(;O03(AlJIRXGfE z%f2}fzx`Y&kBy}4)#0{VN=T+aaugwn7*NiN2~h-Fd{Lqx52D_>4F+((wUD^%7_l^y z$SO`-Hxo6uGD0Xbr#}%v#fc4y*bG3?wk`^-S({9E?RLAseXfi>unR>BQHb02cf)%8^Km}U_jjySZ``k)6t)+TW= z^74)#bGSZ5gaKC9+#82Bb*H((WyJ4DQ=TZV)FRE+oM@VfXY0gI;Xz49*4`p0~_Xqy~`I&dk delta 921 zcmY+BTS$~a6vy|>e7aw_Tb~-XZJOV1Y3jNrl}4zUTlA2iA*L9HAz@@@S5YK%i_90Z z^5iY=#uBNOI_q_{MJre}g%BSE2_(oDyF5f#YBeiH?qQhW{O33Sa}Hx!QP!>~JL}c( zj5VnDyKnZOlo9{}#2NU(J2ilSia2xUQWK)00*IidTNGZR7w`}XrD}G1>jH%+G-;~f z70zmMg=PvAf9tiF9^#L8wijw%e0#b2>EXiO5}5{5jj42I3GJ2b#socFCD(9dr8mjGDtm#l*}^ws%7J08;cLk~;SwE&Fbvfl1$t?W8Q zxLs1c@c>)fNvwR$dDPY2Ix@^@F9{F&qp37R;Qu`50)D%0SsgDku)-F#<{*@ zY-e1vH*_(3@*sh3R+#$L6Ra%zf*oK8LoWVNuT_(2-0p0NyUg{4;kleMq5o7>wqB5C zZt;d>L7HAW*HNcLTsdA@%y3*wUBy(H(&l}APa23TWF`!+YKP%$M!(?1OsSB>$?qHt_%iaB;JS0HIsF4Ll@Zyj*+IjAIHu&KkG2jtRPn&uH(h9 zKs+8&_b)06p|ygA0FN!DUU(t&?;;U<) z*=**Nk|0vlX&QXikFsbKTTeT#WGjdIs0ej1M^Yp%f^f1aUByY9EEq*>!aYpeqitBF3A6IL0(N$}K9=xedBkW+(`hyb3HG$BM^O|0U9g!x< zkqhD#n-mE|i`@#c))>MXm^mzqD)1Vz_aYMLh#1TWW=?L$(Wn3zrqfZkfc0pOiD&pE zrh}C&-};;?;@klS&^vxV4A7eR3LfTgGNBsgXqxT_zys_`oMxf6q#U?Uza`ZP@Q@zd z{sLeSLy|S{6Za;cfh8PI&Vqhar_?|nZAl5|nHfyI>g4B8P2@pXADPILoKftj)ftTd z3)q&Kk2^E7?H*+>Fk{bUfF)|p$^}+DKD)ua-#!yBzXBs0dl?^PhbbJp!PUHI>Ybwo z)=ih|%M51cwJ@~iU1OnB`Gth7cA}u1h4hAcCi9*_?PkxFh;6MsXfz25r+~pO-`$p10#){tL59ybqq|T!g9Ff PbtOpPJTPAgpY^{15P)YO delta 980 zcmbVKTS!!45I*ytZ57vT52mIox<}W`?y7i!RP3@ICCj|8wJI2*lnY+4#2yU9Rg502 zh{iM{2`WK^K>aOUHwi1s5KPp z{~Ld4u9LR}h4bFnE4HauCYBc_-#7QRHC+&SJ@1}s8=tgV?H3o7G$+`Dhi)tmz4i|l z%ERhp9RzsHANRxi;W79$?C1_Y>`+Bxgb`1NM?oJG4#NKM`W@uIEEpp^0Y)%O=kOS{ zTCJQylnFLW);Gc^j_8AMCNdDL_%(8n;hm@^f4V^uLAcTEik;3VlVb6eUWcjC$Gsmo z8AOBxB52vGm6NR47aaf(>GS9w0E*Qy@eFUr++~_+u`e`Qj--g3j&M@b5hW*blB`m& zZ8WMBA}5TZkD)H-5UXzvd4LqCZ3SnsIohE%S+Qx$!_oipX7$iU1!7JrYNe;(*T>6obSg1 z7MQLwbeOtXsimNhurtq}IK@gva|5$!GiyAZy&{nW<_I0;OtzEQ!k|5_rK*(RDN}5{ zmK6>GrM^X48S|H1GRW{tiH^DSJ!v9@=dhx*2tMQE(hyjti=~M`1IrG}@scGBzSBX= z8y?o^m8!jfSv4P25g=ewBGnb?vPnUzf}B{KXdNecXA`ME(|bd|ncbQ4I~ zlV71;^hJxv*<)FF8y1@8+)N#nnpc6^g;$kj=heWEiw=ha|Nrwl|K~ZUds@{#t@54< zg9XYB`yQfYd}#zh0APSQ`dfP77OZa-uW3OY2DG4eDPaK5N4k_h83@>HjlgQN36)Xh zk)FA+iP`zCsr2ijU={Xc`n|yi-yT2mh$ux3!Z2nV?rvk$8w~w2@NSC|uI_ciAiASR zx3Os(EYFLh24e@4`AAbMd`7QHE|2jht`69eM9J1f`At-saBNNA+h56KU!61! z@Cm;ji07xqmW*?0i{Qn4y8&;;7*TC^(h-{@1p2WtB^q8)S4x&ZF8eNkUTjD&X1x;T z2C^vnuw4M6a~Ve&^ii9mCmg(#eb%Isd)8c7VlaipCG{{xZ%dp2FEObsADU4rYvF~6 z@;rD!7t2xpMOvw>0C-KM&UXOM(OR|2O-!gBmur8jXCR_Sk|c!|G@`=Mn93BQ;Lz3R zdT_b+i;Vc|=1bsm+iVr+v2<05PXfEcMbHgjs7o7kH6ku&>Xl9mIROb`?bJlN@``;!$6 z>w^j4MDh3fEHS~;p-P3Q(43Ji>J2U{A%G8Oiok~}{2ao<*&!Gu<6M(R=dtzeG+yzh S7q++FInhxd_7B{E`Le(J8Asdz delta 780 zcmZ9IT}V_>5XX1Ub#ud2FSLmtm3P-oSF`*GR4U9X5fLkB(LyHKnk;H+5j{jDu0k(? zqz##gRxc(#v|L5z$#$0v8s!@$h^=0E>AZNAW3zR-Sq z1pK0ch#z`mm?TL63>bfSz|@R0rbxXJ3=l!zOtm2}ipOGV;SYLZI$|5O{x3au+x-cb z6)9PY&TkslzIHcvx2))}KK2E8aerKU5M)>b(eF6E=V=4}-Eho1xc;li_6xttd(J*WKHwsI!wY=;lv1J0${ zc+{t7((?>eA5U(#Tc_w$zh}g)t5TT4a~bqgi`usVhDkkQ4i!GiOTIJk;Nj95@X%E#cWUP9jlu0`5_3o6t4dOIrV@9)H0eK96dMz+crm=M)@P;R`>ut4J z%)nb3h86Qk` zlu#s>+^jF@!o+lqX|iIf*yL{MCaK1zdk1f9`1Q29Re@QPnZxPpy^WuD&3MqXwSKdj zOdC7XT#!|tbFvsp{eml?>bFmz*_tZ$+qq{G1EpunKP#Nb%(#>=36Z3IyhjO&0J_)Qch z`q)aoy$zRz?bp8#fC_TQD+i*z6Ni z!os*^^TC7@jEw6icP04%eRw_T<1qooM)Qu=m#2T1=I5+C+`zhZ`wdOTE6US1_%bRm MvTZ->%h;|50CY#~fdBvi delta 601 zcmccdgZ0V})(v+#882Hi; zc9c*gm)xu`>B7Wxm1(kJsmSC`=@!Ykiw^JYx%_l-RjUHCCNqcAza=~GUR&M!z;&~_ zOdC7X9Ei%p%C)#vPL5J3Vw^hptjZ*0HH;{xO`fP`KY53$4%14AfxlGo7`S<&+9XEC z&68C$JQ>$)&eQk{;^b&00?Bh)R*V}bb82fau9=*tAv4)e+Z)KArG1TY^X5XGJ&cT- zHtXs6G6Q)vhHi|LGfiZf9vq+CVX_fKS)0}Ywe2!hn0&}cfpOvF#x&8%A585G)-^OV zFeor7Fq$z5C^v#Qjt`C>Xkf@vU~*&u5dv8POCV~1e1Y|wgkbEQ}jAA5A#H$hc~9Uy={dYqyg= s9uttgxZ(JWY3{%3g4SinnjSd1{f;K%6=g=Y>1%x%mA7B!nYj`#(8(ct^hxe&@V+)SF(!!jzp)*QDQ4E(p+uNtQ$$NjBn&v^DsZMYHgLuv$9&*^k$f(rZqnT zOw+ElSpYrMlo7`uNar$-%OQl0btj%KhwAlX(D*;Y32n%f*D(+pTz1gl21`0R%x^Bd z0~V*iZ`p`5W+QyV?>V}Vw>VYgw-f;MV!HJROkt<>6Fz^*gUZ#c`_! zTje+&?xZL?Ux^v!8+~>_xjxF!RVV83pC$g_c z4}@iO3Y)T6^5DQ*=czv@7ovwEsN5!TlyqC3XR#v@M36jl*48aMI`TSxmit$1FoLl8 z9X7w?dAk9A#yt)bZ_a8*p1@mva_eT`#<)EPsBwo<5c}q}UPhOHC3<(i3Vrl=_g#QX zcz3T8E>U(t9`HtKayh|E4_rlZ@X@~g+vPmk3&qV025D!>tN?z>Kj09c2hWrlIb*DB z79c>Q2mJ~drPf3D6mW$a4qL;FvC37P@vyQh3I?#VsssiorFuW`wy3GO#i4_>xiC!L z+P?+3O5NxKxQs{Yb|p@Q8;n`!9-YF#bhdJPOgM46VyOp(`cht^59<#=FHP5=6LkAbi=3BlZ$}1pwJ+zh zV0(3BUCO`y4toUAVA}UzMo>FOQyNUrIx=hUHHTm;KJ;hS~Lz@n2BoZ_v(v-`B7X8wc^KNx9)i?kw8%6~#Kst67*!Gvq6xaC(r z*{^kq7`&NEkEcRF4{xUO8j=2%FP6vq=Yvi1B^SfmOEXX!e2(%SDMHe=cHHyNTIWpS SiQ}6(Yrg&C{CfewL;nKC&>Q6d delta 1278 zcma)4drVVj6z6>R7PuYI8^i!p=7k{C4lC32k2wmx%+v`=I);)u8E7_LNMIq+J)8li zA)Cz2$q^b8T-ZeMu`SROXT&E3wXBv$MHp&G23>F?i;H{Vf^J_+vdsQL{Jxue&iS3+ zJ&h?Z3We~(_w4g0@5Ys7Vh)Cvy>X6GD}#1r5Okjg*kJNfeoUr20fxGa}Q@Y-ACBFg;uq{&{L$tX;(dWg(V%Gc zEH#-aT6JN$3bLPuPJJQrRpocAz!UBBxCYJyyxG1Zh*k1;XNNV2wg(X_PCJ)^pVG*j zz=SZ|>^T5k_?sss!WBsHRI@_`n2*(^nRw*YG0gF9;GHyiQzEVe-ADd&lh~I8^0fe} zFg=S()+ivm@wt9JC@ktf4wva+ey^ItJB^=H-(0Pgx1A|oD8 diff --git a/plugins/official/license-header/dist/plugin.wasm.sources b/plugins/official/license-header/dist/plugin.wasm.sources index 8fbbf7217..6b9d7a3ea 100644 --- a/plugins/official/license-header/dist/plugin.wasm.sources +++ b/plugins/official/license-header/dist/plugin.wasm.sources @@ -1 +1 @@ -be6dd0b46a0f407f354ae2b67c6304948c71749bc3587dcf81b39dd245afdb48 +a9bf8c6074ffb5d5335f07d6e5f1af6108faec0ca6e282a85684b991995baefc diff --git a/plugins/official/mybatis/dist/plugin.wasm b/plugins/official/mybatis/dist/plugin.wasm index 1a4045534e489251d3238c9871d3abc73942684a..56953a3764da0c27b67fb288080ebf852895740c 100644 GIT binary patch delta 1398 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 delta 73623 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 z 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 diff --git a/plugins/official/solidity/dist/plugin.wasm.sources b/plugins/official/solidity/dist/plugin.wasm.sources index ac053bcd8..956a79eb4 100644 --- a/plugins/official/solidity/dist/plugin.wasm.sources +++ b/plugins/official/solidity/dist/plugin.wasm.sources @@ -1 +1 @@ -0a02c2ec0444e5eccb68b2bfabeaaf7752d1bc2b22bc0f26883a2a35eeac7df7 +674e164012c93a106a0c3977b1066d5a49524f8f8426fb09404e3b7a7340a629 diff --git a/plugins/official/string-tools/dist/plugin.wasm b/plugins/official/string-tools/dist/plugin.wasm index 5e022a9e2820b34a5c99263c190c852deb3699a7..68c50416509473e6dfbb1a1b6a3dae4e2005da75 100644 GIT binary patch delta 679 zcmaF!o%79i&J7-dT+Beg&BDmY%s4qnuv?IknU9r`fsv6>lu4A4k%5P4^E<&+%v=t; z822*nW8B8*xOtK2VJ5~6o6{t=Ff%Tg+$f_+HkmK`320D~Tr`13*IdWL_;jZbU$%M6UL|0o5dOR8J}+7 zEY7%rWqX$_r1_0?D B`|kh% delta 724 zcmcJIPe_w-7{}l5@Atkf-CTQN%VECxZp)SzI|Ncu!8*(l6p?Sk(IAoVFe(e8Zfzn# z|BUKay$~JD=>}>k{iGLS)7FZXUJBGhP!X;=G&}^dPTA|aSceWlm*;u-e7}62Qn{*B zt{M-?)mD)L6qHhSNWLOd*d+)6T*L(k#KsrpVOkx0f-ENS7_EH3l_!|sUG52rLDp06 z`RCcKd^1Iz8+(6=oUFrJQ<43zt6Qn#nonL+m%4U+VJZJ^OuC@bCc1WSdNh4+ApL4S z6X)@!hc*;>b4!+BftR*#p?_;P?~<@O$L}__fA^2o@gL93cpo3z^VP{-YYO_=qV~v~ z_YcRBW1g_e?zX8c5RNwF6N!YN3W5Hsxr7i?iAo$J6+{AJ%<-IO!b7m+R)~$T(^@Ty zx4TTm?e?Up+Yx!Gzu$xnY_9E&36E<*rBYpIHH~7-D>%wM6}@9=Wn1}jWCkd(nIjPt zcw@A$6|;;dPhggN2D^Y~?BdWD6P-#O#8aM2oe}YZw~Q2kDZV^?M%&kA67yJ~!%7)Q8>JilXt>jd9U9Pzyhd p%L=|19h)u3q77${O8)svzMYK^GR93poI$91GDLjFbclGj{RA+R3UL4c diff --git a/plugins/official/string-tools/dist/plugin.wasm.sources b/plugins/official/string-tools/dist/plugin.wasm.sources index 1599b4632..45439d0f3 100644 --- a/plugins/official/string-tools/dist/plugin.wasm.sources +++ b/plugins/official/string-tools/dist/plugin.wasm.sources @@ -1 +1 @@ -10c214d40a6b43bb8b850bfe6d97c1a360ed748b5e95645354b3317806d7a538 +f253276316839b418223b8292683e313d311ce41c9701c04c9c3fcc85e0638e5 diff --git a/sdk/rust/openidea-plugin/src/details.rs b/sdk/rust/openidea-plugin/src/details.rs index 5a9349309..bf6806ec9 100644 --- a/sdk/rust/openidea-plugin/src/details.rs +++ b/sdk/rust/openidea-plugin/src/details.rs @@ -1,7 +1,8 @@ -//! The pane beside the Services tree for the nodes of the plugin's -//! `location = "services"` views (world `plugin-details`). The nodes, the +//! The selected item's pane for `location = "services"` views and tree/list +//! views declaring `detail = true` (API 1.3, world `plugin-details`). The items, //! toolbar and their events come from [`crate::views::Views`] as in any view; -//! register both: `register_plugin!(MyPlugin, views, details)`. +//! register both: `register_plugin!(MyPlugin, views, details)`. The host remembers +//! the resizable divider and requests details after the select event finishes. use crate::{Error, Invocation}; @@ -64,7 +65,7 @@ impl Tab { } } -/// The detail pane of the nodes of the plugin's services views. +/// The selected item's detail pane in Services or a `detail = true` tree/list view. pub trait Details { /// The tabs of node `key` of view `view` (at most 8), asked when the node is /// selected and again after [`crate::host::refresh_view`] of the view. diff --git a/src/features/plugins/__tests__/detailViews.test.tsx b/src/features/plugins/__tests__/detailViews.test.tsx new file mode 100644 index 000000000..af0de32d3 --- /dev/null +++ b/src/features/plugins/__tests__/detailViews.test.tsx @@ -0,0 +1,290 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; +import { act, fireEvent, render, screen, waitFor } from "@testing-library/react"; +import type { ProjectInfo, ServiceTab, View } from "@/bindings"; +import { createMemoryPluginsBackend, setPluginsBackend } from "../backend"; +import { ToolWindowShownProvider, useContributions } from "@/workbench/contributions"; +import { useProject } from "@/platform/project"; +import { useRemote } from "@/platform/remote"; +import { PluginView } from "../views/PluginView"; +import { ServicePane } from "../views/ServicePane"; +import { defineBuiltinUiPoints } from "../points"; +import { clearUiContributions, syncUiContributions } from "../projection"; +import { bumpView } from "../views/viewStore"; + +const originalProject = useProject.getState().project; +const originalRemote = useRemote.getState().session; +afterEach(() => { + setPluginsBackend(null); + act(() => { + useProject.setState({ project: originalProject }); + useRemote.setState({ session: originalRemote }); + }); +}); +const select = (key: string) => { + const row = screen.getByText(key); + fireEvent.mouseDown(row, { button: 0 }); + fireEvent.click(row); +}; +const tabs = (key: string): ServiceTab[] => [ + { id: "info", label: "Info", body: { kind: "text", value: `Details ${key}` } }, +]; +const item = (key: string) => ({ + key, + label: key, + icon: null, + detail: null, + parent: null, + expandable: false, + expanded: false, +}); + +function setup(kind: "tree" | "list") { + let keys = ["a", "b"]; + const b = { + ...createMemoryPluginsBackend([]), + renderView: vi.fn(async (): Promise => ({ + toolbar: [], + status: null, + body: { kind, value: keys.map(item) }, + })), + viewEvent: vi.fn(async () => {}), + serviceDetail: vi.fn(async (_p: string, _v: string, key: string) => tabs(key)), + }; + setPluginsBackend(b); + return { + b, + remove: () => { + keys = ["b"]; + bumpView("p", kind); + }, + }; +} + +describe("detail views", () => { + it.each(["tree", "list"] as const)("follows %s selection and clears removed items", async (kind) => { + const { b, remove } = setup(kind); + render(); + await screen.findByText("a"); + select("a"); + expect(await screen.findByRole("document")).toHaveTextContent("Details a"); + select("b"); + await waitFor(() => expect(screen.getByRole("document")).toHaveTextContent("Details b")); + expect(b.serviceDetail).toHaveBeenLastCalledWith("p", kind, "b"); + select("a"); + await waitFor(() => expect(screen.getByRole("document")).toHaveTextContent("Details a")); + act(remove); + expect(await screen.findByText("Select an item to view details")).toBeTruthy(); + expect(screen.queryByRole("document")).toBeNull(); + }); + + it("waits for the select handler before requesting details", async () => { + const { b } = setup("list"); + let finish = () => {}; + b.viewEvent.mockImplementation( + () => + new Promise((resolve) => { + finish = resolve; + }), + ); + render(); + await screen.findByText("a"); + select("a"); + await waitFor(() => expect(b.viewEvent).toHaveBeenCalled()); + expect(b.serviceDetail).not.toHaveBeenCalled(); + await act(async () => finish()); + expect(await screen.findByRole("document")).toHaveTextContent("Details a"); + }); + + it.each(["tree", "list"] as const)("updates %s details on keyboard selection", async (kind) => { + const { b } = setup(kind); + render(); + await screen.findByText("a"); + select("a"); + await screen.findByRole("document"); + const row = screen.getByText("a").closest('[role="treeitem"], [role="option"]')!; + fireEvent.keyDown(row, { key: "ArrowDown" }); + await waitFor(() => expect(screen.getByRole("document")).toHaveTextContent("Details b")); + expect(b.serviceDetail).toHaveBeenLastCalledWith("p", kind, "b"); + }); + + it("keeps ordinary bodies unchanged and does not request details without opt-in", async () => { + const { b } = setup("list"); + render(); + await screen.findByText("a"); + select("a"); + await waitFor(() => expect(b.viewEvent).toHaveBeenCalled()); + expect(screen.queryByRole("separator")).toBeNull(); + expect(b.serviceDetail).not.toHaveBeenCalled(); + }); + + it("ignores late detail responses after the selected item changes", async () => { + let resolveA = (_tabs: ServiceTab[]) => {}; + const b = { + ...createMemoryPluginsBackend([]), + serviceDetail: vi.fn(async (_p: string, _v: string, key: string) => + key === "a" + ? new Promise((resolve) => { + resolveA = resolve; + }) + : tabs(key), + ), + }; + setPluginsBackend(b); + const ui = render(); + await waitFor(() => expect(b.serviceDetail).toHaveBeenCalled()); + ui.rerender(); + expect(await screen.findByRole("document")).toHaveTextContent("Details b"); + await act(async () => resolveA(tabs("a"))); + expect(screen.getByRole("document")).toHaveTextContent("Details b"); + }); + + it("stops the previous item's log immediately on selection change", async () => { + const stop = vi.fn(); + setPluginsBackend({ + ...createMemoryPluginsBackend([]), + serviceDetail: async (_p, _v, key) => + key === "a" + ? [{ id: "log", label: "Log", body: { kind: "log", value: { program: "sh", args: [], toggles: [] } } }] + : new Promise(() => {}), + serviceLog: () => stop, + }); + const ui = render(); + await screen.findByRole("tab", { name: "Log" }); + ui.rerender(); + expect(stop).toHaveBeenCalledOnce(); + expect(screen.queryByRole("tab")).toBeNull(); + }); +}); + +it("retries details after an error and refresh", async () => { + let fail = true; + setPluginsBackend({ + ...createMemoryPluginsBackend([]), + serviceDetail: async () => { + if (fail) throw new Error("offline"); + return tabs("a"); + }, + }); + render(); + await screen.findByText("offline"); + fail = false; + act(() => bumpView("p", "retry")); + expect(await screen.findByRole("document")).toHaveTextContent("Details a"); +}); + +it("clears selection and cancels a log when the project changes", async () => { + const { b } = setup("list"); + const stop = vi.fn(); + setPluginsBackend({ + ...b, + serviceDetail: async () => [ + { id: "log", label: "Log", body: { kind: "log", value: { program: "sh", args: [], toggles: [] } } }, + ], + serviceLog: () => stop, + }); + render(); + await screen.findByText("a"); + select("a"); + await screen.findByRole("tab", { name: "Log" }); + act(() => useProject.setState({ project: { root: "/other" } as ProjectInfo })); + expect(stop).toHaveBeenCalledOnce(); + expect(await screen.findByText("Select an item to view details")).toBeTruthy(); + expect(screen.queryByRole("tab")).toBeNull(); +}); + +it("stops logs while a kept-alive tool window is hidden and reloads on show", async () => { + const stop = vi.fn(); + const serviceDetail = vi.fn(async (): Promise => [ + { id: "log", label: "Log", body: { kind: "log", value: { program: "sh", args: [], toggles: [] } } }, + ]); + setPluginsBackend({ ...createMemoryPluginsBackend([]), serviceDetail, serviceLog: () => stop }); + const view = (shown: boolean) => ( + + + + ); + const ui = render(view(true)); + await screen.findByRole("tab", { name: "Log" }); + ui.rerender(view(false)); + expect(stop).toHaveBeenCalledOnce(); + expect(screen.queryByRole("tab")).toBeNull(); + ui.rerender(view(true)); + await screen.findByRole("tab", { name: "Log" }); + expect(serviceDetail).toHaveBeenCalledTimes(2); +}); + +it.each(["left", "right", "bottom"].flatMap((location) => [null, "items"].map((group) => ({ location, group }))))( + "projects detail declarations in $location with group=$group", + async ({ location, group }) => { + const undefine = defineBuiltinUiPoints(); + const { b } = setup("list"); + try { + syncUiContributions( + [ + { + pluginId: "p", + point: "views", + key: "list", + decl: { id: "list", title: "Items", location, group, detail: true }, + }, + ], + [{ id: "p", name: "P", enabled: true, status: "active" } as Parameters[1][number]], + ); + const contribution = useContributions + .getState() + .toolWindows.get(group ? `plugin.p.group:${group}` : "plugin.p.list")!; + expect(contribution.anchor).toBe(location); + const Component = contribution.component; + render(); + await screen.findByText("a"); + select("a"); + expect(await screen.findByRole("document")).toHaveTextContent("Details a"); + expect(b.serviceDetail).toHaveBeenCalledWith("p", "list", "a"); + } finally { + clearUiContributions(); + undefine(); + } + }, +); + +it("drops queued events when their project/view has been left", async () => { + const { b } = setup("list"); + let finish = () => {}; + b.viewEvent.mockImplementationOnce( + () => + new Promise((resolve) => { + finish = resolve; + }), + ); + render(); + await screen.findByText("a"); + select("a"); + await waitFor(() => expect(b.viewEvent).toHaveBeenCalledOnce()); + select("b"); + act(() => useProject.setState({ project: { root: "/next" } as ProjectInfo })); + await act(async () => finish()); + expect(b.viewEvent).toHaveBeenCalledOnce(); + expect(b.serviceDetail).not.toHaveBeenCalled(); +}); + +it("clears detail when remote hosts use the same project path", async () => { + setup("list"); + const session = (config: string) => ({ + target: { kind: "ssh" as const, config }, + root: "/same", + host: config, + os: "linux", + commands: [], + }); + act(() => { + useProject.setState({ project: { root: "/same" } as ProjectInfo }); + useRemote.setState({ session: session("one") }); + }); + render(); + await screen.findByText("a"); + select("a"); + await screen.findByRole("document"); + act(() => useRemote.setState({ session: session("two") })); + expect(await screen.findByText("Select an item to view details")).toBeTruthy(); + expect(screen.queryByRole("document")).toBeNull(); +}); diff --git a/src/features/plugins/__tests__/serviceProvider.test.tsx b/src/features/plugins/__tests__/serviceProvider.test.tsx index 2780c4b83..d8f4cb9c5 100644 --- a/src/features/plugins/__tests__/serviceProvider.test.tsx +++ b/src/features/plugins/__tests__/serviceProvider.test.tsx @@ -1,13 +1,17 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { render, renderHook, waitFor } from "@testing-library/react"; -import type { View, ViewEvent, ViewTreeItem } from "@/bindings"; +import { act, render, renderHook, waitFor } from "@testing-library/react"; +import type { ProjectInfo, View, ViewEvent, ViewTreeItem } from "@/bindings"; import { serviceProviders, type ServiceTreeItem } from "@/workbench/contributions"; import { createMemoryPluginsBackend, setPluginsBackend, type PluginsBackend } from "../backend"; import { defineBuiltinUiPoints } from "../points"; import { clearUiContributions, syncUiContributions } from "../projection"; +import { useProject } from "@/platform/project"; +import { useRemote } from "@/platform/remote"; import { pluginServiceProvider } from "../views/serviceProvider"; let undefinePoints: () => void = () => {}; +const originalProject = useProject.getState().project; +const originalRemote = useRemote.getState().session; beforeEach(() => { undefinePoints = defineBuiltinUiPoints(); @@ -17,6 +21,10 @@ afterEach(() => { clearUiContributions(); undefinePoints(); setPluginsBackend(null); + act(() => { + useProject.setState({ project: originalProject }); + useRemote.setState({ session: originalRemote }); + }); }); const item = (key: string, label: string, parent: string | null = null): ViewTreeItem => ({ @@ -73,6 +81,17 @@ describe("plugin service providers", () => { expect(nodes[0]?.label).toBe("minikube"); }); + it("maps a list to Services nodes without another split", async () => { + backend({ + toolbar: [], + status: null, + body: { kind: "list", value: [{ key: "a", label: "Alpha", icon: null, detail: "ready" }] }, + }); + const { roots: nodes } = await roots("p"); + expect(nodes).toEqual([expect.objectContaining({ key: "plugin:p/kube/a", label: "Alpha", detail: "ready" })]); + expect(nodes[0]?.children).toBeUndefined(); + }); + it("routes events with the raw key", async () => { const { events } = backend(); const { provider, roots: nodes } = await roots("p"); @@ -130,3 +149,70 @@ describe("plugin service providers", () => { expect(serviceProviders().map((p) => p.id)).not.toContain("plugin.p.kube"); }); }); + +const remote = (config: string) => ({ + target: { kind: "ssh" as const, config }, + root: "/same", + host: config, + os: "linux", + commands: [], +}); + +it("reloads Services roots when remote hosts share a project path", async () => { + const { b } = backend(); + act(() => { + useProject.setState({ project: { root: "/same" } as ProjectInfo }); + useRemote.setState({ session: remote("one") }); + }); + const provider = pluginServiceProvider("p", decl, "plugin", noMenu); + renderHook(() => provider.useRoots()); + await waitFor(() => expect(b.renderView).toHaveBeenCalledTimes(1)); + act(() => useRemote.setState({ session: remote("two") })); + await waitFor(() => expect(b.renderView).toHaveBeenCalledTimes(2)); +}); + +it("drops queued Services selections after a remote host switch", async () => { + const { b } = backend(); + let finish = () => {}; + const viewEvent = vi.fn( + () => + new Promise((resolve) => { + finish = resolve; + }), + ); + setPluginsBackend({ ...b, viewEvent }); + act(() => { + useProject.setState({ project: { root: "/same" } as ProjectInfo }); + useRemote.setState({ session: remote("one") }); + }); + const provider = pluginServiceProvider("p", decl, "plugin", noMenu); + provider.select?.({ key: "plugin:p/kube/a", label: "a", icon: "folder" }); + await waitFor(() => expect(viewEvent).toHaveBeenCalledOnce()); + provider.select?.({ key: "plugin:p/kube/b", label: "b", icon: "folder" }); + act(() => useRemote.setState({ session: remote("two") })); + finish(); + await new Promise((resolve) => setTimeout(resolve, 0)); + expect(viewEvent).toHaveBeenCalledOnce(); +}); + +it("waits for the Services selection handler before requesting its detail", async () => { + const { b } = backend(); + let finish = () => {}; + const viewEvent = vi.fn( + () => + new Promise((resolve) => { + finish = resolve; + }), + ); + const serviceDetail = vi.fn(async () => []); + setPluginsBackend({ ...b, viewEvent, serviceDetail }); + const provider = pluginServiceProvider("p", decl, "plugin", noMenu); + const node = { key: "plugin:p/kube/a", label: "a", icon: "folder" }; + provider.select?.(node); + const Detail = provider.detail!; + render(); + await waitFor(() => expect(viewEvent).toHaveBeenCalledOnce()); + expect(serviceDetail).not.toHaveBeenCalled(); + await act(async () => finish()); + await waitFor(() => expect(serviceDetail).toHaveBeenCalledWith("p", "kube", "a")); +}); diff --git a/src/features/plugins/backend.ts b/src/features/plugins/backend.ts index 154b3d588..d443aae17 100644 --- a/src/features/plugins/backend.ts +++ b/src/features/plugins/backend.ts @@ -100,7 +100,7 @@ export interface PluginsBackend { /** Content of a plugin view (`doc`: the document of a custom editor). */ renderView(pluginId: string, view: string, viewport: Viewport | null, doc: number | null): Promise; viewEvent(pluginId: string, view: string, event: ViewEvent, doc: number | null): Promise; - /** The Services pane of node `key` of a plugin's services view. */ + /** The detail tabs of item `key` in a Services or `detail = true` view. */ serviceDetail(pluginId: string, view: string, key: string): Promise; /** The HTTP routes a plugin reports for this window's project (`[[contributes.endpoints]]`). */ endpoints(pluginId: string): Promise; diff --git a/src/features/plugins/uiPoints.tsx b/src/features/plugins/uiPoints.tsx index 75d91a74a..25ca7b6fe 100644 --- a/src/features/plugins/uiPoints.tsx +++ b/src/features/plugins/uiPoints.tsx @@ -365,6 +365,7 @@ interface ViewDecl { title: string; icon?: string | null; location: ToolWindowAnchor | "services"; + detail?: boolean; web?: string; group?: string | null; when?: string | null; @@ -475,7 +476,7 @@ function projectView(pluginId: string, decl: ViewDecl, index: number): () => voi decl.web ? ( ) : ( - + ), index, ); diff --git a/src/features/plugins/views/PluginView.module.css b/src/features/plugins/views/PluginView.module.css index b8f4c443a..d90af139f 100644 --- a/src/features/plugins/views/PluginView.module.css +++ b/src/features/plugins/views/PluginView.module.css @@ -80,6 +80,15 @@ outline: none; } +.listItem[aria-selected="true"] { + background: var(--bg-tree-selected); +} + +.master { + height: 100%; + overflow: auto; +} + .detail { color: var(--fg-muted); } diff --git a/src/features/plugins/views/PluginView.tsx b/src/features/plugins/views/PluginView.tsx index 669b2cb36..e6df815a3 100644 --- a/src/features/plugins/views/PluginView.tsx +++ b/src/features/plugins/views/PluginView.tsx @@ -27,6 +27,9 @@ import { Input, Select, Spinner, + SplitGroup, + SplitHandle, + SplitPanel, Tree, showContextMenu, type MenuItem, @@ -35,7 +38,8 @@ import { pluginsBackend } from "../backend"; import { subscribeTheme, themeKey } from "@/platform/themeWatch"; import { FRAME_TAG, frameDocument, frameTheme, frameThemeMessage } from "./frame"; import { localizeView, usePluginT } from "../pluginText"; -import { onViewMessage, useViewRevision } from "./viewStore"; +import { currentViewLocation, onViewMessage, useViewLocation, useViewRevision } from "./viewStore"; +import { ServicePane } from "./ServicePane"; import styles from "./PluginView.module.css"; export interface PluginViewProps { @@ -49,6 +53,8 @@ export interface PluginViewProps { label?: string; /** Context menu entries by item key (tables use the absolute row index). */ itemMenu?: (key: string) => MenuItem[]; + /** Show detail-provider tabs beside a tree or list. */ + detail?: boolean; } /** Table rows asked for beyond the visible ones (each side). */ @@ -57,14 +63,23 @@ const ROW_HEIGHT = 24; /** Plugin text is shown as written: the plugin translates it through its own catalog. */ export function PluginView(props: PluginViewProps) { + const location = useViewLocation(); return ( - + ); } -function PluginViewContent({ pluginId, view, doc = null, revision = 0, label, itemMenu }: PluginViewProps) { +function PluginViewContent({ + pluginId, + view, + doc = null, + revision = 0, + label, + itemMenu, + detail = false, +}: PluginViewProps) { const [rendered, setContent] = useState(null); const t = usePluginT(pluginId); const content = useMemo(() => rendered && localizeView(rendered, t), [rendered, t]); @@ -72,6 +87,24 @@ function PluginViewContent({ pluginId, view, doc = null, revision = 0, label, it const [viewport, setViewport] = useState(null); const pluginRevision = useViewRevision(pluginId, view); const seq = useRef(0); + const mounted = useRef(true); + const queue = useRef(Promise.resolve()); + const [selection, setSelection] = useState<{ key: string; after: Promise } | null>(null); + const items = content?.body.kind === "tree" || content?.body.kind === "list" ? content.body.value : null; + const hasDetail = detail && items !== null; + const selected = hasDetail && items.some((i) => i.key === selection?.key) ? selection : null; + const splitId = `plugin-detail-${encodeURIComponent(JSON.stringify([pluginId, view]))}`; + + useEffect(() => { + mounted.current = true; + return () => { + mounted.current = false; + }; + }, []); + + useEffect(() => { + if (!selected) setSelection(null); + }, [selected]); useEffect(() => { const mine = ++seq.current; @@ -88,13 +121,23 @@ function PluginViewContent({ pluginId, view, doc = null, revision = 0, label, it setError(e instanceof Error ? e.message : String(e)); }, ); + return () => { + ++seq.current; + }; }, [pluginId, view, doc, viewport, revision, pluginRevision]); const send = useCallback( (event: ViewEvent) => { - pluginsBackend() - .viewEvent(pluginId, view, event, doc) - .catch((e: unknown) => setError(e instanceof Error ? e.message : String(e))); + const location = currentViewLocation(); + const pending = queue.current.then(() => + mounted.current && location === currentViewLocation() + ? pluginsBackend().viewEvent(pluginId, view, event, doc) + : undefined, + ); + queue.current = pending.catch((e: unknown) => { + if (mounted.current) setError(e instanceof Error ? e.message : String(e)); + }); + if (event.kind === "select") setSelection({ key: event.key, after: pending }); }, [pluginId, view, doc], ); @@ -143,14 +186,43 @@ function PluginViewContent({ pluginId, view, doc = null, revision = 0, label, it )}
- + {hasDetail ? ( + + +
+ +
+
+ + + {selected ? ( + + ) : ( + + )} + +
+ ) : ( + + )}
{content.status &&
{content.status}
} @@ -164,15 +236,16 @@ interface BodyProps { view: string; onViewport: (v: Viewport) => void; itemMenu?: (key: string) => MenuItem[]; + selectedKey?: string | null; } -function Body({ content, send, pluginId, view, onViewport, itemMenu }: BodyProps) { +function Body({ content, send, pluginId, view, onViewport, itemMenu, selectedKey }: BodyProps) { const body = content.body; switch (body.kind) { case "message": return ; case "tree": - return ; + return ; case "list": return (
    @@ -180,12 +253,32 @@ function Body({ content, send, pluginId, view, onViewport, itemMenu }: BodyProps
  • send({ kind: "select", key: i.key })} onDoubleClick={() => send({ kind: "activate", key: i.key })} - onKeyDown={(e) => e.key === "Enter" && send({ kind: "activate", key: i.key })} + onKeyDown={(e) => { + if (selectedKey === undefined) { + if (e.key === "Enter") send({ kind: "activate", key: i.key }); + return; + } + if (e.key === " ") { + e.preventDefault(); + send({ kind: "select", key: i.key }); + } else if (e.key === "Enter") { + send({ kind: "select", key: i.key }); + send({ kind: "activate", key: i.key }); + } else if (e.key === "ArrowDown" || e.key === "ArrowUp") { + e.preventDefault(); + const index = body.value.indexOf(i) + (e.key === "ArrowDown" ? 1 : -1); + const next = body.value[index]; + if (next) { + (e.currentTarget.parentElement?.children[index] as HTMLElement | undefined)?.focus(); + send({ kind: "select", key: next.key }); + } + } + }} onContextMenu={(e) => openItemMenu(e, itemMenu, i.key)} > {i.icon && } @@ -245,9 +338,10 @@ interface TreeBodyProps { items: ViewTreeItem[]; send: (e: ViewEvent) => void; itemMenu?: (key: string) => MenuItem[]; + selectedKey?: string | null; } -function TreeBody({ items, send, itemMenu }: TreeBodyProps) { +function TreeBody({ items, send, itemMenu, selectedKey }: TreeBodyProps) { const roots = useMemo(() => treeNodes(items), [items]); const expanded = useMemo(() => new Set(items.filter((i) => i.expanded).map((i) => i.key)), [items]); return ( @@ -260,6 +354,7 @@ function TreeBody({ items, send, itemMenu }: TreeBodyProps) { getIcon={(n) => n.item.icon ?? undefined} getDetail={(n) => n.item.detail ?? undefined} expanded={expanded} + selected={selectedKey === undefined ? undefined : new Set(selectedKey === null ? [] : [selectedKey])} onExpandedChange={(_, node, isExpanded) => send(isExpanded ? { kind: "expand", key: node.item.key } : { kind: "collapse", key: node.item.key }) } diff --git a/src/features/plugins/views/ServicePane.tsx b/src/features/plugins/views/ServicePane.tsx index 0044264ad..a9b23cd4a 100644 --- a/src/features/plugins/views/ServicePane.tsx +++ b/src/features/plugins/views/ServicePane.tsx @@ -1,6 +1,5 @@ /** - * The Services pane of a node of a plugin's `location = "services"` view: the - * tabs its `service-provider` returns, switched here without calling the plugin. + * The detail-provider tabs of a selected item, shared by Services and tool windows. */ import { useEffect, useState } from "react"; import type { ServiceTab } from "@/bindings"; @@ -8,25 +7,30 @@ import { tx, VerbatimTextContext } from "@/platform/i18n"; import { EmptyState, LogPane, Spinner, Tabs } from "@/ui"; import { copySelectionOnKeyDown } from "@/ui/selectableText"; import { pluginsBackend } from "../backend"; -import { useViewRevision } from "./viewStore"; +import { useToolWindowShown } from "@/workbench/contributions"; +import { useViewLocation, useViewRevision } from "./viewStore"; import styles from "./ServicePane.module.css"; interface ServicePaneProps { pluginId: string; view: string; itemKey: string; + after?: Promise; } /** Plugin text is shown as written: the plugin translates it through its own catalog. */ export function ServicePane(props: ServicePaneProps) { + const location = useViewLocation(); + const shown = useToolWindowShown(); + if (!shown) return null; return ( - + ); } -function ServicePaneContent({ pluginId, view, itemKey }: ServicePaneProps) { +function ServicePaneContent({ pluginId, view, itemKey, after }: ServicePaneProps) { // `views.refresh()` asks for the pane again. const revision = useViewRevision(pluginId, view); const [tabs, setTabs] = useState(null); @@ -35,8 +39,8 @@ function ServicePaneContent({ pluginId, view, itemKey }: ServicePaneProps) { useEffect(() => { let alive = true; - pluginsBackend() - .serviceDetail(pluginId, view, itemKey) + Promise.resolve(after) + .then(() => (alive ? pluginsBackend().serviceDetail(pluginId, view, itemKey) : [])) .then( (t) => { if (!alive) return; @@ -48,7 +52,7 @@ function ServicePaneContent({ pluginId, view, itemKey }: ServicePaneProps) { return () => { alive = false; }; - }, [pluginId, view, itemKey, revision]); + }, [pluginId, view, itemKey, revision, after]); if (error) return ; if (!tabs) return ; diff --git a/src/features/plugins/views/serviceProvider.tsx b/src/features/plugins/views/serviceProvider.tsx index 9c301a00d..464be153e 100644 --- a/src/features/plugins/views/serviceProvider.tsx +++ b/src/features/plugins/views/serviceProvider.tsx @@ -2,7 +2,7 @@ * A plugin view declared with `location = "services"`: its tree's items are * nodes of the Services tool window, its toolbar the Services toolbar for one * selected node, `viewItem.context` its nodes' right-click menu, and the - * plugin's `service-provider` the selected node's pane. + * plugin's `detail-provider` the selected node's pane. */ import { useEffect, useMemo, useState } from "react"; import type { View, ViewEvent } from "@/bindings"; @@ -11,7 +11,7 @@ import type { ServiceProviderContribution, ServiceTreeItem } from "@/workbench/c import { pluginsBackend } from "../backend"; import { treeNodes, type TreeNode } from "./PluginView"; import { ServicePane } from "./ServicePane"; -import { useViewRevision } from "./viewStore"; +import { currentViewLocation, useViewLocation, useViewRevision } from "./viewStore"; interface ServicesViewDecl { id: string; @@ -30,8 +30,11 @@ export function pluginServiceProvider( // Events of one node stay in order (a toolbar button after the select it acts on). let queue = Promise.resolve(); const send = (event: ViewEvent) => { + const location = currentViewLocation(); queue = queue - .then(() => pluginsBackend().viewEvent(pluginId, decl.id, event, null)) + .then(() => + location === currentViewLocation() ? pluginsBackend().viewEvent(pluginId, decl.id, event, null) : undefined, + ) .catch((e: unknown) => console.warn(`plugin ${pluginId}: view ${decl.id}`, e)); }; const toItem = (n: TreeNode): ServiceTreeItem => ({ @@ -49,7 +52,9 @@ export function pluginServiceProvider( order: 900, useRoots() { const revision = useViewRevision(pluginId, decl.id); + const location = useViewLocation(); const [view, setView] = useState(null); + const [renderedLocation, setRenderedLocation] = useState(location); useEffect(() => { let alive = true; pluginsBackend() @@ -59,14 +64,23 @@ export function pluginServiceProvider( if (!alive) return; toolbar = v.toolbar; setView(v); + setRenderedLocation(location); }, (e: unknown) => console.warn(`plugin ${pluginId}: view ${decl.id}`, e), ); return () => { alive = false; }; - }, [revision]); - return useMemo(() => (view?.body.kind === "tree" ? treeNodes(view.body.value).map(toItem) : []), [view]); + }, [revision, location]); + return useMemo(() => { + if (renderedLocation !== location) return []; + if (view?.body.kind === "tree") return treeNodes(view.body.value).map(toItem); + if (view?.body.kind === "list") + return view.body.value.map((item) => + toItem({ item: { ...item, parent: null, expandable: false, expanded: false }, children: [] }), + ); + return []; + }, [view, location, renderedLocation]); }, // Ids per node: the Services toolbar offers an action of several selected // nodes only when they share its id, and a plugin's buttons act on one. @@ -89,6 +103,6 @@ export function pluginServiceProvider( }; function Detail({ item }: { item: ServiceTreeItem }) { - return ; + return ; } } diff --git a/src/features/plugins/views/viewStore.ts b/src/features/plugins/views/viewStore.ts index 433f636d7..fa0b25326 100644 --- a/src/features/plugins/views/viewStore.ts +++ b/src/features/plugins/views/viewStore.ts @@ -4,6 +4,18 @@ * sends to the script of an `html` body (`viewMessage`). */ import { create } from "zustand"; +import { useProject } from "@/platform/project"; +import { projectLocation, useRemote } from "@/platform/remote"; + +export function currentViewLocation(): string | null { + return projectLocation(useProject.getState().project?.root); +} + +export function useViewLocation(): string | null { + const root = useProject((s) => s.project?.root); + useRemote((s) => s.session); + return projectLocation(root); +} export const viewKey = (pluginId: string, view: string) => `${pluginId}/${view}`; diff --git a/src/features/services/ServicesTree.tsx b/src/features/services/ServicesTree.tsx index 839247649..faa67ba9b 100644 --- a/src/features/services/ServicesTree.tsx +++ b/src/features/services/ServicesTree.tsx @@ -205,8 +205,8 @@ export function ServicesTreeView() { ) : ( - - + +
    key={location} @@ -258,7 +258,7 @@ export function ServicesTreeView() {
    - + {selected && Detail && shown ? ( ) : ( diff --git a/src/platform/locales/text/en.json b/src/platform/locales/text/en.json index fc2b480fc..a17b7f7d2 100644 --- a/src/platform/locales/text/en.json +++ b/src/platform/locales/text/en.json @@ -313,5 +313,7 @@ "Reopen in Container": "Reopen in Container", "Builds or starts the project's dev container (devcontainer.json) with the Dev Containers CLI and opens the project in it.": "Builds or starts the project's dev container (devcontainer.json) with the Dev Containers CLI and opens the project in it.", "devcontainer up exited with {status}": "devcontainer up exited with {status}", + "Select an item to view details": "Select an item to view details", + "Nothing to show": "Nothing to show", "IDE-managed Tomcat runtime directory must not overlap Tomcat home or base directory": "IDE-managed Tomcat runtime directory must not overlap Tomcat home or base directory" } diff --git a/src/platform/locales/text/zh.json b/src/platform/locales/text/zh.json index b256a1a96..9f497af11 100644 --- a/src/platform/locales/text/zh.json +++ b/src/platform/locales/text/zh.json @@ -6680,5 +6680,6 @@ "Builds or starts the project's dev container (devcontainer.json) with the Dev Containers CLI and opens the project in it.": "使用 Dev Containers CLI 构建或启动项目的开发容器(devcontainer.json),并在其中打开项目。", "Read-only: the table schema could not be identified in the result database.": "只读:无法确定结果所在数据库中的表架构。", "devcontainer up exited with {status}": "devcontainer up 已退出,状态为 {status}", + "Select an item to view details": "选择条目以查看详情", "IDE-managed Tomcat runtime directory must not overlap Tomcat home or base directory": "IDE 托管的 Tomcat 运行目录不得与 Tomcat 主目录或基目录重叠" } diff --git a/src/ui/Splitter.tsx b/src/ui/Splitter.tsx index 8c71a47f9..d4448641f 100644 --- a/src/ui/Splitter.tsx +++ b/src/ui/Splitter.tsx @@ -4,10 +4,55 @@ */ import { Group, Panel, Separator, type GroupProps, type PanelProps, type SeparatorProps } from "react-resizable-panels"; import clsx from "clsx"; +import { useState } from "react"; import styles from "./Splitter.module.css"; -export function SplitGroup({ className, ...rest }: GroupProps) { - return ; +export function SplitGroup({ + className, + storageKey, + defaultLayout, + onLayoutChanged, + ...rest +}: GroupProps & { storageKey?: string }) { + const [saved] = useState(() => { + try { + const value: unknown = storageKey ? JSON.parse(localStorage.getItem(storageKey) ?? "null") : null; + return value && + typeof value === "object" && + !Array.isArray(value) && + Object.values(value).every((n) => typeof n === "number" && Number.isFinite(n) && n >= 0 && n <= 100) + ? (value as Record) + : undefined; + } catch { + return undefined; + } + }); + if (!storageKey) + return ( + + ); + return ( + { + if (storageKey && meta.isUserInteraction) { + try { + localStorage.setItem(storageKey, JSON.stringify(meta.requestedLayout ?? layout)); + } catch { + /* Storage may be unavailable. */ + } + } + onLayoutChanged?.(layout, meta); + }} + /> + ); } export function SplitPanel({ className, ...rest }: PanelProps) {