diff --git a/.changes/cli-mobile-dev.md b/.changes/cli-mobile-dev.md new file mode 100644 index 000000000..bd0df7aa9 --- /dev/null +++ b/.changes/cli-mobile-dev.md @@ -0,0 +1,6 @@ +--- +"cli.rs": minor +"cli.js": minor +--- + +Added `android dev` and `ios dev` commands. diff --git a/.changes/codegen-mobile-devurl.md b/.changes/codegen-mobile-devurl.md new file mode 100644 index 000000000..da7c8812d --- /dev/null +++ b/.changes/codegen-mobile-devurl.md @@ -0,0 +1,5 @@ +--- +"tauri-codegen": patch +--- + +Change `devPath` URL to use the local IP address on iOS and Android. diff --git a/.changes/dev-proxy.md b/.changes/dev-proxy.md new file mode 100644 index 000000000..3e4e88316 --- /dev/null +++ b/.changes/dev-proxy.md @@ -0,0 +1,5 @@ +--- +"tauri": major +--- + +**Breaking change:** Use the custom protocol as a proxy to the development server on all platforms except Linux. diff --git a/core/tauri-codegen/Cargo.toml b/core/tauri-codegen/Cargo.toml index 590465c8f..b2b08da15 100644 --- a/core/tauri-codegen/Cargo.toml +++ b/core/tauri-codegen/Cargo.toml @@ -29,6 +29,8 @@ semver = "1" ico = "0.1" png = "0.17" json-patch = "0.2" +local-ip-address = "0.4" +url = "2" [target."cfg(target_os = \"macos\")".dependencies] plist = "1" diff --git a/core/tauri-codegen/src/context.rs b/core/tauri-codegen/src/context.rs index d5e5cd578..28264dbce 100644 --- a/core/tauri-codegen/src/context.rs +++ b/core/tauri-codegen/src/context.rs @@ -122,7 +122,7 @@ enum Target { pub fn context_codegen(data: ContextData) -> Result { let ContextData { dev, - config, + mut config, config_parent, root, } = data; @@ -155,6 +155,23 @@ pub fn context_codegen(data: ContextData) -> Result d == "localhost", + Some(url::Host::Ipv4(i)) => { + i == std::net::Ipv4Addr::LOCALHOST || i == std::net::Ipv4Addr::UNSPECIFIED + } + _ => false, + }; + if localhost { + if let Ok(ip) = local_ip_address::local_ip() { + url.set_host(Some(&ip.to_string())).unwrap(); + } + } + } + } + let mut options = AssetOptions::new(config.tauri.pattern.clone()) .freeze_prototype(config.tauri.security.freeze_prototype) .dangerous_disable_asset_csp_modification( diff --git a/core/tauri-codegen/src/embedded_assets.rs b/core/tauri-codegen/src/embedded_assets.rs index a5983fa6e..7e2437efc 100644 --- a/core/tauri-codegen/src/embedded_assets.rs +++ b/core/tauri-codegen/src/embedded_assets.rs @@ -431,6 +431,7 @@ impl ToTokens for EmbeddedAssets { // we expect phf related items to be in path when generating the path code tokens.append_all(quote! {{ + #[allow(unused_imports)] use ::tauri::utils::assets::{CspHash, EmbeddedAssets, phf, phf::phf_map}; EmbeddedAssets::new(phf_map! { #assets }, &[#global_hashes], phf_map! { #html_hashes }) }}); diff --git a/core/tauri-utils/src/config.rs b/core/tauri-utils/src/config.rs index 5e6a72091..0545b04ce 100644 --- a/core/tauri-utils/src/config.rs +++ b/core/tauri-utils/src/config.rs @@ -2364,7 +2364,7 @@ fn default_dialog() -> bool { #[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct IosConfig { /// The development team. This value is required for iOS development because code signing is enforced. - /// The `APPLE_DEVELOPMENT_TEAM` environment variable can be set to overwrite it. + /// The `TAURI_APPLE_DEVELOPMENT_TEAM` environment variable can be set to overwrite it. #[serde(alias = "development-team")] pub development_team: Option, } diff --git a/core/tauri/Cargo.toml b/core/tauri/Cargo.toml index d11edae25..879245f65 100644 --- a/core/tauri/Cargo.toml +++ b/core/tauri/Cargo.toml @@ -75,7 +75,7 @@ base64 = { version = "0.13", optional = true } clap = { version = "3", optional = true } reqwest = { version = "0.11", features = [ "json", "stream" ], optional = true } bytes = { version = "1", features = [ "serde" ], optional = true } -attohttpc = { version = "0.20", features = [ "compress", "json", "form" ], optional = true } +attohttpc = { version = "0.20", features = [ "compress", "json", "form" ] } open = { version = "3.0", optional = true } shared_child = { version = "1.0", optional = true } os_pipe = { version = "1.0", optional = true } @@ -146,7 +146,7 @@ updater = [ "dialog-ask", "fs-extract-api" ] -http-api = [ "attohttpc" ] +http-api = [ ] http-multipart = [ "attohttpc/multipart-form", "reqwest/multipart" ] shell-open-api = [ "open", "regex", "tauri-macros/shell-scope" ] fs-extract-api = [ "zip" ] diff --git a/core/tauri/src/manager.rs b/core/tauri/src/manager.rs index 673fb3c6b..1f670d235 100644 --- a/core/tauri/src/manager.rs +++ b/core/tauri/src/manager.rs @@ -142,11 +142,6 @@ fn set_csp( Csp::DirectiveMap(csp).to_string() } -#[cfg(target_os = "linux")] -fn set_html_csp(html: &str, csp: &str) -> String { - html.replacen(tauri_utils::html::CSP_TOKEN, csp, 1) -} - // inspired by https://github.com/rust-lang/rust/blob/1be5c8f90912c446ecbdc405cbc4a89f9acd20fd/library/alloc/src/str.rs#L260-L297 fn replace_with_callback String>( original: &str, @@ -374,7 +369,13 @@ impl WindowManager { /// Get the origin as it will be seen in the webview. fn get_browser_origin(&self) -> String { match self.base_path() { - AppUrl::Url(WindowUrl::External(url)) => url.origin().ascii_serialization(), + AppUrl::Url(WindowUrl::External(url)) => { + if cfg!(dev) && !cfg!(target_os = "linux") { + format_real_schema("tauri") + } else { + url.origin().ascii_serialization() + } + } _ => format_real_schema("tauri"), } } @@ -820,8 +821,12 @@ impl WindowManager { >, ) -> Box Result> + Send + Sync> { + #[cfg(dev)] + let url = self.get_url().into_owned(); + #[cfg(not(dev))] let manager = self.clone(); let window_origin = window_origin.to_string(); + Box::new(move |request| { let path = request .uri() @@ -834,32 +839,47 @@ impl WindowManager { // the `strip_prefix` only returns None when a request is made to `https://tauri.$P` on Windows // where `$P` is not `localhost/*` .unwrap_or_else(|| "".to_string()); - let asset = manager.get_asset(path)?; - let mut builder = HttpResponseBuilder::new() - .header("Access-Control-Allow-Origin", &window_origin) - .mimetype(&asset.mime_type); - if let Some(csp) = &asset.csp_header { - builder = builder.header("Content-Security-Policy", csp); - } - let mut response = builder.body(asset.bytes)?; - if let Some(handler) = &web_resource_request_handler { - handler(request, &mut response); - // if it's an HTML file, we need to set the CSP meta tag on Linux - #[cfg(target_os = "linux")] - if let Some(response_csp) = response.headers().get("Content-Security-Policy") { - let response_csp = String::from_utf8_lossy(response_csp.as_bytes()); - let body = set_html_csp(&String::from_utf8_lossy(response.body()), &response_csp); - *response.body_mut() = body.as_bytes().to_vec(); - } - } else { - #[cfg(target_os = "linux")] - { - if let Some(csp) = &asset.csp_header { - let body = set_html_csp(&String::from_utf8_lossy(response.body()), csp); - *response.body_mut() = body.as_bytes().to_vec(); + let mut builder = + HttpResponseBuilder::new().header("Access-Control-Allow-Origin", &window_origin); + + #[cfg(dev)] + let mut response = { + let mut url = url.clone(); + url.set_path(&path); + match attohttpc::get(url.as_str()).send() { + Ok(r) => { + for (name, value) in r.headers() { + builder = builder.header(name, value); + } + builder.status(r.status()).body(r.bytes()?)? + } + Err(e) => { + debug_eprintln!("Failed to request {}: {}", url.path(), e); + return Err(Box::new(e)); } } + }; + + #[cfg(not(dev))] + let mut response = { + let asset = manager.get_asset(path)?; + builder = builder.mimetype(&asset.mime_type); + if let Some(csp) = &asset.csp_header { + builder = builder.header("Content-Security-Policy", csp); + } + builder.body(asset.bytes)? + }; + if let Some(handler) = &web_resource_request_handler { + handler(request, &mut response); + } + // if it's an HTML file, we need to set the CSP meta tag on Linux + #[cfg(all(not(dev), target_os = "linux"))] + if let Some(response_csp) = response.headers().get("Content-Security-Policy") { + let response_csp = String::from_utf8_lossy(response_csp.as_bytes()); + let html = String::from_utf8_lossy(response.body()); + let body = html.replacen(tauri_utils::html::CSP_TOKEN, &response_csp, 1); + *response.body_mut() = body.as_bytes().to_vec(); } Ok(response) }) @@ -1061,7 +1081,10 @@ impl WindowManager { #[allow(unused_mut)] // mut url only for the data-url parsing let (is_local, mut url) = match &pending.webview_attributes.url { WindowUrl::App(path) => { + #[cfg(target_os = "linux")] let url = self.get_url(); + #[cfg(not(target_os = "linux"))] + let url: Cow<'_, Url> = Cow::Owned(Url::parse("tauri://localhost").unwrap()); ( true, // ignore "index.html" just to simplify the url @@ -1078,7 +1101,13 @@ impl WindowManager { } WindowUrl::External(url) => { let config_url = self.get_url(); - (config_url.make_relative(url).is_some(), url.clone()) + let is_local = config_url.make_relative(url).is_some(); + let mut url = url.clone(); + if is_local && !cfg!(target_os = "linux") { + url.set_scheme("tauri").unwrap(); + url.set_host(Some("localhost")).unwrap(); + } + (is_local, url) } _ => unimplemented!(), }; diff --git a/examples/api/dist/assets/index.js b/examples/api/dist/assets/index.js index 7ed233678..52f29c45b 100644 --- a/examples/api/dist/assets/index.js +++ b/examples/api/dist/assets/index.js @@ -1,44 +1,44 @@ -const Zl=function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))i(o);new MutationObserver(o=>{for(const l of o)if(l.type==="childList")for(const u of l.addedNodes)u.tagName==="LINK"&&u.rel==="modulepreload"&&i(u)}).observe(document,{childList:!0,subtree:!0});function n(o){const l={};return o.integrity&&(l.integrity=o.integrity),o.referrerpolicy&&(l.referrerPolicy=o.referrerpolicy),o.crossorigin==="use-credentials"?l.credentials="include":o.crossorigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function i(o){if(o.ep)return;o.ep=!0;const l=n(o);fetch(o.href,l)}};Zl();function J(){}function vl(t){return t()}function Io(){return Object.create(null)}function pe(t){t.forEach(vl)}function $l(t){return typeof t=="function"}function ke(t,e){return t!=t?e==e:t!==e||t&&typeof t=="object"||typeof t=="function"}let Un;function er(t,e){return Un||(Un=document.createElement("a")),Un.href=e,t===Un.href}function tr(t){return Object.keys(t).length===0}function nr(t,...e){if(t==null)return J;const n=t.subscribe(...e);return n.unsubscribe?()=>n.unsubscribe():n}function _l(t,e,n){t.$$.on_destroy.push(nr(e,n))}function r(t,e){t.appendChild(e)}function m(t,e,n){t.insertBefore(e,n||null)}function h(t){t.parentNode.removeChild(t)}function dt(t,e){for(let n=0;nt.removeEventListener(e,n,i)}function Xn(t){return function(e){return e.preventDefault(),t.call(this,e)}}function a(t,e,n){n==null?t.removeAttribute(e):t.getAttribute(e)!==n&&t.setAttribute(e,n)}function se(t){return t===""?null:+t}function or(t){return Array.from(t.childNodes)}function Z(t,e){e=""+e,t.wholeText!==e&&(t.data=e)}function G(t,e){t.value=e==null?"":e}function zt(t,e){for(let n=0;n{Vn.delete(t),i&&(n&&t.d(1),i())}),t.o(e)}else i&&i()}function Kn(t){t&&t.c()}function Vt(t,e,n,i){const{fragment:o,on_mount:l,on_destroy:u,after_update:f}=t.$$;o&&o.m(e,n),i||Lt(()=>{const c=l.map(vl).filter($l);u?u.push(...c):pe(c),t.$$.on_mount=[]}),f.forEach(Lt)}function Gt(t,e){const n=t.$$;n.fragment!==null&&(pe(n.on_destroy),n.fragment&&n.fragment.d(e),n.on_destroy=n.fragment=null,n.ctx=[])}function ar(t,e){t.$$.dirty[0]===-1&&(Ut.push(t),sr(),t.$$.dirty.fill(0)),t.$$.dirty[e/31|0]|=1<{const g=y.length?y[0]:_;return p.ctx&&o(p.ctx[k],p.ctx[k]=g)&&(!p.skip_bound&&p.bound[k]&&p.bound[k](g),d&&ar(t,k)),_}):[],p.update(),d=!0,pe(p.before_update),p.fragment=i?i(p.ctx):!1,e.target){if(e.hydrate){const k=or(e.target);p.fragment&&p.fragment.l(k),k.forEach(h)}else p.fragment&&p.fragment.c();e.intro&&Ee(t.$$.fragment),Vt(t,e.target,e.anchor,e.customElement),gl()}qt(c)}class Se{$destroy(){Gt(this,1),this.$destroy=J}$on(e,n){const i=this.$$.callbacks[e]||(this.$$.callbacks[e]=[]);return i.push(n),()=>{const o=i.indexOf(n);o!==-1&&i.splice(o,1)}}$set(e){this.$$set&&!tr(e)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}}const Ct=[];function yl(t,e=J){let n;const i=new Set;function o(f){if(ke(t,f)&&(t=f,n)){const c=!Ct.length;for(const p of i)p[1](),Ct.push(p,t);if(c){for(let p=0;p{i.delete(p),i.size===0&&(n(),n=null)}}return{set:o,update:l,subscribe:u}}var Ei=function(t,e){return Ei=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,i){n.__proto__=i}||function(n,i){for(var o in i)Object.prototype.hasOwnProperty.call(i,o)&&(n[o]=i[o])},Ei(t,e)};function ji(t,e){if(typeof e!="function"&&e!==null)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function n(){this.constructor=t}Ei(t,e),t.prototype=e===null?Object.create(e):(n.prototype=e.prototype,new n)}var ue=function(){return ue=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0&&o[o.length-1])||d[0]!==6&&d[0]!==2)){u=0;continue}if(d[0]===3&&(!o||d[1]>o[0]&&d[1]{for(const l of o)if(l.type==="childList")for(const a of l.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&i(a)}).observe(document,{childList:!0,subtree:!0});function n(o){const l={};return o.integrity&&(l.integrity=o.integrity),o.referrerpolicy&&(l.referrerPolicy=o.referrerpolicy),o.crossorigin==="use-credentials"?l.credentials="include":o.crossorigin==="anonymous"?l.credentials="omit":l.credentials="same-origin",l}function i(o){if(o.ep)return;o.ep=!0;const l=n(o);fetch(o.href,l)}})();function J(){}function vl(t){return t()}function Io(){return Object.create(null)}function pe(t){t.forEach(vl)}function xl(t){return typeof t=="function"}function ke(t,e){return t!=t?e==e:t!==e||t&&typeof t=="object"||typeof t=="function"}let Un;function $l(t,e){return Un||(Un=document.createElement("a")),Un.href=e,t===Un.href}function er(t){return Object.keys(t).length===0}function tr(t,...e){if(t==null)return J;const n=t.subscribe(...e);return n.unsubscribe?()=>n.unsubscribe():n}function _l(t,e,n){t.$$.on_destroy.push(tr(e,n))}function r(t,e){t.appendChild(e)}function m(t,e,n){t.insertBefore(e,n||null)}function h(t){t.parentNode.removeChild(t)}function dt(t,e){for(let n=0;nt.removeEventListener(e,n,i)}function Xn(t){return function(e){return e.preventDefault(),t.call(this,e)}}function u(t,e,n){n==null?t.removeAttribute(e):t.getAttribute(e)!==n&&t.setAttribute(e,n)}function se(t){return t===""?null:+t}function ir(t){return Array.from(t.childNodes)}function x(t,e){e=""+e,t.wholeText!==e&&(t.data=e)}function G(t,e){t.value=e==null?"":e}function zt(t,e){for(let n=0;n{Vn.delete(t),i&&(n&&t.d(1),i())}),t.o(e)}else i&&i()}function Kn(t){t&&t.c()}function Vt(t,e,n,i){const{fragment:o,on_mount:l,on_destroy:a,after_update:f}=t.$$;o&&o.m(e,n),i||Lt(()=>{const c=l.map(vl).filter(xl);a?a.push(...c):pe(c),t.$$.on_mount=[]}),f.forEach(Lt)}function Gt(t,e){const n=t.$$;n.fragment!==null&&(pe(n.on_destroy),n.fragment&&n.fragment.d(e),n.on_destroy=n.fragment=null,n.ctx=[])}function ur(t,e){t.$$.dirty[0]===-1&&(Ut.push(t),rr(),t.$$.dirty.fill(0)),t.$$.dirty[e/31|0]|=1<{const g=y.length?y[0]:_;return p.ctx&&o(p.ctx[w],p.ctx[w]=g)&&(!p.skip_bound&&p.bound[w]&&p.bound[w](g),d&&ur(t,w)),_}):[],p.update(),d=!0,pe(p.before_update),p.fragment=i?i(p.ctx):!1,e.target){if(e.hydrate){const w=ir(e.target);p.fragment&&p.fragment.l(w),w.forEach(h)}else p.fragment&&p.fragment.c();e.intro&&Ee(t.$$.fragment),Vt(t,e.target,e.anchor,e.customElement),gl()}qt(c)}class Se{$destroy(){Gt(this,1),this.$destroy=J}$on(e,n){const i=this.$$.callbacks[e]||(this.$$.callbacks[e]=[]);return i.push(n),()=>{const o=i.indexOf(n);o!==-1&&i.splice(o,1)}}$set(e){this.$$set&&!er(e)&&(this.$$.skip_bound=!0,this.$$set(e),this.$$.skip_bound=!1)}}const Ct=[];function yl(t,e=J){let n;const i=new Set;function o(f){if(ke(t,f)&&(t=f,n)){const c=!Ct.length;for(const p of i)p[1](),Ct.push(p,t);if(c){for(let p=0;p{i.delete(p),i.size===0&&(n(),n=null)}}return{set:o,update:l,subscribe:a}}var Ei=function(t,e){return Ei=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(n,i){n.__proto__=i}||function(n,i){for(var o in i)Object.prototype.hasOwnProperty.call(i,o)&&(n[o]=i[o])},Ei(t,e)};function ji(t,e){if(typeof e!="function"&&e!==null)throw new TypeError("Class extends value "+String(e)+" is not a constructor or null");function n(){this.constructor=t}Ei(t,e),t.prototype=e===null?Object.create(e):(n.prototype=e.prototype,new n)}var ue=function(){return ue=Object.assign||function(t){for(var e,n=1,i=arguments.length;n0&&o[o.length-1])||d[0]!==6&&d[0]!==2)){a=0;continue}if(d[0]===3&&(!o||d[1]>o[0]&&d[1]@tauri-apps/api package. It's used as the main validation app, serving as the test bed of our +`;function El(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"Os",message:{cmd:"platform"}})]})})}function mr(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"Os",message:{cmd:"version"}})]})})}function vr(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"Os",message:{cmd:"osType"}})]})})}function _r(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"Os",message:{cmd:"arch"}})]})})}function br(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"Os",message:{cmd:"tempdir"}})]})})}Object.freeze({__proto__:null,EOL:hr,platform:El,version:mr,type:vr,arch:_r,tempdir:br});function Wl(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"App",message:{cmd:"getAppVersion"}})]})})}function Dl(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"App",message:{cmd:"getAppName"}})]})})}function jl(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"App",message:{cmd:"getTauriVersion"}})]})})}Object.freeze({__proto__:null,getName:Dl,getVersion:Wl,getTauriVersion:jl});function Rl(t){return t===void 0&&(t=0),M(this,void 0,void 0,function(){return T(this,function(e){return[2,P({__tauriModule:"Process",message:{cmd:"exit",exitCode:t}})]})})}function Fi(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"Process",message:{cmd:"relaunch"}})]})})}Object.freeze({__proto__:null,exit:Rl,relaunch:Fi});function gr(t){let e,n,i,o,l,a,f,c,p,d,w,_,y,g,b,L,W,U,j,q,A,S,z,D,C,N;return{c(){e=s("p"),e.innerHTML=`This is a demo of Tauri's API capabilities using the @tauri-apps/api package. It's used as the main validation app, serving as the test bed of our development process. In the future, this app will be used on Tauri's integration - tests.`,n=v(),i=s("br"),o=v(),l=s("br"),u=v(),f=s("pre"),c=E("App name: "),p=s("code"),d=E(t[2]),k=E(` + tests.`,n=v(),i=s("br"),o=v(),l=s("br"),a=v(),f=s("pre"),c=E("App name: "),p=s("code"),d=E(t[2]),w=E(` App version: `),_=s("code"),y=E(t[0]),g=E(` Tauri version: `),b=s("code"),L=E(t[1]),W=E(` -`),U=v(),j=s("br"),q=v(),A=s("div"),S=s("button"),S.textContent="Close application",z=v(),D=s("button"),D.textContent="Relaunch application",a(S,"class","btn"),a(D,"class","btn"),a(A,"class","flex flex-wrap gap-1 shadow-")},m(B,Y){m(B,e,Y),m(B,n,Y),m(B,i,Y),m(B,o,Y),m(B,l,Y),m(B,u,Y),m(B,f,Y),r(f,c),r(f,p),r(p,d),r(f,k),r(f,_),r(_,y),r(f,g),r(f,b),r(b,L),r(f,W),m(B,U,Y),m(B,j,Y),m(B,q,Y),m(B,A,Y),r(A,S),r(A,z),r(A,D),C||(N=[O(S,"click",t[3]),O(D,"click",t[4])],C=!0)},p(B,[Y]){Y&4&&Z(d,B[2]),Y&1&&Z(y,B[0]),Y&2&&Z(L,B[1])},i:J,o:J,d(B){B&&h(e),B&&h(n),B&&h(i),B&&h(o),B&&h(l),B&&h(u),B&&h(f),B&&h(U),B&&h(j),B&&h(q),B&&h(A),C=!1,pe(N)}}}function wr(t,e,n){let i="0.0.0",o="0.0.0",l="Unknown";Dl().then(c=>{n(2,l=c)}),Wl().then(c=>{n(0,i=c)}),jl().then(c=>{n(1,o=c)});async function u(){await Rl()}async function f(){await Fi()}return[i,o,l,u,f]}class kr extends Se{constructor(e){super(),Ce(this,e,wr,yr,ke,{})}}function Hl(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"Cli",message:{cmd:"cliMatches"}})]})})}Object.freeze({__proto__:null,getMatches:Hl});function Mr(t){let e,n,i,o,l,u,f,c,p,d,k,_,y;return{c(){e=s("p"),e.innerHTML=`This binary can be run from the terminal and takes the following arguments: +`),U=v(),j=s("br"),q=v(),A=s("div"),S=s("button"),S.textContent="Close application",z=v(),D=s("button"),D.textContent="Relaunch application",u(S,"class","btn"),u(D,"class","btn"),u(A,"class","flex flex-wrap gap-1 shadow-")},m(B,Y){m(B,e,Y),m(B,n,Y),m(B,i,Y),m(B,o,Y),m(B,l,Y),m(B,a,Y),m(B,f,Y),r(f,c),r(f,p),r(p,d),r(f,w),r(f,_),r(_,y),r(f,g),r(f,b),r(b,L),r(f,W),m(B,U,Y),m(B,j,Y),m(B,q,Y),m(B,A,Y),r(A,S),r(A,z),r(A,D),C||(N=[O(S,"click",t[3]),O(D,"click",t[4])],C=!0)},p(B,[Y]){Y&4&&x(d,B[2]),Y&1&&x(y,B[0]),Y&2&&x(L,B[1])},i:J,o:J,d(B){B&&h(e),B&&h(n),B&&h(i),B&&h(o),B&&h(l),B&&h(a),B&&h(f),B&&h(U),B&&h(j),B&&h(q),B&&h(A),C=!1,pe(N)}}}function yr(t,e,n){let i="0.0.0",o="0.0.0",l="Unknown";Dl().then(c=>{n(2,l=c)}),Wl().then(c=>{n(0,i=c)}),jl().then(c=>{n(1,o=c)});async function a(){await Rl()}async function f(){await Fi()}return[i,o,l,a,f]}class wr extends Se{constructor(e){super(),Ce(this,e,yr,gr,ke,{})}}function Hl(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"Cli",message:{cmd:"cliMatches"}})]})})}Object.freeze({__proto__:null,getMatches:Hl});function kr(t){let e,n,i,o,l,a,f,c,p,d,w,_,y;return{c(){e=s("p"),e.innerHTML=`This binary can be run from the terminal and takes the following arguments:
  --config <PATH>
   --theme <light|dark|system>
   --verbose
- Additionally, it has a update --background subcommand.`,n=v(),i=s("br"),o=v(),l=s("div"),l.textContent="Note that the arguments are only parsed, not implemented.",u=v(),f=s("br"),c=v(),p=s("br"),d=v(),k=s("button"),k.textContent="Get matches",a(l,"class","note"),a(k,"class","btn"),a(k,"id","cli-matches")},m(g,b){m(g,e,b),m(g,n,b),m(g,i,b),m(g,o,b),m(g,l,b),m(g,u,b),m(g,f,b),m(g,c,b),m(g,p,b),m(g,d,b),m(g,k,b),_||(y=O(k,"click",t[0]),_=!0)},p:J,i:J,o:J,d(g){g&&h(e),g&&h(n),g&&h(i),g&&h(o),g&&h(l),g&&h(u),g&&h(f),g&&h(c),g&&h(p),g&&h(d),g&&h(k),_=!1,y()}}}function Tr(t,e,n){let{onMessage:i}=e;function o(){Hl().then(i).catch(i)}return t.$$set=l=>{"onMessage"in l&&n(1,i=l.onMessage)},[o,i]}class Cr extends Se{constructor(e){super(),Ce(this,e,Tr,Mr,ke,{onMessage:1})}}function Xt(t,e){return M(this,void 0,void 0,function(){return T(this,function(n){return[2,Hi(t,null,e)]})})}function Fl(t,e){return M(this,void 0,void 0,function(){return T(this,function(n){return[2,Sl(t,null,e)]})})}function ni(t,e){return M(this,void 0,void 0,function(){return T(this,function(n){return[2,Cl(t,void 0,e)]})})}Object.freeze({__proto__:null,listen:Xt,once:Fl,emit:ni});function Sr(t){let e,n,i,o,l,u,f,c;return{c(){e=s("div"),n=s("button"),n.textContent="Call Log API",i=v(),o=s("button"),o.textContent="Call Request (async) API",l=v(),u=s("button"),u.textContent="Send event to Rust",a(n,"class","btn"),a(n,"id","log"),a(o,"class","btn"),a(o,"id","request"),a(u,"class","btn"),a(u,"id","event")},m(p,d){m(p,e,d),r(e,n),r(e,i),r(e,o),r(e,l),r(e,u),f||(c=[O(n,"click",t[0]),O(o,"click",t[1]),O(u,"click",t[2])],f=!0)},p:J,i:J,o:J,d(p){p&&h(e),f=!1,pe(c)}}}function zr(t,e,n){let{onMessage:i}=e,o;at(async()=>{o=await Xt("rust-event",i)}),Di(()=>{o&&o()});function l(){xn("log_operation",{event:"tauri-click",payload:"this payload is optional because we used Option in Rust"})}function u(){xn("perform_request",{endpoint:"dummy endpoint arg",body:{id:5,name:"test"}}).then(i).catch(i)}function f(){ni("js-event","this is the payload string")}return t.$$set=c=>{"onMessage"in c&&n(3,i=c.onMessage)},[l,u,f,i]}class Lr extends Se{constructor(e){super(),Ce(this,e,zr,Sr,ke,{onMessage:3})}}function Ii(t){return t===void 0&&(t={}),M(this,void 0,void 0,function(){return T(this,function(e){return typeof t=="object"&&Object.freeze(t),[2,P({__tauriModule:"Dialog",message:{cmd:"openDialog",options:t}})]})})}function Il(t){return t===void 0&&(t={}),M(this,void 0,void 0,function(){return T(this,function(e){return typeof t=="object"&&Object.freeze(t),[2,P({__tauriModule:"Dialog",message:{cmd:"saveDialog",options:t}})]})})}function Ar(t,e){var n;return M(this,void 0,void 0,function(){var i;return T(this,function(o){return i=typeof e=="string"?{title:e}:e,[2,P({__tauriModule:"Dialog",message:{cmd:"messageDialog",message:t.toString(),title:(n=i==null?void 0:i.title)===null||n===void 0?void 0:n.toString(),type:i==null?void 0:i.type}})]})})}function Ul(t,e){var n;return M(this,void 0,void 0,function(){var i;return T(this,function(o){return i=typeof e=="string"?{title:e}:e,[2,P({__tauriModule:"Dialog",message:{cmd:"askDialog",message:t.toString(),title:(n=i==null?void 0:i.title)===null||n===void 0?void 0:n.toString(),type:i==null?void 0:i.type}})]})})}function Pr(t,e){var n;return M(this,void 0,void 0,function(){var i;return T(this,function(o){return i=typeof e=="string"?{title:e}:e,[2,P({__tauriModule:"Dialog",message:{cmd:"confirmDialog",message:t.toString(),title:(n=i==null?void 0:i.title)===null||n===void 0?void 0:n.toString(),type:i==null?void 0:i.type}})]})})}Object.freeze({__proto__:null,open:Ii,save:Il,message:Ar,ask:Ul,confirm:Pr});var Pt;function Or(t,e){return e===void 0&&(e={}),M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"Fs",message:{cmd:"readTextFile",path:t,options:e}})]})})}function Ui(t,e){return e===void 0&&(e={}),M(this,void 0,void 0,function(){var n;return T(this,function(i){switch(i.label){case 0:return[4,P({__tauriModule:"Fs",message:{cmd:"readFile",path:t,options:e}})];case 1:return n=i.sent(),[2,Uint8Array.from(n)]}})})}function Wi(t,e,n){return M(this,void 0,void 0,function(){var i,o;return T(this,function(l){return typeof n=="object"&&Object.freeze(n),typeof t=="object"&&Object.freeze(t),i={path:"",contents:""},o=n,typeof t=="string"?i.path=t:(i.path=t.path,i.contents=t.contents),typeof e=="string"?i.contents=e!=null?e:"":o=e,[2,P({__tauriModule:"Fs",message:{cmd:"writeFile",path:i.path,contents:Array.from(new TextEncoder().encode(i.contents)),options:o}})]})})}function Er(t,e,n){return M(this,void 0,void 0,function(){var i,o;return T(this,function(l){return typeof n=="object"&&Object.freeze(n),typeof t=="object"&&Object.freeze(t),i={path:"",contents:[]},o=n,typeof t=="string"?i.path=t:(i.path=t.path,i.contents=t.contents),e&&"dir"in e?o=e:typeof t=="string"&&(i.contents=e!=null?e:[]),[2,P({__tauriModule:"Fs",message:{cmd:"writeFile",path:i.path,contents:Array.from(i.contents instanceof ArrayBuffer?new Uint8Array(i.contents):i.contents),options:o}})]})})}function Nl(t,e){return e===void 0&&(e={}),M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"Fs",message:{cmd:"readDir",path:t,options:e}})]})})}function Wr(t,e){return e===void 0&&(e={}),M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"Fs",message:{cmd:"createDir",path:t,options:e}})]})})}function Dr(t,e){return e===void 0&&(e={}),M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"Fs",message:{cmd:"removeDir",path:t,options:e}})]})})}function jr(t,e,n){return n===void 0&&(n={}),M(this,void 0,void 0,function(){return T(this,function(i){return[2,P({__tauriModule:"Fs",message:{cmd:"copyFile",source:t,destination:e,options:n}})]})})}function Rr(t,e){return e===void 0&&(e={}),M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"Fs",message:{cmd:"removeFile",path:t,options:e}})]})})}function Hr(t,e,n){return n===void 0&&(n={}),M(this,void 0,void 0,function(){return T(this,function(i){return[2,P({__tauriModule:"Fs",message:{cmd:"renameFile",oldPath:t,newPath:e,options:n}})]})})}(function(t){t[t.Audio=1]="Audio",t[t.Cache=2]="Cache",t[t.Config=3]="Config",t[t.Data=4]="Data",t[t.LocalData=5]="LocalData",t[t.Desktop=6]="Desktop",t[t.Document=7]="Document",t[t.Download=8]="Download",t[t.Executable=9]="Executable",t[t.Font=10]="Font",t[t.Home=11]="Home",t[t.Picture=12]="Picture",t[t.Public=13]="Public",t[t.Runtime=14]="Runtime",t[t.Template=15]="Template",t[t.Video=16]="Video",t[t.Resource=17]="Resource",t[t.App=18]="App",t[t.Log=19]="Log",t[t.Temp=20]="Temp"})(Pt||(Pt={}));Object.freeze({__proto__:null,get BaseDirectory(){return Pt},get Dir(){return Pt},readTextFile:Or,readBinaryFile:Ui,writeTextFile:Wi,writeFile:Wi,writeBinaryFile:Er,readDir:Nl,createDir:Wr,removeDir:Dr,copyFile:jr,removeFile:Rr,renameFile:Hr});function Fr(t){let e,n,i,o,l,u,f,c,p,d,k,_,y,g,b,L,W,U,j,q,A,S,z,D;return{c(){e=s("div"),n=s("input"),i=v(),o=s("input"),l=v(),u=s("br"),f=v(),c=s("div"),p=s("input"),d=v(),k=s("label"),k.textContent="Multiple",_=v(),y=s("div"),g=s("input"),b=v(),L=s("label"),L.textContent="Directory",W=v(),U=s("br"),j=v(),q=s("button"),q.textContent="Open dialog",A=v(),S=s("button"),S.textContent="Open save dialog",a(n,"class","input"),a(n,"id","dialog-default-path"),a(n,"placeholder","Default path"),a(o,"class","input"),a(o,"id","dialog-filter"),a(o,"placeholder","Extensions filter, comma-separated"),a(e,"class","flex gap-2 children:grow"),a(p,"type","checkbox"),a(p,"id","dialog-multiple"),a(k,"for","dialog-multiple"),a(g,"type","checkbox"),a(g,"id","dialog-directory"),a(L,"for","dialog-directory"),a(q,"class","btn"),a(q,"id","open-dialog"),a(S,"class","btn"),a(S,"id","save-dialog")},m(C,N){m(C,e,N),r(e,n),G(n,t[0]),r(e,i),r(e,o),G(o,t[1]),m(C,l,N),m(C,u,N),m(C,f,N),m(C,c,N),r(c,p),p.checked=t[2],r(c,d),r(c,k),m(C,_,N),m(C,y,N),r(y,g),g.checked=t[3],r(y,b),r(y,L),m(C,W,N),m(C,U,N),m(C,j,N),m(C,q,N),m(C,A,N),m(C,S,N),z||(D=[O(n,"input",t[8]),O(o,"input",t[9]),O(p,"change",t[10]),O(g,"change",t[11]),O(q,"click",t[4]),O(S,"click",t[5])],z=!0)},p(C,[N]){N&1&&n.value!==C[0]&&G(n,C[0]),N&2&&o.value!==C[1]&&G(o,C[1]),N&4&&(p.checked=C[2]),N&8&&(g.checked=C[3])},i:J,o:J,d(C){C&&h(e),C&&h(l),C&&h(u),C&&h(f),C&&h(c),C&&h(_),C&&h(y),C&&h(W),C&&h(U),C&&h(j),C&&h(q),C&&h(A),C&&h(S),z=!1,pe(D)}}}function Ir(t,e){var n=new Blob([t],{type:"application/octet-binary"}),i=new FileReader;i.onload=function(o){var l=o.target.result;e(l.substr(l.indexOf(",")+1))},i.readAsDataURL(n)}function Ur(t,e,n){let{onMessage:i}=e,{insecureRenderHtml:o}=e,l=null,u=null,f=!1,c=!1;function p(){Ii({title:"My wonderful open dialog",defaultPath:l,filters:u?[{name:"Tauri Example",extensions:u.split(",").map(b=>b.trim())}]:[],multiple:f,directory:c}).then(function(b){if(Array.isArray(b))i(b);else{var L=b,W=L.match(/\S+\.\S+$/g);Ui(L).then(function(U){W&&(L.includes(".png")||L.includes(".jpg"))?Ir(new Uint8Array(U),function(j){var q="data:image/png;base64,"+j;o('')}):i(b)}).catch(i(b))}}).catch(i)}function d(){Il({title:"My wonderful save dialog",defaultPath:l,filters:u?[{name:"Tauri Example",extensions:u.split(",").map(b=>b.trim())}]:[]}).then(i).catch(i)}function k(){l=this.value,n(0,l)}function _(){u=this.value,n(1,u)}function y(){f=this.checked,n(2,f)}function g(){c=this.checked,n(3,c)}return t.$$set=b=>{"onMessage"in b&&n(6,i=b.onMessage),"insecureRenderHtml"in b&&n(7,o=b.insecureRenderHtml)},[l,u,f,c,p,d,i,o,k,_,y,g]}class Nr extends Se{constructor(e){super(),Ce(this,e,Ur,Fr,ke,{onMessage:6,insecureRenderHtml:7})}}function qo(t,e,n){const i=t.slice();return i[9]=e[n],i}function Bo(t){let e,n=t[9][0]+"",i,o;return{c(){e=s("option"),i=E(n),e.__value=o=t[9][1],e.value=e.__value},m(l,u){m(l,e,u),r(e,i)},p:J,d(l){l&&h(e)}}}function qr(t){let e,n,i,o,l,u,f,c,p,d,k,_,y,g,b,L,W,U,j,q=t[2],A=[];for(let S=0;SisNaN(parseInt(_))).map(_=>[_,Pt[_]]);function c(){const _=l.match(/\S+\.\S+$/g),y={dir:Vo()};(_?Ui(l,y):Nl(l,y)).then(function(b){if(_)if(l.includes(".png")||l.includes(".jpg"))Br(new Uint8Array(b),function(L){const W="data:image/png;base64,"+L;o('')});else{const L=String.fromCharCode.apply(null,b);o(''),setTimeout(()=>{const W=document.getElementById("file-response");W.value=L,document.getElementById("file-save").addEventListener("click",function(){Wi(l,W.value,{dir:Vo()}).catch(i)})})}else i(b)}).catch(i)}function p(){n(1,u.src=wl(l),u)}function d(){l=this.value,n(0,l)}function k(_){Yn[_?"unshift":"push"](()=>{u=_,n(1,u)})}return t.$$set=_=>{"onMessage"in _&&n(5,i=_.onMessage),"insecureRenderHtml"in _&&n(6,o=_.insecureRenderHtml)},[l,u,f,c,p,i,o,d,k]}class Gr extends Se{constructor(e){super(),Ce(this,e,Vr,qr,ke,{onMessage:5,insecureRenderHtml:6})}}var Ot;(function(t){t[t.JSON=1]="JSON",t[t.Text=2]="Text",t[t.Binary=3]="Binary"})(Ot||(Ot={}));var Jn=function(){function t(e,n){this.type=e,this.payload=n}return t.form=function(e){var n={};for(var i in e){var o=e[i],l=void 0;l=typeof o=="string"?o:o instanceof Uint8Array||Array.isArray(o)?Array.from(o):typeof o.file=="string"?{file:o.file,mime:o.mime,fileName:o.fileName}:{file:Array.from(o.file),mime:o.mime,fileName:o.fileName},n[i]=l}return new t("Form",n)},t.json=function(e){return new t("Json",e)},t.text=function(e){return new t("Text",e)},t.bytes=function(e){return new t("Bytes",Array.from(e instanceof ArrayBuffer?new Uint8Array(e):e))},t}(),ql=function(t){this.url=t.url,this.status=t.status,this.ok=this.status>=200&&this.status<300,this.headers=t.headers,this.rawHeaders=t.rawHeaders,this.data=t.data},Bl=function(){function t(e){this.id=e}return t.prototype.drop=function(){return M(this,void 0,void 0,function(){return T(this,function(e){return[2,P({__tauriModule:"Http",message:{cmd:"dropClient",client:this.id}})]})})},t.prototype.request=function(e){return M(this,void 0,void 0,function(){var n;return T(this,function(i){return(n=!e.responseType||e.responseType===Ot.JSON)&&(e.responseType=Ot.Text),[2,P({__tauriModule:"Http",message:{cmd:"httpRequest",client:this.id,options:e}}).then(function(o){var l=new ql(o);if(n){try{l.data=JSON.parse(l.data)}catch(u){if(l.ok&&l.data==="")l.data={};else if(l.ok)throw Error("Failed to parse response `".concat(l.data,"` as JSON: ").concat(u,";\n try setting the `responseType` option to `ResponseType.Text` or `ResponseType.Binary` if the API does not return a JSON response."))}return l}return l})]})})},t.prototype.get=function(e,n){return M(this,void 0,void 0,function(){return T(this,function(i){return[2,this.request(ue({method:"GET",url:e},n))]})})},t.prototype.post=function(e,n,i){return M(this,void 0,void 0,function(){return T(this,function(o){return[2,this.request(ue({method:"POST",url:e,body:n},i))]})})},t.prototype.put=function(e,n,i){return M(this,void 0,void 0,function(){return T(this,function(o){return[2,this.request(ue({method:"PUT",url:e,body:n},i))]})})},t.prototype.patch=function(e,n){return M(this,void 0,void 0,function(){return T(this,function(i){return[2,this.request(ue({method:"PATCH",url:e},n))]})})},t.prototype.delete=function(e,n){return M(this,void 0,void 0,function(){return T(this,function(i){return[2,this.request(ue({method:"DELETE",url:e},n))]})})},t}();function Zn(t){return M(this,void 0,void 0,function(){return T(this,function(e){return[2,P({__tauriModule:"Http",message:{cmd:"createClient",options:t}}).then(function(n){return new Bl(n)})]})})}var Ai=null;function Jr(t,e){var n;return M(this,void 0,void 0,function(){return T(this,function(i){switch(i.label){case 0:return Ai!==null?[3,2]:[4,Zn()];case 1:Ai=i.sent(),i.label=2;case 2:return[2,Ai.request(ue({url:t,method:(n=e==null?void 0:e.method)!==null&&n!==void 0?n:"GET"},e))]}})})}Object.freeze({__proto__:null,getClient:Zn,fetch:Jr,Body:Jn,Client:Bl,Response:ql,get ResponseType(){return Ot}});function Go(t,e,n){const i=t.slice();return i[12]=e[n],i[14]=n,i}function Jo(t){let e,n,i,o,l,u,f,c,p,d,k,_,y,g,b,L,W,U=t[5],j=[];for(let z=0;zFe(j[z],1,1,()=>{j[z]=null});let A=!t[3]&&xo(),S=!t[3]&&t[8]&&Qo();return{c(){e=s("span"),n=s("span"),i=E(t[6]),o=v(),l=s("ul");for(let z=0;z{d[g]=null}),ti(),l=d[o],l?l.p(_,y):(l=d[o]=p[o](_),l.c()),Ee(l,1),l.m(e,u))},i(_){f||(Ee(l),f=!0)},o(_){Fe(l),f=!1},d(_){_&&h(e),c&&c.d(),d[o].d()}}}function xo(t){let e;return{c(){e=s("span"),e.textContent=",",a(e,"class","comma svelte-gbh3pt")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function Qo(t){let e;return{c(){e=s("span"),e.textContent=",",a(e,"class","comma svelte-gbh3pt")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function Kr(t){let e,n,i=t[5].length&&Jo(t);return{c(){i&&i.c(),e=$n()},m(o,l){i&&i.m(o,l),m(o,e,l),n=!0},p(o,[l]){o[5].length?i?(i.p(o,l),l&32&&Ee(i,1)):(i=Jo(o),i.c(),Ee(i,1),i.m(e.parentNode,e)):i&&(ei(),Fe(i,1,1,()=>{i=null}),ti())},i(o){n||(Ee(i),n=!0)},o(o){Fe(i),n=!1},d(o){i&&i.d(o),o&&h(e)}}}const xr="...";function Qr(t,e,n){let{json:i}=e,{depth:o=1/0}=e,{_lvl:l=0}=e,{_last:u=!0}=e;const f=b=>b===null?"null":typeof b;let c,p,d,k,_;const y=b=>{switch(f(b)){case"string":return`"${b}"`;case"function":return"f () {...}";case"symbol":return b.toString();default:return b}},g=()=>{n(8,_=!_)};return t.$$set=b=>{"json"in b&&n(0,i=b.json),"depth"in b&&n(1,o=b.depth),"_lvl"in b&&n(2,l=b._lvl),"_last"in b&&n(3,u=b._last)},t.$$.update=()=>{t.$$.dirty&17&&(n(5,c=f(i)==="object"?Object.keys(i):[]),n(4,p=Array.isArray(i)),n(6,d=p?"[":"{"),n(7,k=p?"]":"}")),t.$$.dirty&6&&n(8,_=ot[9].call(n)),a(k,"class","input h-auto w-100%"),a(k,"id","request-body"),a(k,"placeholder","Request body"),a(k,"rows","5"),a(b,"class","btn"),a(b,"id","make-request"),a(S,"class","input"),a(D,"class","input"),a(A,"class","flex gap-2 children:grow"),a($,"type","checkbox"),a(x,"class","btn"),a(x,"type","button")},m(R,V){m(R,e,V),r(e,n),r(n,i),r(n,o),r(n,l),r(n,u),r(n,f),zt(n,t[0]),r(e,c),r(e,p),r(e,d),r(e,k),G(k,t[1]),r(e,_),r(e,y),r(e,g),r(e,b),m(R,L,V),m(R,W,V),m(R,U,V),m(R,j,V),m(R,q,V),m(R,A,V),r(A,S),G(S,t[2]),r(A,z),r(A,D),G(D,t[3]),m(R,C,V),m(R,N,V),m(R,B,V),m(R,Y,V),r(Y,$),$.checked=t[5],r(Y,_e),m(R,te,V),m(R,oe,V),m(R,K,V),m(R,be,V),m(R,H,V),m(R,x,V),m(R,le,V),m(R,ae,V),m(R,ee,V),m(R,ve,V),m(R,re,V),Vt(ge,R,V),ne=!0,Me||(Le=[O(n,"change",t[9]),O(k,"input",t[10]),O(e,"submit",Xn(t[6])),O(S,"input",t[11]),O(D,"input",t[12]),O($,"change",t[13]),O(x,"click",t[7])],Me=!0)},p(R,[V]){V&1&&zt(n,R[0]),V&2&&G(k,R[1]),V&4&&S.value!==R[2]&&G(S,R[2]),V&8&&D.value!==R[3]&&G(D,R[3]),V&32&&($.checked=R[5]);const Re={};V&16&&(Re.json=R[4]),ge.$set(Re)},i(R){ne||(Ee(ge.$$.fragment,R),ne=!0)},o(R){Fe(ge.$$.fragment,R),ne=!1},d(R){R&&h(e),R&&h(L),R&&h(W),R&&h(U),R&&h(j),R&&h(q),R&&h(A),R&&h(C),R&&h(N),R&&h(B),R&&h(Y),R&&h(te),R&&h(oe),R&&h(K),R&&h(be),R&&h(H),R&&h(x),R&&h(le),R&&h(ae),R&&h(ee),R&&h(ve),R&&h(re),Gt(ge,R),Me=!1,pe(Le)}}}function $r(t,e,n){let i="GET",o="",{onMessage:l}=e;async function u(){const W=await Zn().catch(q=>{throw l(q),q}),j={url:"http://localhost:3003",method:i||"GET"||"GET"};o.startsWith("{")&&o.endsWith("}")||o.startsWith("[")&&o.endsWith("]")?j.body=Jn.json(JSON.parse(o)):o!==""&&(j.body=Jn.text(o)),W.request(j).then(l).catch(l)}let f="baz",c="qux",p=null,d=!0;async function k(){const W=await Zn().catch(U=>{throw l(U),U});n(4,p=await W.request({url:"http://localhost:3003",method:"POST",body:Jn.form({foo:f,bar:c}),headers:d?{"Content-Type":"multipart/form-data"}:void 0,responseType:Ot.Text}))}function _(){i=Pi(this),n(0,i)}function y(){o=this.value,n(1,o)}function g(){f=this.value,n(2,f)}function b(){c=this.value,n(3,c)}function L(){d=this.checked,n(5,d)}return t.$$set=W=>{"onMessage"in W&&n(8,l=W.onMessage)},[i,o,f,c,p,d,u,k,l,_,y,g,b,L]}class es extends Se{constructor(e){super(),Ce(this,e,$r,Zr,ke,{onMessage:8})}}function ts(t){let e,n,i;return{c(){e=s("button"),e.textContent="Send test notification",a(e,"class","btn"),a(e,"id","notification")},m(o,l){m(o,e,l),n||(i=O(e,"click",ns),n=!0)},p:J,i:J,o:J,d(o){o&&h(e),n=!1,i()}}}function ns(){new Notification("Notification title",{body:"This is the notification body"})}function is(t,e,n){let{onMessage:i}=e;return t.$$set=o=>{"onMessage"in o&&n(0,i=o.onMessage)},[i]}class os extends Se{constructor(e){super(),Ce(this,e,is,ts,ke,{onMessage:0})}}function Zo(t,e,n){const i=t.slice();return i[65]=e[n],i}function $o(t,e,n){const i=t.slice();return i[68]=e[n],i}function el(t){let e,n,i,o,l,u,f=Object.keys(t[1]),c=[];for(let p=0;pt[38].call(i))},m(p,d){m(p,e,d),m(p,n,d),m(p,i,d),r(i,o);for(let k=0;kupdate --background subcommand.`,n=v(),i=s("br"),o=v(),l=s("div"),l.textContent="Note that the arguments are only parsed, not implemented.",a=v(),f=s("br"),c=v(),p=s("br"),d=v(),w=s("button"),w.textContent="Get matches",u(l,"class","note"),u(w,"class","btn"),u(w,"id","cli-matches")},m(g,b){m(g,e,b),m(g,n,b),m(g,i,b),m(g,o,b),m(g,l,b),m(g,a,b),m(g,f,b),m(g,c,b),m(g,p,b),m(g,d,b),m(g,w,b),_||(y=O(w,"click",t[0]),_=!0)},p:J,i:J,o:J,d(g){g&&h(e),g&&h(n),g&&h(i),g&&h(o),g&&h(l),g&&h(a),g&&h(f),g&&h(c),g&&h(p),g&&h(d),g&&h(w),_=!1,y()}}}function Mr(t,e,n){let{onMessage:i}=e;function o(){Hl().then(i).catch(i)}return t.$$set=l=>{"onMessage"in l&&n(1,i=l.onMessage)},[o,i]}class Tr extends Se{constructor(e){super(),Ce(this,e,Mr,kr,ke,{onMessage:1})}}function Xt(t,e){return M(this,void 0,void 0,function(){return T(this,function(n){return[2,Hi(t,null,e)]})})}function Fl(t,e){return M(this,void 0,void 0,function(){return T(this,function(n){return[2,Sl(t,null,e)]})})}function ni(t,e){return M(this,void 0,void 0,function(){return T(this,function(n){return[2,Cl(t,void 0,e)]})})}Object.freeze({__proto__:null,listen:Xt,once:Fl,emit:ni});function Cr(t){let e,n,i,o,l,a,f,c;return{c(){e=s("div"),n=s("button"),n.textContent="Call Log API",i=v(),o=s("button"),o.textContent="Call Request (async) API",l=v(),a=s("button"),a.textContent="Send event to Rust",u(n,"class","btn"),u(n,"id","log"),u(o,"class","btn"),u(o,"id","request"),u(a,"class","btn"),u(a,"id","event")},m(p,d){m(p,e,d),r(e,n),r(e,i),r(e,o),r(e,l),r(e,a),f||(c=[O(n,"click",t[0]),O(o,"click",t[1]),O(a,"click",t[2])],f=!0)},p:J,i:J,o:J,d(p){p&&h(e),f=!1,pe(c)}}}function Sr(t,e,n){let{onMessage:i}=e,o;at(async()=>{o=await Xt("rust-event",i)}),Di(()=>{o&&o()});function l(){Qn("log_operation",{event:"tauri-click",payload:"this payload is optional because we used Option in Rust"})}function a(){Qn("perform_request",{endpoint:"dummy endpoint arg",body:{id:5,name:"test"}}).then(i).catch(i)}function f(){ni("js-event","this is the payload string")}return t.$$set=c=>{"onMessage"in c&&n(3,i=c.onMessage)},[l,a,f,i]}class zr extends Se{constructor(e){super(),Ce(this,e,Sr,Cr,ke,{onMessage:3})}}function Ii(t){return t===void 0&&(t={}),M(this,void 0,void 0,function(){return T(this,function(e){return typeof t=="object"&&Object.freeze(t),[2,P({__tauriModule:"Dialog",message:{cmd:"openDialog",options:t}})]})})}function Il(t){return t===void 0&&(t={}),M(this,void 0,void 0,function(){return T(this,function(e){return typeof t=="object"&&Object.freeze(t),[2,P({__tauriModule:"Dialog",message:{cmd:"saveDialog",options:t}})]})})}function Lr(t,e){var n;return M(this,void 0,void 0,function(){var i;return T(this,function(o){return i=typeof e=="string"?{title:e}:e,[2,P({__tauriModule:"Dialog",message:{cmd:"messageDialog",message:t.toString(),title:(n=i==null?void 0:i.title)===null||n===void 0?void 0:n.toString(),type:i==null?void 0:i.type}})]})})}function Ul(t,e){var n;return M(this,void 0,void 0,function(){var i;return T(this,function(o){return i=typeof e=="string"?{title:e}:e,[2,P({__tauriModule:"Dialog",message:{cmd:"askDialog",message:t.toString(),title:(n=i==null?void 0:i.title)===null||n===void 0?void 0:n.toString(),type:i==null?void 0:i.type}})]})})}function Ar(t,e){var n;return M(this,void 0,void 0,function(){var i;return T(this,function(o){return i=typeof e=="string"?{title:e}:e,[2,P({__tauriModule:"Dialog",message:{cmd:"confirmDialog",message:t.toString(),title:(n=i==null?void 0:i.title)===null||n===void 0?void 0:n.toString(),type:i==null?void 0:i.type}})]})})}Object.freeze({__proto__:null,open:Ii,save:Il,message:Lr,ask:Ul,confirm:Ar});var Pt;function Pr(t,e){return e===void 0&&(e={}),M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"Fs",message:{cmd:"readTextFile",path:t,options:e}})]})})}function Ui(t,e){return e===void 0&&(e={}),M(this,void 0,void 0,function(){var n;return T(this,function(i){switch(i.label){case 0:return[4,P({__tauriModule:"Fs",message:{cmd:"readFile",path:t,options:e}})];case 1:return n=i.sent(),[2,Uint8Array.from(n)]}})})}function Wi(t,e,n){return M(this,void 0,void 0,function(){var i,o;return T(this,function(l){return typeof n=="object"&&Object.freeze(n),typeof t=="object"&&Object.freeze(t),i={path:"",contents:""},o=n,typeof t=="string"?i.path=t:(i.path=t.path,i.contents=t.contents),typeof e=="string"?i.contents=e!=null?e:"":o=e,[2,P({__tauriModule:"Fs",message:{cmd:"writeFile",path:i.path,contents:Array.from(new TextEncoder().encode(i.contents)),options:o}})]})})}function Or(t,e,n){return M(this,void 0,void 0,function(){var i,o;return T(this,function(l){return typeof n=="object"&&Object.freeze(n),typeof t=="object"&&Object.freeze(t),i={path:"",contents:[]},o=n,typeof t=="string"?i.path=t:(i.path=t.path,i.contents=t.contents),e&&"dir"in e?o=e:typeof t=="string"&&(i.contents=e!=null?e:[]),[2,P({__tauriModule:"Fs",message:{cmd:"writeFile",path:i.path,contents:Array.from(i.contents instanceof ArrayBuffer?new Uint8Array(i.contents):i.contents),options:o}})]})})}function Nl(t,e){return e===void 0&&(e={}),M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"Fs",message:{cmd:"readDir",path:t,options:e}})]})})}function Er(t,e){return e===void 0&&(e={}),M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"Fs",message:{cmd:"createDir",path:t,options:e}})]})})}function Wr(t,e){return e===void 0&&(e={}),M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"Fs",message:{cmd:"removeDir",path:t,options:e}})]})})}function Dr(t,e,n){return n===void 0&&(n={}),M(this,void 0,void 0,function(){return T(this,function(i){return[2,P({__tauriModule:"Fs",message:{cmd:"copyFile",source:t,destination:e,options:n}})]})})}function jr(t,e){return e===void 0&&(e={}),M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"Fs",message:{cmd:"removeFile",path:t,options:e}})]})})}function Rr(t,e,n){return n===void 0&&(n={}),M(this,void 0,void 0,function(){return T(this,function(i){return[2,P({__tauriModule:"Fs",message:{cmd:"renameFile",oldPath:t,newPath:e,options:n}})]})})}(function(t){t[t.Audio=1]="Audio",t[t.Cache=2]="Cache",t[t.Config=3]="Config",t[t.Data=4]="Data",t[t.LocalData=5]="LocalData",t[t.Desktop=6]="Desktop",t[t.Document=7]="Document",t[t.Download=8]="Download",t[t.Executable=9]="Executable",t[t.Font=10]="Font",t[t.Home=11]="Home",t[t.Picture=12]="Picture",t[t.Public=13]="Public",t[t.Runtime=14]="Runtime",t[t.Template=15]="Template",t[t.Video=16]="Video",t[t.Resource=17]="Resource",t[t.App=18]="App",t[t.Log=19]="Log",t[t.Temp=20]="Temp"})(Pt||(Pt={}));Object.freeze({__proto__:null,get BaseDirectory(){return Pt},get Dir(){return Pt},readTextFile:Pr,readBinaryFile:Ui,writeTextFile:Wi,writeFile:Wi,writeBinaryFile:Or,readDir:Nl,createDir:Er,removeDir:Wr,copyFile:Dr,removeFile:jr,renameFile:Rr});function Hr(t){let e,n,i,o,l,a,f,c,p,d,w,_,y,g,b,L,W,U,j,q,A,S,z,D;return{c(){e=s("div"),n=s("input"),i=v(),o=s("input"),l=v(),a=s("br"),f=v(),c=s("div"),p=s("input"),d=v(),w=s("label"),w.textContent="Multiple",_=v(),y=s("div"),g=s("input"),b=v(),L=s("label"),L.textContent="Directory",W=v(),U=s("br"),j=v(),q=s("button"),q.textContent="Open dialog",A=v(),S=s("button"),S.textContent="Open save dialog",u(n,"class","input"),u(n,"id","dialog-default-path"),u(n,"placeholder","Default path"),u(o,"class","input"),u(o,"id","dialog-filter"),u(o,"placeholder","Extensions filter, comma-separated"),u(e,"class","flex gap-2 children:grow"),u(p,"type","checkbox"),u(p,"id","dialog-multiple"),u(w,"for","dialog-multiple"),u(g,"type","checkbox"),u(g,"id","dialog-directory"),u(L,"for","dialog-directory"),u(q,"class","btn"),u(q,"id","open-dialog"),u(S,"class","btn"),u(S,"id","save-dialog")},m(C,N){m(C,e,N),r(e,n),G(n,t[0]),r(e,i),r(e,o),G(o,t[1]),m(C,l,N),m(C,a,N),m(C,f,N),m(C,c,N),r(c,p),p.checked=t[2],r(c,d),r(c,w),m(C,_,N),m(C,y,N),r(y,g),g.checked=t[3],r(y,b),r(y,L),m(C,W,N),m(C,U,N),m(C,j,N),m(C,q,N),m(C,A,N),m(C,S,N),z||(D=[O(n,"input",t[8]),O(o,"input",t[9]),O(p,"change",t[10]),O(g,"change",t[11]),O(q,"click",t[4]),O(S,"click",t[5])],z=!0)},p(C,[N]){N&1&&n.value!==C[0]&&G(n,C[0]),N&2&&o.value!==C[1]&&G(o,C[1]),N&4&&(p.checked=C[2]),N&8&&(g.checked=C[3])},i:J,o:J,d(C){C&&h(e),C&&h(l),C&&h(a),C&&h(f),C&&h(c),C&&h(_),C&&h(y),C&&h(W),C&&h(U),C&&h(j),C&&h(q),C&&h(A),C&&h(S),z=!1,pe(D)}}}function Fr(t,e){var n=new Blob([t],{type:"application/octet-binary"}),i=new FileReader;i.onload=function(o){var l=o.target.result;e(l.substr(l.indexOf(",")+1))},i.readAsDataURL(n)}function Ir(t,e,n){let{onMessage:i}=e,{insecureRenderHtml:o}=e,l=null,a=null,f=!1,c=!1;function p(){Ii({title:"My wonderful open dialog",defaultPath:l,filters:a?[{name:"Tauri Example",extensions:a.split(",").map(b=>b.trim())}]:[],multiple:f,directory:c}).then(function(b){if(Array.isArray(b))i(b);else{var L=b,W=L.match(/\S+\.\S+$/g);Ui(L).then(function(U){W&&(L.includes(".png")||L.includes(".jpg"))?Fr(new Uint8Array(U),function(j){var q="data:image/png;base64,"+j;o('')}):i(b)}).catch(i(b))}}).catch(i)}function d(){Il({title:"My wonderful save dialog",defaultPath:l,filters:a?[{name:"Tauri Example",extensions:a.split(",").map(b=>b.trim())}]:[]}).then(i).catch(i)}function w(){l=this.value,n(0,l)}function _(){a=this.value,n(1,a)}function y(){f=this.checked,n(2,f)}function g(){c=this.checked,n(3,c)}return t.$$set=b=>{"onMessage"in b&&n(6,i=b.onMessage),"insecureRenderHtml"in b&&n(7,o=b.insecureRenderHtml)},[l,a,f,c,p,d,i,o,w,_,y,g]}class Ur extends Se{constructor(e){super(),Ce(this,e,Ir,Hr,ke,{onMessage:6,insecureRenderHtml:7})}}function qo(t,e,n){const i=t.slice();return i[9]=e[n],i}function Bo(t){let e,n=t[9][0]+"",i;return{c(){e=s("option"),i=E(n),e.__value=t[9][1],e.value=e.__value},m(o,l){m(o,e,l),r(e,i)},p:J,d(o){o&&h(e)}}}function Nr(t){let e,n,i,o,l,a,f,c,p,d,w,_,y,g,b,L,W,U,j,q=t[2],A=[];for(let S=0;SisNaN(parseInt(_))).map(_=>[_,Pt[_]]);function c(){const _=l.match(/\S+\.\S+$/g),y={dir:Vo()};(_?Ui(l,y):Nl(l,y)).then(function(b){if(_)if(l.includes(".png")||l.includes(".jpg"))qr(new Uint8Array(b),function(L){const W="data:image/png;base64,"+L;o('')});else{const L=String.fromCharCode.apply(null,b);o(''),setTimeout(()=>{const W=document.getElementById("file-response");W.value=L,document.getElementById("file-save").addEventListener("click",function(){Wi(l,W.value,{dir:Vo()}).catch(i)})})}else i(b)}).catch(i)}function p(){n(1,a.src=wl(l),a)}function d(){l=this.value,n(0,l)}function w(_){Yn[_?"unshift":"push"](()=>{a=_,n(1,a)})}return t.$$set=_=>{"onMessage"in _&&n(5,i=_.onMessage),"insecureRenderHtml"in _&&n(6,o=_.insecureRenderHtml)},[l,a,f,c,p,i,o,d,w]}class Vr extends Se{constructor(e){super(),Ce(this,e,Br,Nr,ke,{onMessage:5,insecureRenderHtml:6})}}var Ot;(function(t){t[t.JSON=1]="JSON",t[t.Text=2]="Text",t[t.Binary=3]="Binary"})(Ot||(Ot={}));var Jn=function(){function t(e,n){this.type=e,this.payload=n}return t.form=function(e){var n={};for(var i in e){var o=e[i],l=void 0;l=typeof o=="string"?o:o instanceof Uint8Array||Array.isArray(o)?Array.from(o):typeof o.file=="string"?{file:o.file,mime:o.mime,fileName:o.fileName}:{file:Array.from(o.file),mime:o.mime,fileName:o.fileName},n[i]=l}return new t("Form",n)},t.json=function(e){return new t("Json",e)},t.text=function(e){return new t("Text",e)},t.bytes=function(e){return new t("Bytes",Array.from(e instanceof ArrayBuffer?new Uint8Array(e):e))},t}(),ql=function(t){this.url=t.url,this.status=t.status,this.ok=this.status>=200&&this.status<300,this.headers=t.headers,this.rawHeaders=t.rawHeaders,this.data=t.data},Bl=function(){function t(e){this.id=e}return t.prototype.drop=function(){return M(this,void 0,void 0,function(){return T(this,function(e){return[2,P({__tauriModule:"Http",message:{cmd:"dropClient",client:this.id}})]})})},t.prototype.request=function(e){return M(this,void 0,void 0,function(){var n;return T(this,function(i){return(n=!e.responseType||e.responseType===Ot.JSON)&&(e.responseType=Ot.Text),[2,P({__tauriModule:"Http",message:{cmd:"httpRequest",client:this.id,options:e}}).then(function(o){var l=new ql(o);if(n){try{l.data=JSON.parse(l.data)}catch(a){if(l.ok&&l.data==="")l.data={};else if(l.ok)throw Error("Failed to parse response `".concat(l.data,"` as JSON: ").concat(a,";\n try setting the `responseType` option to `ResponseType.Text` or `ResponseType.Binary` if the API does not return a JSON response."))}return l}return l})]})})},t.prototype.get=function(e,n){return M(this,void 0,void 0,function(){return T(this,function(i){return[2,this.request(ue({method:"GET",url:e},n))]})})},t.prototype.post=function(e,n,i){return M(this,void 0,void 0,function(){return T(this,function(o){return[2,this.request(ue({method:"POST",url:e,body:n},i))]})})},t.prototype.put=function(e,n,i){return M(this,void 0,void 0,function(){return T(this,function(o){return[2,this.request(ue({method:"PUT",url:e,body:n},i))]})})},t.prototype.patch=function(e,n){return M(this,void 0,void 0,function(){return T(this,function(i){return[2,this.request(ue({method:"PATCH",url:e},n))]})})},t.prototype.delete=function(e,n){return M(this,void 0,void 0,function(){return T(this,function(i){return[2,this.request(ue({method:"DELETE",url:e},n))]})})},t}();function xn(t){return M(this,void 0,void 0,function(){return T(this,function(e){return[2,P({__tauriModule:"Http",message:{cmd:"createClient",options:t}}).then(function(n){return new Bl(n)})]})})}var Ai=null;function Gr(t,e){var n;return M(this,void 0,void 0,function(){return T(this,function(i){switch(i.label){case 0:return Ai!==null?[3,2]:[4,xn()];case 1:Ai=i.sent(),i.label=2;case 2:return[2,Ai.request(ue({url:t,method:(n=e==null?void 0:e.method)!==null&&n!==void 0?n:"GET"},e))]}})})}Object.freeze({__proto__:null,getClient:xn,fetch:Gr,Body:Jn,Client:Bl,Response:ql,get ResponseType(){return Ot}});function Go(t,e,n){const i=t.slice();return i[12]=e[n],i[14]=n,i}function Jo(t){let e,n,i,o,l,a,f,c,p,d,w,_,y,g,b,L,W,U=t[5],j=[];for(let z=0;zFe(j[z],1,1,()=>{j[z]=null});let A=!t[3]&&Qo(),S=!t[3]&&t[8]&&Zo();return{c(){e=s("span"),n=s("span"),i=E(t[6]),o=v(),l=s("ul");for(let z=0;z{d[g]=null}),ti(),l=d[o],l?l.p(_,y):(l=d[o]=p[o](_),l.c()),Ee(l,1),l.m(e,a))},i(_){f||(Ee(l),f=!0)},o(_){Fe(l),f=!1},d(_){_&&h(e),c&&c.d(),d[o].d()}}}function Qo(t){let e;return{c(){e=s("span"),e.textContent=",",u(e,"class","comma svelte-gbh3pt")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function Zo(t){let e;return{c(){e=s("span"),e.textContent=",",u(e,"class","comma svelte-gbh3pt")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function Yr(t){let e,n,i=t[5].length&&Jo(t);return{c(){i&&i.c(),e=$n()},m(o,l){i&&i.m(o,l),m(o,e,l),n=!0},p(o,[l]){o[5].length?i?(i.p(o,l),l&32&&Ee(i,1)):(i=Jo(o),i.c(),Ee(i,1),i.m(e.parentNode,e)):i&&(ei(),Fe(i,1,1,()=>{i=null}),ti())},i(o){n||(Ee(i),n=!0)},o(o){Fe(i),n=!1},d(o){i&&i.d(o),o&&h(e)}}}const Kr="...";function Qr(t,e,n){let{json:i}=e,{depth:o=1/0}=e,{_lvl:l=0}=e,{_last:a=!0}=e;const f=b=>b===null?"null":typeof b;let c,p,d,w,_;const y=b=>{switch(f(b)){case"string":return`"${b}"`;case"function":return"f () {...}";case"symbol":return b.toString();default:return b}},g=()=>{n(8,_=!_)};return t.$$set=b=>{"json"in b&&n(0,i=b.json),"depth"in b&&n(1,o=b.depth),"_lvl"in b&&n(2,l=b._lvl),"_last"in b&&n(3,a=b._last)},t.$$.update=()=>{t.$$.dirty&17&&(n(5,c=f(i)==="object"?Object.keys(i):[]),n(4,p=Array.isArray(i)),n(6,d=p?"[":"{"),n(7,w=p?"]":"}")),t.$$.dirty&6&&n(8,_=ot[9].call(n)),u(w,"class","input h-auto w-100%"),u(w,"id","request-body"),u(w,"placeholder","Request body"),u(w,"rows","5"),u(b,"class","btn"),u(b,"id","make-request"),u(S,"class","input"),u(D,"class","input"),u(A,"class","flex gap-2 children:grow"),u($,"type","checkbox"),u(Q,"class","btn"),u(Q,"type","button")},m(R,V){m(R,e,V),r(e,n),r(n,i),r(n,o),r(n,l),r(n,a),r(n,f),zt(n,t[0]),r(e,c),r(e,p),r(e,d),r(e,w),G(w,t[1]),r(e,_),r(e,y),r(e,g),r(e,b),m(R,L,V),m(R,W,V),m(R,U,V),m(R,j,V),m(R,q,V),m(R,A,V),r(A,S),G(S,t[2]),r(A,z),r(A,D),G(D,t[3]),m(R,C,V),m(R,N,V),m(R,B,V),m(R,Y,V),r(Y,$),$.checked=t[5],r(Y,_e),m(R,te,V),m(R,oe,V),m(R,K,V),m(R,be,V),m(R,H,V),m(R,Q,V),m(R,le,V),m(R,ae,V),m(R,ee,V),m(R,ve,V),m(R,re,V),Vt(ge,R,V),ne=!0,Me||(Le=[O(n,"change",t[9]),O(w,"input",t[10]),O(e,"submit",Xn(t[6])),O(S,"input",t[11]),O(D,"input",t[12]),O($,"change",t[13]),O(Q,"click",t[7])],Me=!0)},p(R,[V]){V&1&&zt(n,R[0]),V&2&&G(w,R[1]),V&4&&S.value!==R[2]&&G(S,R[2]),V&8&&D.value!==R[3]&&G(D,R[3]),V&32&&($.checked=R[5]);const Re={};V&16&&(Re.json=R[4]),ge.$set(Re)},i(R){ne||(Ee(ge.$$.fragment,R),ne=!0)},o(R){Fe(ge.$$.fragment,R),ne=!1},d(R){R&&h(e),R&&h(L),R&&h(W),R&&h(U),R&&h(j),R&&h(q),R&&h(A),R&&h(C),R&&h(N),R&&h(B),R&&h(Y),R&&h(te),R&&h(oe),R&&h(K),R&&h(be),R&&h(H),R&&h(Q),R&&h(le),R&&h(ae),R&&h(ee),R&&h(ve),R&&h(re),Gt(ge,R),Me=!1,pe(Le)}}}function xr(t,e,n){let i="GET",o="",{onMessage:l}=e;async function a(){const W=await xn().catch(q=>{throw l(q),q}),j={url:"http://localhost:3003",method:i||"GET"||"GET"};o.startsWith("{")&&o.endsWith("}")||o.startsWith("[")&&o.endsWith("]")?j.body=Jn.json(JSON.parse(o)):o!==""&&(j.body=Jn.text(o)),W.request(j).then(l).catch(l)}let f="baz",c="qux",p=null,d=!0;async function w(){const W=await xn().catch(U=>{throw l(U),U});n(4,p=await W.request({url:"http://localhost:3003",method:"POST",body:Jn.form({foo:f,bar:c}),headers:d?{"Content-Type":"multipart/form-data"}:void 0,responseType:Ot.Text}))}function _(){i=Pi(this),n(0,i)}function y(){o=this.value,n(1,o)}function g(){f=this.value,n(2,f)}function b(){c=this.value,n(3,c)}function L(){d=this.checked,n(5,d)}return t.$$set=W=>{"onMessage"in W&&n(8,l=W.onMessage)},[i,o,f,c,p,d,a,w,l,_,y,g,b,L]}class $r extends Se{constructor(e){super(),Ce(this,e,xr,Zr,ke,{onMessage:8})}}function es(t){let e,n,i;return{c(){e=s("button"),e.textContent="Send test notification",u(e,"class","btn"),u(e,"id","notification")},m(o,l){m(o,e,l),n||(i=O(e,"click",ts),n=!0)},p:J,i:J,o:J,d(o){o&&h(e),n=!1,i()}}}function ts(){new Notification("Notification title",{body:"This is the notification body"})}function ns(t,e,n){let{onMessage:i}=e;return t.$$set=o=>{"onMessage"in o&&n(0,i=o.onMessage)},[i]}class is extends Se{constructor(e){super(),Ce(this,e,ns,es,ke,{onMessage:0})}}function xo(t,e,n){const i=t.slice();return i[65]=e[n],i}function $o(t,e,n){const i=t.slice();return i[68]=e[n],i}function el(t){let e,n,i,o,l,a,f=Object.keys(t[1]),c=[];for(let p=0;pt[38].call(i))},m(p,d){m(p,e,d),m(p,n,d),m(p,i,d),r(i,o);for(let w=0;wt[55].call(Ne)),a(Qe,"class","input"),a(Qe,"type","number"),a(Ze,"class","input"),a(Ze,"type","number"),a(Ue,"class","flex gap-2"),a($e,"class","input grow"),a($e,"id","title"),a(Ft,"class","btn"),a(Ft,"type","submit"),a(st,"class","flex gap-1"),a(et,"class","input grow"),a(et,"id","url"),a(It,"class","btn"),a(It,"id","open-url"),a(ut,"class","flex gap-1"),a(rt,"class","flex flex-col gap-1")},m(w,I){m(w,e,I),m(w,n,I),m(w,i,I),r(i,o),r(i,l),r(i,u),r(i,f),r(i,c),r(i,p),r(i,d),r(i,k),r(i,_),m(w,y,I),m(w,g,I),m(w,b,I),m(w,L,I),r(L,W),r(W,U),r(W,j),j.checked=t[3],r(L,q),r(L,A),r(A,S),r(A,z),z.checked=t[2],r(L,D),r(L,C),r(C,N),r(C,B),B.checked=t[4],r(L,Y),r(L,$),r($,_e),r($,te),te.checked=t[5],r(L,oe),r(L,K),r(K,be),r(K,H),H.checked=t[6],m(w,x,I),m(w,le,I),m(w,ae,I),m(w,ee,I),r(ee,ve),r(ve,re),r(re,ge),r(re,ne),G(ne,t[13]),r(ve,Me),r(ve,Le),r(Le,R),r(Le,V),G(V,t[14]),r(ee,Re),r(ee,Ae),r(Ae,Te),r(Te,ce),r(Te,he),G(he,t[7]),r(Ae,fe),r(Ae,Pe),r(Pe,tt),r(Pe,me),G(me,t[8]),r(ee,de),r(ee,F),r(F,ie),r(ie,X),r(ie,ye),G(ye,t[9]),r(F,Yt),r(F,ht),r(ht,Kt),r(ht,He),G(He,t[10]),r(ee,xt),r(ee,Be),r(Be,Q),r(Q,Et),r(Q,We),G(We,t[11]),r(Be,Wt),r(Be,nt),r(nt,Dt),r(nt,De),G(De,t[12]),m(w,mt,I),m(w,vt,I),m(w,_t,I),m(w,Oe,I),r(Oe,Ie),r(Ie,je),r(je,it),r(je,jt),r(je,ot),r(ot,Rt),r(ot,ii),r(je,qi),r(je,Qt),r(Qt,Bi),r(Qt,oi),r(Ie,Vi),r(Ie,Ve),r(Ve,$t),r(Ve,Gi),r(Ve,en),r(en,Ji),r(en,li),r(Ve,Xi),r(Ve,nn),r(nn,Yi),r(nn,ri),r(Oe,Ki),r(Oe,gt),r(gt,Ge),r(Ge,ln),r(Ge,xi),r(Ge,rn),r(rn,Qi),r(rn,si),r(Ge,Zi),r(Ge,un),r(un,$i),r(un,ui),r(gt,eo),r(gt,Je),r(Je,cn),r(Je,to),r(Je,fn),r(fn,no),r(fn,ai),r(Je,io),r(Je,pn),r(pn,oo),r(pn,ci),r(Oe,lo),r(Oe,yt),r(yt,Xe),r(Xe,mn),r(Xe,ro),r(Xe,vn),r(vn,so),r(vn,fi),r(Xe,uo),r(Xe,bn),r(bn,ao),r(bn,di),r(yt,co),r(yt,Ye),r(Ye,yn),r(Ye,fo),r(Ye,wn),r(wn,po),r(wn,pi),r(Ye,ho),r(Ye,Mn),r(Mn,mo),r(Mn,hi),r(Oe,vo),r(Oe,wt),r(wt,Ke),r(Ke,Cn),r(Ke,_o),r(Ke,Sn),r(Sn,bo),r(Sn,mi),r(Ke,go),r(Ke,Ln),r(Ln,yo),r(Ln,vi),r(wt,wo),r(wt,xe),r(xe,Pn),r(xe,ko),r(xe,On),r(On,Mo),r(On,_i),r(xe,To),r(xe,Wn),r(Wn,Co),r(Wn,bi),m(w,gi,I),m(w,yi,I),m(w,wi,I),m(w,Ht,I),m(w,ki,I),m(w,lt,I),r(lt,jn),r(jn,kt),kt.checked=t[15],r(jn,So),r(lt,zo),r(lt,Rn),r(Rn,Mt),Mt.checked=t[16],r(Rn,Lo),m(w,Mi,I),m(w,Ue,I),r(Ue,Hn),r(Hn,Ao),r(Hn,Ne);for(let we=0;we=1,d,k,_,y=p&&el(t),g=t[1][t[0]]&&nl(t);return{c(){e=s("div"),n=s("div"),i=s("input"),o=v(),l=s("button"),l.textContent="New window",u=v(),f=s("br"),c=v(),y&&y.c(),d=v(),g&&g.c(),a(i,"class","input grow"),a(i,"type","text"),a(i,"placeholder","New Window label.."),a(l,"class","btn"),a(n,"class","flex gap-1"),a(e,"class","flex flex-col children:grow gap-2")},m(b,L){m(b,e,L),r(e,n),r(n,i),G(i,t[20]),r(n,o),r(n,l),r(e,u),r(e,f),r(e,c),y&&y.m(e,null),r(e,d),g&&g.m(e,null),k||(_=[O(i,"input",t[37]),O(l,"click",t[34])],k=!0)},p(b,L){L[0]&1048576&&i.value!==b[20]&&G(i,b[20]),L[0]&2&&(p=Object.keys(b[1]).length>=1),p?y?y.p(b,L):(y=el(b),y.c(),y.m(e,d)):y&&(y.d(1),y=null),b[1][b[0]]?g?g.p(b,L):(g=nl(b),g.c(),g.m(e,null)):g&&(g.d(1),g=null)},i:J,o:J,d(b){b&&h(e),y&&y.d(),g&&g.d(),k=!1,pe(_)}}}function rs(t,e,n){let i=qe.label;const o={[qe.label]:qe},l=["default","crosshair","hand","arrow","move","text","wait","help","progress","notAllowed","contextMenu","cell","verticalText","alias","copy","noDrop","grab","grabbing","allScroll","zoomIn","zoomOut","eResize","nResize","neResize","nwResize","sResize","seResize","swResize","wResize","ewResize","nsResize","neswResize","nwseResize","colResize","rowResize"];let{onMessage:u}=e,f,c="https://tauri.app",p=!0,d=!1,k=!0,_=!1,y=!1,g=null,b=null,L=null,W=null,U=null,j=null,q=null,A=null,S=1,z=new ft(q,A),D=new ft(q,A),C=new St(g,b),N=new St(g,b),B,Y,$=!1,_e=!0,te=null,oe=null,K="default",be="Awesome Tauri Example!";function H(){Ri(c)}function x(){o[i].setTitle(be)}function le(){o[i].hide(),setTimeout(o[i].show,2e3)}function ae(){o[i].minimize(),setTimeout(o[i].unminimize,2e3)}function ee(){Ii({multiple:!1}).then(Q=>{typeof Q=="string"&&o[i].setIcon(Q)})}function ve(){if(!f)return;const Q=new At(f);n(1,o[f]=Q,o),Q.once("tauri://error",function(){u("Error creating new webview")})}function re(){o[i].innerSize().then(Q=>{n(25,C=Q),n(7,g=C.width),n(8,b=C.height)}),o[i].outerSize().then(Q=>{n(26,N=Q)})}function ge(){o[i].innerPosition().then(Q=>{n(23,z=Q)}),o[i].outerPosition().then(Q=>{n(24,D=Q),n(13,q=D.x),n(14,A=D.y)})}async function ne(Q){!Q||(B&&B(),Y&&Y(),Y=await Q.listen("tauri://move",ge),B=await Q.listen("tauri://resize",re))}async function Me(){await o[i].minimize(),await o[i].requestUserAttention(Jt.Critical),await new Promise(Q=>setTimeout(Q,3e3)),await o[i].requestUserAttention(null)}function Le(){f=this.value,n(20,f)}function R(){i=Pi(this),n(0,i),n(1,o)}const V=()=>o[i].center();function Re(){d=this.checked,n(3,d)}function Ae(){p=this.checked,n(2,p)}function Te(){k=this.checked,n(4,k)}function ce(){_=this.checked,n(5,_)}function he(){y=this.checked,n(6,y)}function fe(){q=se(this.value),n(13,q)}function Pe(){A=se(this.value),n(14,A)}function tt(){g=se(this.value),n(7,g)}function me(){b=se(this.value),n(8,b)}function de(){L=se(this.value),n(9,L)}function F(){W=se(this.value),n(10,W)}function ie(){U=se(this.value),n(11,U)}function X(){j=se(this.value),n(12,j)}function ye(){$=this.checked,n(15,$)}function Yt(){_e=this.checked,n(16,_e)}function ht(){K=Pi(this),n(19,K),n(28,l)}function Kt(){te=se(this.value),n(17,te)}function He(){oe=se(this.value),n(18,oe)}function xt(){be=this.value,n(27,be)}function Be(){c=this.value,n(21,c)}return t.$$set=Q=>{"onMessage"in Q&&n(36,u=Q.onMessage)},t.$$.update=()=>{var Q,Et,We,Wt,nt,Dt,De,mt,vt,_t,Oe,Ie,je,it,jt,ot,Rt;t.$$.dirty[0]&3&&(o[i],ge(),re()),t.$$.dirty[0]&7&&((Q=o[i])==null||Q.setResizable(p)),t.$$.dirty[0]&11&&(d?(Et=o[i])==null||Et.maximize():(We=o[i])==null||We.unmaximize()),t.$$.dirty[0]&19&&((Wt=o[i])==null||Wt.setDecorations(k)),t.$$.dirty[0]&35&&((nt=o[i])==null||nt.setAlwaysOnTop(_)),t.$$.dirty[0]&67&&((Dt=o[i])==null||Dt.setFullscreen(y)),t.$$.dirty[0]&387&&g&&b&&((De=o[i])==null||De.setSize(new St(g,b))),t.$$.dirty[0]&1539&&(L&&W?(mt=o[i])==null||mt.setMinSize(new Qn(L,W)):(vt=o[i])==null||vt.setMinSize(null)),t.$$.dirty[0]&6147&&(U>800&&j>400?(_t=o[i])==null||_t.setMaxSize(new Qn(U,j)):(Oe=o[i])==null||Oe.setMaxSize(null)),t.$$.dirty[0]&24579&&q!==null&&A!==null&&((Ie=o[i])==null||Ie.setPosition(new ft(q,A))),t.$$.dirty[0]&3&&((je=o[i])==null||je.scaleFactor().then(bt=>n(22,S=bt))),t.$$.dirty[0]&3&&ne(o[i]),t.$$.dirty[0]&32771&&((it=o[i])==null||it.setCursorGrab($)),t.$$.dirty[0]&65539&&((jt=o[i])==null||jt.setCursorVisible(_e)),t.$$.dirty[0]&524291&&((ot=o[i])==null||ot.setCursorIcon(K)),t.$$.dirty[0]&393219&&te!==null&&oe!==null&&((Rt=o[i])==null||Rt.setCursorPosition(new ft(te,oe)))},[i,o,p,d,k,_,y,g,b,L,W,U,j,q,A,$,_e,te,oe,K,f,c,S,z,D,C,N,be,l,H,x,le,ae,ee,ve,Me,u,Le,R,V,Re,Ae,Te,ce,he,fe,Pe,tt,me,de,F,ie,X,ye,Yt,ht,Kt,He,xt,Be]}class ss extends Se{constructor(e){super(),Ce(this,e,rs,ls,ke,{onMessage:36},null,[-1,-1,-1])}}function Gl(t,e){return M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"GlobalShortcut",message:{cmd:"register",shortcut:t,handler:pt(e)}})]})})}function us(t,e){return M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"GlobalShortcut",message:{cmd:"registerAll",shortcuts:t,handler:pt(e)}})]})})}function as(t){return M(this,void 0,void 0,function(){return T(this,function(e){return[2,P({__tauriModule:"GlobalShortcut",message:{cmd:"isRegistered",shortcut:t}})]})})}function Jl(t){return M(this,void 0,void 0,function(){return T(this,function(e){return[2,P({__tauriModule:"GlobalShortcut",message:{cmd:"unregister",shortcut:t}})]})})}function Xl(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"GlobalShortcut",message:{cmd:"unregisterAll"}})]})})}Object.freeze({__proto__:null,register:Gl,registerAll:us,isRegistered:as,unregister:Jl,unregisterAll:Xl});function ol(t,e,n){const i=t.slice();return i[9]=e[n],i}function ll(t){let e,n=t[9]+"",i,o,l,u,f;function c(){return t[8](t[9])}return{c(){e=s("div"),i=E(n),o=v(),l=s("button"),l.textContent="Unregister",a(l,"class","btn"),a(l,"type","button"),a(e,"class","flex justify-between")},m(p,d){m(p,e,d),r(e,i),r(e,o),r(e,l),u||(f=O(l,"click",c),u=!0)},p(p,d){t=p,d&2&&n!==(n=t[9]+"")&&Z(i,n)},d(p){p&&h(e),u=!1,f()}}}function rl(t){let e,n,i,o,l;return{c(){e=s("br"),n=v(),i=s("button"),i.textContent="Unregister all",a(i,"class","btn"),a(i,"type","button")},m(u,f){m(u,e,f),m(u,n,f),m(u,i,f),o||(l=O(i,"click",t[5]),o=!0)},p:J,d(u){u&&h(e),u&&h(n),u&&h(i),o=!1,l()}}}function cs(t){let e,n,i,o,l,u,f,c,p,d,k,_=t[1],y=[];for(let b=0;b<_.length;b+=1)y[b]=ll(ol(t,_,b));let g=t[1].length>1&&rl(t);return{c(){e=s("div"),n=s("input"),i=v(),o=s("button"),o.textContent="Register",l=v(),u=s("br"),f=v(),c=s("div");for(let b=0;b1?g?g.p(b,L):(g=rl(b),g.c(),g.m(c,null)):g&&(g.d(1),g=null)},i:J,o:J,d(b){b&&h(e),b&&h(l),b&&h(u),b&&h(f),b&&h(c),dt(y,b),g&&g.d(),d=!1,pe(k)}}}function fs(t,e,n){let i,{onMessage:o}=e;const l=yl([]);_l(t,l,_=>n(1,i=_));let u="CmdOrControl+X";function f(){const _=u;Gl(_,()=>{o(`Shortcut ${_} triggered`)}).then(()=>{l.update(y=>[...y,_]),o(`Shortcut ${_} registered successfully`)}).catch(o)}function c(_){const y=_;Jl(y).then(()=>{l.update(g=>g.filter(b=>b!==y)),o(`Shortcut ${y} unregistered`)}).catch(o)}function p(){Xl().then(()=>{l.update(()=>[]),o("Unregistered all shortcuts")}).catch(o)}function d(){u=this.value,n(0,u)}const k=_=>c(_);return t.$$set=_=>{"onMessage"in _&&n(6,o=_.onMessage)},[u,i,l,f,c,p,o,d,k]}class ds extends Se{constructor(e){super(),Ce(this,e,fs,cs,ke,{onMessage:6})}}function sl(t){let e,n,i,o,l,u,f;return{c(){e=s("br"),n=v(),i=s("input"),o=v(),l=s("button"),l.textContent="Write",a(i,"class","input"),a(i,"placeholder","write to stdin"),a(l,"class","btn")},m(c,p){m(c,e,p),m(c,n,p),m(c,i,p),G(i,t[4]),m(c,o,p),m(c,l,p),u||(f=[O(i,"input",t[14]),O(l,"click",t[8])],u=!0)},p(c,p){p&16&&i.value!==c[4]&&G(i,c[4])},d(c){c&&h(e),c&&h(n),c&&h(i),c&&h(o),c&&h(l),u=!1,pe(f)}}}function ps(t){let e,n,i,o,l,u,f,c,p,d,k,_,y,g,b,L,W,U,j,q,A,S,z,D,C=t[5]&&sl(t);return{c(){e=s("div"),n=s("div"),i=E(`Script: - `),o=s("input"),l=v(),u=s("div"),f=E(`Encoding: - `),c=s("input"),p=v(),d=s("div"),k=E(`Working directory: + `),Ne=s("select");for(let k=0;kt[55].call(Ne)),u(Ze,"class","input"),u(Ze,"type","number"),u(xe,"class","input"),u(xe,"type","number"),u(Ue,"class","flex gap-2"),u($e,"class","input grow"),u($e,"id","title"),u(Ft,"class","btn"),u(Ft,"type","submit"),u(st,"class","flex gap-1"),u(et,"class","input grow"),u(et,"id","url"),u(It,"class","btn"),u(It,"id","open-url"),u(ut,"class","flex gap-1"),u(rt,"class","flex flex-col gap-1")},m(k,I){m(k,e,I),m(k,n,I),m(k,i,I),r(i,o),r(i,l),r(i,a),r(i,f),r(i,c),r(i,p),r(i,d),r(i,w),r(i,_),m(k,y,I),m(k,g,I),m(k,b,I),m(k,L,I),r(L,W),r(W,U),r(W,j),j.checked=t[3],r(L,q),r(L,A),r(A,S),r(A,z),z.checked=t[2],r(L,D),r(L,C),r(C,N),r(C,B),B.checked=t[4],r(L,Y),r(L,$),r($,_e),r($,te),te.checked=t[5],r(L,oe),r(L,K),r(K,be),r(K,H),H.checked=t[6],m(k,Q,I),m(k,le,I),m(k,ae,I),m(k,ee,I),r(ee,ve),r(ve,re),r(re,ge),r(re,ne),G(ne,t[13]),r(ve,Me),r(ve,Le),r(Le,R),r(Le,V),G(V,t[14]),r(ee,Re),r(ee,Ae),r(Ae,Te),r(Te,ce),r(Te,he),G(he,t[7]),r(Ae,fe),r(Ae,Pe),r(Pe,tt),r(Pe,me),G(me,t[8]),r(ee,de),r(ee,F),r(F,ie),r(ie,X),r(ie,ye),G(ye,t[9]),r(F,Yt),r(F,ht),r(ht,Kt),r(ht,He),G(He,t[10]),r(ee,Qt),r(ee,Be),r(Be,Z),r(Z,Et),r(Z,We),G(We,t[11]),r(Be,Wt),r(Be,nt),r(nt,Dt),r(nt,De),G(De,t[12]),m(k,mt,I),m(k,vt,I),m(k,_t,I),m(k,Oe,I),r(Oe,Ie),r(Ie,je),r(je,it),r(je,jt),r(je,ot),r(ot,Rt),r(ot,ii),r(je,qi),r(je,Zt),r(Zt,Bi),r(Zt,oi),r(Ie,Vi),r(Ie,Ve),r(Ve,$t),r(Ve,Gi),r(Ve,en),r(en,Ji),r(en,li),r(Ve,Xi),r(Ve,nn),r(nn,Yi),r(nn,ri),r(Oe,Ki),r(Oe,gt),r(gt,Ge),r(Ge,ln),r(Ge,Qi),r(Ge,rn),r(rn,Zi),r(rn,si),r(Ge,xi),r(Ge,un),r(un,$i),r(un,ui),r(gt,eo),r(gt,Je),r(Je,cn),r(Je,to),r(Je,fn),r(fn,no),r(fn,ai),r(Je,io),r(Je,pn),r(pn,oo),r(pn,ci),r(Oe,lo),r(Oe,yt),r(yt,Xe),r(Xe,mn),r(Xe,ro),r(Xe,vn),r(vn,so),r(vn,fi),r(Xe,uo),r(Xe,bn),r(bn,ao),r(bn,di),r(yt,co),r(yt,Ye),r(Ye,yn),r(Ye,fo),r(Ye,wn),r(wn,po),r(wn,pi),r(Ye,ho),r(Ye,Mn),r(Mn,mo),r(Mn,hi),r(Oe,vo),r(Oe,wt),r(wt,Ke),r(Ke,Cn),r(Ke,_o),r(Ke,Sn),r(Sn,bo),r(Sn,mi),r(Ke,go),r(Ke,Ln),r(Ln,yo),r(Ln,vi),r(wt,wo),r(wt,Qe),r(Qe,Pn),r(Qe,ko),r(Qe,On),r(On,Mo),r(On,_i),r(Qe,To),r(Qe,Wn),r(Wn,Co),r(Wn,bi),m(k,gi,I),m(k,yi,I),m(k,wi,I),m(k,Ht,I),m(k,ki,I),m(k,lt,I),r(lt,jn),r(jn,kt),kt.checked=t[15],r(jn,So),r(lt,zo),r(lt,Rn),r(Rn,Mt),Mt.checked=t[16],r(Rn,Lo),m(k,Mi,I),m(k,Ue,I),r(Ue,Hn),r(Hn,Ao),r(Hn,Ne);for(let we=0;we=1,d,w,_,y=p&&el(t),g=t[1][t[0]]&&nl(t);return{c(){e=s("div"),n=s("div"),i=s("input"),o=v(),l=s("button"),l.textContent="New window",a=v(),f=s("br"),c=v(),y&&y.c(),d=v(),g&&g.c(),u(i,"class","input grow"),u(i,"type","text"),u(i,"placeholder","New Window label.."),u(l,"class","btn"),u(n,"class","flex gap-1"),u(e,"class","flex flex-col children:grow gap-2")},m(b,L){m(b,e,L),r(e,n),r(n,i),G(i,t[20]),r(n,o),r(n,l),r(e,a),r(e,f),r(e,c),y&&y.m(e,null),r(e,d),g&&g.m(e,null),w||(_=[O(i,"input",t[37]),O(l,"click",t[34])],w=!0)},p(b,L){L[0]&1048576&&i.value!==b[20]&&G(i,b[20]),L[0]&2&&(p=Object.keys(b[1]).length>=1),p?y?y.p(b,L):(y=el(b),y.c(),y.m(e,d)):y&&(y.d(1),y=null),b[1][b[0]]?g?g.p(b,L):(g=nl(b),g.c(),g.m(e,null)):g&&(g.d(1),g=null)},i:J,o:J,d(b){b&&h(e),y&&y.d(),g&&g.d(),w=!1,pe(_)}}}function ls(t,e,n){let i=qe.label;const o={[qe.label]:qe},l=["default","crosshair","hand","arrow","move","text","wait","help","progress","notAllowed","contextMenu","cell","verticalText","alias","copy","noDrop","grab","grabbing","allScroll","zoomIn","zoomOut","eResize","nResize","neResize","nwResize","sResize","seResize","swResize","wResize","ewResize","nsResize","neswResize","nwseResize","colResize","rowResize"];let{onMessage:a}=e,f,c="https://tauri.app",p=!0,d=!1,w=!0,_=!1,y=!1,g=null,b=null,L=null,W=null,U=null,j=null,q=null,A=null,S=1,z=new ft(q,A),D=new ft(q,A),C=new St(g,b),N=new St(g,b),B,Y,$=!1,_e=!0,te=null,oe=null,K="default",be="Awesome Tauri Example!";function H(){Ri(c)}function Q(){o[i].setTitle(be)}function le(){o[i].hide(),setTimeout(o[i].show,2e3)}function ae(){o[i].minimize(),setTimeout(o[i].unminimize,2e3)}function ee(){Ii({multiple:!1}).then(Z=>{typeof Z=="string"&&o[i].setIcon(Z)})}function ve(){if(!f)return;const Z=new At(f);n(1,o[f]=Z,o),Z.once("tauri://error",function(){a("Error creating new webview")})}function re(){o[i].innerSize().then(Z=>{n(25,C=Z),n(7,g=C.width),n(8,b=C.height)}),o[i].outerSize().then(Z=>{n(26,N=Z)})}function ge(){o[i].innerPosition().then(Z=>{n(23,z=Z)}),o[i].outerPosition().then(Z=>{n(24,D=Z),n(13,q=D.x),n(14,A=D.y)})}async function ne(Z){!Z||(B&&B(),Y&&Y(),Y=await Z.listen("tauri://move",ge),B=await Z.listen("tauri://resize",re))}async function Me(){await o[i].minimize(),await o[i].requestUserAttention(Jt.Critical),await new Promise(Z=>setTimeout(Z,3e3)),await o[i].requestUserAttention(null)}function Le(){f=this.value,n(20,f)}function R(){i=Pi(this),n(0,i),n(1,o)}const V=()=>o[i].center();function Re(){d=this.checked,n(3,d)}function Ae(){p=this.checked,n(2,p)}function Te(){w=this.checked,n(4,w)}function ce(){_=this.checked,n(5,_)}function he(){y=this.checked,n(6,y)}function fe(){q=se(this.value),n(13,q)}function Pe(){A=se(this.value),n(14,A)}function tt(){g=se(this.value),n(7,g)}function me(){b=se(this.value),n(8,b)}function de(){L=se(this.value),n(9,L)}function F(){W=se(this.value),n(10,W)}function ie(){U=se(this.value),n(11,U)}function X(){j=se(this.value),n(12,j)}function ye(){$=this.checked,n(15,$)}function Yt(){_e=this.checked,n(16,_e)}function ht(){K=Pi(this),n(19,K),n(28,l)}function Kt(){te=se(this.value),n(17,te)}function He(){oe=se(this.value),n(18,oe)}function Qt(){be=this.value,n(27,be)}function Be(){c=this.value,n(21,c)}return t.$$set=Z=>{"onMessage"in Z&&n(36,a=Z.onMessage)},t.$$.update=()=>{var Z,Et,We,Wt,nt,Dt,De,mt,vt,_t,Oe,Ie,je,it,jt,ot,Rt;t.$$.dirty[0]&3&&(o[i],ge(),re()),t.$$.dirty[0]&7&&((Z=o[i])==null||Z.setResizable(p)),t.$$.dirty[0]&11&&(d?(Et=o[i])==null||Et.maximize():(We=o[i])==null||We.unmaximize()),t.$$.dirty[0]&19&&((Wt=o[i])==null||Wt.setDecorations(w)),t.$$.dirty[0]&35&&((nt=o[i])==null||nt.setAlwaysOnTop(_)),t.$$.dirty[0]&67&&((Dt=o[i])==null||Dt.setFullscreen(y)),t.$$.dirty[0]&387&&g&&b&&((De=o[i])==null||De.setSize(new St(g,b))),t.$$.dirty[0]&1539&&(L&&W?(mt=o[i])==null||mt.setMinSize(new Zn(L,W)):(vt=o[i])==null||vt.setMinSize(null)),t.$$.dirty[0]&6147&&(U>800&&j>400?(_t=o[i])==null||_t.setMaxSize(new Zn(U,j)):(Oe=o[i])==null||Oe.setMaxSize(null)),t.$$.dirty[0]&24579&&q!==null&&A!==null&&((Ie=o[i])==null||Ie.setPosition(new ft(q,A))),t.$$.dirty[0]&3&&((je=o[i])==null||je.scaleFactor().then(bt=>n(22,S=bt))),t.$$.dirty[0]&3&&ne(o[i]),t.$$.dirty[0]&32771&&((it=o[i])==null||it.setCursorGrab($)),t.$$.dirty[0]&65539&&((jt=o[i])==null||jt.setCursorVisible(_e)),t.$$.dirty[0]&524291&&((ot=o[i])==null||ot.setCursorIcon(K)),t.$$.dirty[0]&393219&&te!==null&&oe!==null&&((Rt=o[i])==null||Rt.setCursorPosition(new ft(te,oe)))},[i,o,p,d,w,_,y,g,b,L,W,U,j,q,A,$,_e,te,oe,K,f,c,S,z,D,C,N,be,l,H,Q,le,ae,ee,ve,Me,a,Le,R,V,Re,Ae,Te,ce,he,fe,Pe,tt,me,de,F,ie,X,ye,Yt,ht,Kt,He,Qt,Be]}class rs extends Se{constructor(e){super(),Ce(this,e,ls,os,ke,{onMessage:36},null,[-1,-1,-1])}}function Gl(t,e){return M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"GlobalShortcut",message:{cmd:"register",shortcut:t,handler:pt(e)}})]})})}function ss(t,e){return M(this,void 0,void 0,function(){return T(this,function(n){return[2,P({__tauriModule:"GlobalShortcut",message:{cmd:"registerAll",shortcuts:t,handler:pt(e)}})]})})}function us(t){return M(this,void 0,void 0,function(){return T(this,function(e){return[2,P({__tauriModule:"GlobalShortcut",message:{cmd:"isRegistered",shortcut:t}})]})})}function Jl(t){return M(this,void 0,void 0,function(){return T(this,function(e){return[2,P({__tauriModule:"GlobalShortcut",message:{cmd:"unregister",shortcut:t}})]})})}function Xl(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"GlobalShortcut",message:{cmd:"unregisterAll"}})]})})}Object.freeze({__proto__:null,register:Gl,registerAll:ss,isRegistered:us,unregister:Jl,unregisterAll:Xl});function ol(t,e,n){const i=t.slice();return i[9]=e[n],i}function ll(t){let e,n=t[9]+"",i,o,l,a,f;function c(){return t[8](t[9])}return{c(){e=s("div"),i=E(n),o=v(),l=s("button"),l.textContent="Unregister",u(l,"class","btn"),u(l,"type","button"),u(e,"class","flex justify-between")},m(p,d){m(p,e,d),r(e,i),r(e,o),r(e,l),a||(f=O(l,"click",c),a=!0)},p(p,d){t=p,d&2&&n!==(n=t[9]+"")&&x(i,n)},d(p){p&&h(e),a=!1,f()}}}function rl(t){let e,n,i,o,l;return{c(){e=s("br"),n=v(),i=s("button"),i.textContent="Unregister all",u(i,"class","btn"),u(i,"type","button")},m(a,f){m(a,e,f),m(a,n,f),m(a,i,f),o||(l=O(i,"click",t[5]),o=!0)},p:J,d(a){a&&h(e),a&&h(n),a&&h(i),o=!1,l()}}}function as(t){let e,n,i,o,l,a,f,c,p,d,w,_=t[1],y=[];for(let b=0;b<_.length;b+=1)y[b]=ll(ol(t,_,b));let g=t[1].length>1&&rl(t);return{c(){e=s("div"),n=s("input"),i=v(),o=s("button"),o.textContent="Register",l=v(),a=s("br"),f=v(),c=s("div");for(let b=0;b1?g?g.p(b,L):(g=rl(b),g.c(),g.m(c,null)):g&&(g.d(1),g=null)},i:J,o:J,d(b){b&&h(e),b&&h(l),b&&h(a),b&&h(f),b&&h(c),dt(y,b),g&&g.d(),d=!1,pe(w)}}}function cs(t,e,n){let i,{onMessage:o}=e;const l=yl([]);_l(t,l,_=>n(1,i=_));let a="CmdOrControl+X";function f(){const _=a;Gl(_,()=>{o(`Shortcut ${_} triggered`)}).then(()=>{l.update(y=>[...y,_]),o(`Shortcut ${_} registered successfully`)}).catch(o)}function c(_){const y=_;Jl(y).then(()=>{l.update(g=>g.filter(b=>b!==y)),o(`Shortcut ${y} unregistered`)}).catch(o)}function p(){Xl().then(()=>{l.update(()=>[]),o("Unregistered all shortcuts")}).catch(o)}function d(){a=this.value,n(0,a)}const w=_=>c(_);return t.$$set=_=>{"onMessage"in _&&n(6,o=_.onMessage)},[a,i,l,f,c,p,o,d,w]}class fs extends Se{constructor(e){super(),Ce(this,e,cs,as,ke,{onMessage:6})}}function sl(t){let e,n,i,o,l,a,f;return{c(){e=s("br"),n=v(),i=s("input"),o=v(),l=s("button"),l.textContent="Write",u(i,"class","input"),u(i,"placeholder","write to stdin"),u(l,"class","btn")},m(c,p){m(c,e,p),m(c,n,p),m(c,i,p),G(i,t[4]),m(c,o,p),m(c,l,p),a||(f=[O(i,"input",t[14]),O(l,"click",t[8])],a=!0)},p(c,p){p&16&&i.value!==c[4]&&G(i,c[4])},d(c){c&&h(e),c&&h(n),c&&h(i),c&&h(o),c&&h(l),a=!1,pe(f)}}}function ds(t){let e,n,i,o,l,a,f,c,p,d,w,_,y,g,b,L,W,U,j,q,A,S,z,D,C=t[5]&&sl(t);return{c(){e=s("div"),n=s("div"),i=E(`Script: + `),o=s("input"),l=v(),a=s("div"),f=E(`Encoding: + `),c=s("input"),p=v(),d=s("div"),w=E(`Working directory: `),_=s("input"),y=v(),g=s("div"),b=E(`Arguments: - `),L=s("input"),W=v(),U=s("div"),j=s("button"),j.textContent="Run",q=v(),A=s("button"),A.textContent="Kill",S=v(),C&&C.c(),a(o,"class","grow input"),a(n,"class","flex items-center gap-1"),a(c,"class","grow input"),a(u,"class","flex items-center gap-1"),a(_,"class","grow input"),a(_,"placeholder","Working directory"),a(d,"class","flex items-center gap-1"),a(L,"class","grow input"),a(L,"placeholder","Environment variables"),a(g,"class","flex items-center gap-1"),a(j,"class","btn"),a(A,"class","btn"),a(U,"class","flex children:grow gap-1"),a(e,"class","flex flex-col childre:grow gap-1")},m(N,B){m(N,e,B),r(e,n),r(n,i),r(n,o),G(o,t[0]),r(e,l),r(e,u),r(u,f),r(u,c),G(c,t[3]),r(e,p),r(e,d),r(d,k),r(d,_),G(_,t[1]),r(e,y),r(e,g),r(g,b),r(g,L),G(L,t[2]),r(e,W),r(e,U),r(U,j),r(U,q),r(U,A),r(e,S),C&&C.m(e,null),z||(D=[O(o,"input",t[10]),O(c,"input",t[11]),O(_,"input",t[12]),O(L,"input",t[13]),O(j,"click",t[6]),O(A,"click",t[7])],z=!0)},p(N,[B]){B&1&&o.value!==N[0]&&G(o,N[0]),B&8&&c.value!==N[3]&&G(c,N[3]),B&2&&_.value!==N[1]&&G(_,N[1]),B&4&&L.value!==N[2]&&G(L,N[2]),N[5]?C?C.p(N,B):(C=sl(N),C.c(),C.m(e,null)):C&&(C.d(1),C=null)},i:J,o:J,d(N){N&&h(e),C&&C.d(),z=!1,pe(D)}}}function hs(t,e,n){const i=navigator.userAgent.includes("Windows");let o=i?"cmd":"sh",l=i?["/C"]:["-c"],{onMessage:u}=e,f='echo "hello world"',c=null,p="SOMETHING=value ANOTHER=2",d="",k="",_;function y(){return p.split(" ").reduce((S,z)=>{let[D,C]=z.split("=");return{...S,[D]:C}},{})}function g(){n(5,_=null);const S=new Ml(o,[...l,f],{cwd:c||null,env:y(),encoding:d});S.on("close",z=>{u(`command finished with code ${z.code} and signal ${z.signal}`),n(5,_=null)}),S.on("error",z=>u(`command error: "${z}"`)),S.stdout.on("data",z=>u(`command stdout: "${z}"`)),S.stderr.on("data",z=>u(`command stderr: "${z}"`)),S.spawn().then(z=>{n(5,_=z)}).catch(u)}function b(){_.kill().then(()=>u("killed child process")).catch(u)}function L(){_.write(k).catch(u)}function W(){f=this.value,n(0,f)}function U(){d=this.value,n(3,d)}function j(){c=this.value,n(1,c)}function q(){p=this.value,n(2,p)}function A(){k=this.value,n(4,k)}return t.$$set=S=>{"onMessage"in S&&n(9,u=S.onMessage)},[f,c,p,d,k,_,g,b,L,u,W,U,j,q,A]}class ms extends Se{constructor(e){super(),Ce(this,e,hs,ps,ke,{onMessage:9})}}function Ni(t){return M(this,void 0,void 0,function(){return T(this,function(e){return[2,Xt("tauri://update-status",function(n){t(n==null?void 0:n.payload)})]})})}function Yl(){return M(this,void 0,void 0,function(){function t(){e&&e(),e=void 0}var e;return T(this,function(n){return[2,new Promise(function(i,o){Ni(function(l){return l.error?(t(),o(l.error)):l.status==="DONE"?(t(),i()):void 0}).then(function(l){e=l}).catch(function(l){throw t(),l}),ni("tauri://update-install").catch(function(l){throw t(),l})})]})})}function Kl(){return M(this,void 0,void 0,function(){function t(){e&&e(),e=void 0}var e;return T(this,function(n){return[2,new Promise(function(i,o){Fl("tauri://update-available",function(l){var u;u=l==null?void 0:l.payload,t(),i({manifest:u,shouldUpdate:!0})}).catch(function(l){throw t(),l}),Ni(function(l){return l.error?(t(),o(l.error)):l.status==="UPTODATE"?(t(),i({shouldUpdate:!1})):void 0}).then(function(l){e=l}).catch(function(l){throw t(),l}),ni("tauri://update").catch(function(l){throw t(),l})})]})})}Object.freeze({__proto__:null,onUpdaterEvent:Ni,installUpdate:Yl,checkUpdate:Kl});function vs(t){let e;return{c(){e=s("button"),e.innerHTML='
',a(e,"class","btn text-accentText dark:text-darkAccentText flex items-center justify-center")},m(n,i){m(n,e,i)},p:J,d(n){n&&h(e)}}}function _s(t){let e,n,i;return{c(){e=s("button"),e.textContent="Install update",a(e,"class","btn")},m(o,l){m(o,e,l),n||(i=O(e,"click",t[4]),n=!0)},p:J,d(o){o&&h(e),n=!1,i()}}}function bs(t){let e,n,i;return{c(){e=s("button"),e.textContent="Check update",a(e,"class","btn")},m(o,l){m(o,e,l),n||(i=O(e,"click",t[3]),n=!0)},p:J,d(o){o&&h(e),n=!1,i()}}}function gs(t){let e;function n(l,u){return!l[0]&&!l[2]?bs:!l[1]&&l[2]?_s:vs}let i=n(t),o=i(t);return{c(){e=s("div"),o.c(),a(e,"class","flex children:grow children:h10")},m(l,u){m(l,e,u),o.m(e,null)},p(l,[u]){i===(i=n(l))&&o?o.p(l,u):(o.d(1),o=i(l),o&&(o.c(),o.m(e,null)))},i:J,o:J,d(l){l&&h(e),o.d()}}}function ys(t,e,n){let{onMessage:i}=e,o;at(async()=>{o=await Xt("tauri://update-status",i)}),Di(()=>{o&&o()});let l,u,f;async function c(){n(0,l=!0);try{const{shouldUpdate:d,manifest:k}=await Kl();i(`Should update: ${d}`),i(k),n(2,f=d)}catch(d){i(d)}finally{n(0,l=!1)}}async function p(){n(1,u=!0);try{await Yl(),i("Installation complete, restart required."),await Fi()}catch(d){i(d)}finally{n(1,u=!1)}}return t.$$set=d=>{"onMessage"in d&&n(5,i=d.onMessage)},[l,u,f,c,p,i]}class ws extends Se{constructor(e){super(),Ce(this,e,ys,gs,ke,{onMessage:5})}}function xl(t){return M(this,void 0,void 0,function(){return T(this,function(e){return[2,P({__tauriModule:"Clipboard",message:{cmd:"writeText",data:t}})]})})}function Ql(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"Clipboard",message:{cmd:"readText",data:null}})]})})}Object.freeze({__proto__:null,writeText:xl,readText:Ql});function ks(t){let e,n,i,o,l,u,f,c;return{c(){e=s("div"),n=s("input"),i=v(),o=s("button"),o.textContent="Write",l=v(),u=s("button"),u.textContent="Read",a(n,"class","grow input"),a(n,"placeholder","Text to write to the clipboard"),a(o,"class","btn"),a(o,"type","button"),a(u,"class","btn"),a(u,"type","button"),a(e,"class","flex gap-1")},m(p,d){m(p,e,d),r(e,n),G(n,t[0]),r(e,i),r(e,o),r(e,l),r(e,u),f||(c=[O(n,"input",t[4]),O(o,"click",t[1]),O(u,"click",t[2])],f=!0)},p(p,[d]){d&1&&n.value!==p[0]&&G(n,p[0])},i:J,o:J,d(p){p&&h(e),f=!1,pe(c)}}}function Ms(t,e,n){let{onMessage:i}=e,o="clipboard message";function l(){xl(o).then(()=>{i("Wrote to the clipboard")}).catch(i)}function u(){Ql().then(c=>{i(`Clipboard contents: ${c}`)}).catch(i)}function f(){o=this.value,n(0,o)}return t.$$set=c=>{"onMessage"in c&&n(3,i=c.onMessage)},[o,l,u,i,f]}class Ts extends Se{constructor(e){super(),Ce(this,e,Ms,ks,ke,{onMessage:3})}}function Cs(t){let e;return{c(){e=s("div"),e.innerHTML=`
Not available for Linux
- `,a(e,"class","flex flex-col gap-2")},m(n,i){m(n,e,i)},p:J,i:J,o:J,d(n){n&&h(e)}}}function Ss(t,e,n){let{onMessage:i}=e;const o=window.constraints={audio:!0,video:!0};function l(f){const c=document.querySelector("video"),p=f.getVideoTracks();i("Got stream with constraints:",o),i(`Using video device: ${p[0].label}`),window.stream=f,c.srcObject=f}function u(f){if(f.name==="ConstraintNotSatisfiedError"){const c=o.video;i(`The resolution ${c.width.exact}x${c.height.exact} px is not supported by your device.`)}else f.name==="PermissionDeniedError"&&i("Permissions have not been granted to use your camera and microphone, you need to allow the page access to your devices in order for the demo to work.");i(`getUserMedia error: ${f.name}`,f)}return at(async()=>{try{const f=await navigator.mediaDevices.getUserMedia(o);l(f)}catch(f){u(f)}}),Di(()=>{window.stream.getTracks().forEach(function(f){f.stop()})}),t.$$set=f=>{"onMessage"in f&&n(0,i=f.onMessage)},[i]}class zs extends Se{constructor(e){super(),Ce(this,e,Ss,Cs,ke,{onMessage:0})}}function ul(t,e,n){const i=t.slice();return i[32]=e[n],i}function al(t,e,n){const i=t.slice();return i[35]=e[n],i}function cl(t){let e,n,i,o,l,u,f,c,p,d,k,_,y,g,b;function L(S,z){return S[3]?As:Ls}let W=L(t),U=W(t);function j(S,z){return S[2]?Os:Ps}let q=j(t),A=q(t);return{c(){e=s("div"),n=s("span"),n.textContent="Tauri API Validation",i=v(),o=s("span"),l=s("span"),U.c(),f=v(),c=s("span"),c.innerHTML='
',p=v(),d=s("span"),A.c(),_=v(),y=s("span"),y.innerHTML='
',a(n,"class","lt-sm:pl-10 text-darkPrimaryText"),a(l,"title",u=t[3]?"Switch to Light mode":"Switch to Dark mode"),a(l,"class","hover:bg-hoverOverlay active:bg-hoverOverlayDarker dark:hover:bg-darkHoverOverlay dark:active:bg-darkHoverOverlayDarker"),a(c,"title","Minimize"),a(c,"class","hover:bg-hoverOverlay active:bg-hoverOverlayDarker dark:hover:bg-darkHoverOverlay dark:active:bg-darkHoverOverlayDarker"),a(d,"title",k=t[2]?"Restore":"Maximize"),a(d,"class","hover:bg-hoverOverlay active:bg-hoverOverlayDarker dark:hover:bg-darkHoverOverlay dark:active:bg-darkHoverOverlayDarker"),a(y,"title","Close"),a(y,"class","hover:bg-red-700 dark:hover:bg-red-700 hover:text-darkPrimaryText active:bg-red-700/90 dark:active:bg-red-700/90 active:text-darkPrimaryText "),a(o,"class","h-100% children:h-100% children:w-12 children:inline-flex children:items-center children:justify-center"),a(e,"class","w-screen select-none h-8 pl-2 flex justify-between items-center absolute text-primaryText dark:text-darkPrimaryText"),a(e,"data-tauri-drag-region","")},m(S,z){m(S,e,z),r(e,n),r(e,i),r(e,o),r(o,l),U.m(l,null),r(o,f),r(o,c),r(o,p),r(o,d),A.m(d,null),r(o,_),r(o,y),g||(b=[O(l,"click",t[12]),O(c,"click",t[9]),O(d,"click",t[10]),O(y,"click",t[11])],g=!0)},p(S,z){W!==(W=L(S))&&(U.d(1),U=W(S),U&&(U.c(),U.m(l,null))),z[0]&8&&u!==(u=S[3]?"Switch to Light mode":"Switch to Dark mode")&&a(l,"title",u),q!==(q=j(S))&&(A.d(1),A=q(S),A&&(A.c(),A.m(d,null))),z[0]&4&&k!==(k=S[2]?"Restore":"Maximize")&&a(d,"title",k)},d(S){S&&h(e),U.d(),A.d(),g=!1,pe(b)}}}function Ls(t){let e;return{c(){e=s("div"),a(e,"class","i-ph-moon")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function As(t){let e;return{c(){e=s("div"),a(e,"class","i-ph-sun")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function Ps(t){let e;return{c(){e=s("div"),a(e,"class","i-codicon-chrome-maximize")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function Os(t){let e;return{c(){e=s("div"),a(e,"class","i-codicon-chrome-restore")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function Es(t){let e;return{c(){e=s("span"),a(e,"class","i-codicon-menu animate-duration-300ms animate-fade-in")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function Ws(t){let e;return{c(){e=s("span"),a(e,"class","i-codicon-close animate-duration-300ms animate-fade-in")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function fl(t){let e,n,i,o,l,u,f,c,p;function d(y,g){return y[3]?js:Ds}let k=d(t),_=k(t);return{c(){e=s("a"),_.c(),n=v(),i=s("br"),o=v(),l=s("div"),u=v(),f=s("br"),a(e,"href","##"),a(e,"class","nv justify-between h-8"),a(l,"class","bg-white/5 h-2px")},m(y,g){m(y,e,g),_.m(e,null),m(y,n,g),m(y,i,g),m(y,o,g),m(y,l,g),m(y,u,g),m(y,f,g),c||(p=O(e,"click",t[12]),c=!0)},p(y,g){k!==(k=d(y))&&(_.d(1),_=k(y),_&&(_.c(),_.m(e,null)))},d(y){y&&h(e),_.d(),y&&h(n),y&&h(i),y&&h(o),y&&h(l),y&&h(u),y&&h(f),c=!1,p()}}}function Ds(t){let e,n;return{c(){e=E(`Switch to Dark mode - `),n=s("div"),a(n,"class","i-ph-moon")},m(i,o){m(i,e,o),m(i,n,o)},d(i){i&&h(e),i&&h(n)}}}function js(t){let e,n;return{c(){e=E(`Switch to Light mode - `),n=s("div"),a(n,"class","i-ph-sun")},m(i,o){m(i,e,o),m(i,n,o)},d(i){i&&h(e),i&&h(n)}}}function Rs(t){let e,n,i,o,l,u=t[35].label+"",f,c,p,d;function k(){return t[20](t[35])}return{c(){e=s("a"),n=s("div"),o=v(),l=s("p"),f=E(u),a(n,"class",i=t[35].icon+" mr-2"),a(e,"href","##"),a(e,"class",c="nv "+(t[1]===t[35]?"nv_selected":""))},m(_,y){m(_,e,y),r(e,n),r(e,o),r(e,l),r(l,f),p||(d=O(e,"click",k),p=!0)},p(_,y){t=_,y[0]&2&&c!==(c="nv "+(t[1]===t[35]?"nv_selected":""))&&a(e,"class",c)},d(_){_&&h(e),p=!1,d()}}}function dl(t){let e,n=t[35]&&Rs(t);return{c(){n&&n.c(),e=$n()},m(i,o){n&&n.m(i,o),m(i,e,o)},p(i,o){i[35]&&n.p(i,o)},d(i){n&&n.d(i),i&&h(e)}}}function pl(t){let e,n=t[32].html+"",i;return{c(){e=new lr(!1),i=$n(),e.a=i},m(o,l){e.m(n,o,l),m(o,i,l)},p(o,l){l[0]&64&&n!==(n=o[32].html+"")&&e.p(n)},d(o){o&&h(i),o&&e.d()}}}function Hs(t){let e,n,i,o,l,u,f,c,p,d,k,_,y,g,b,L,W,U,j,q,A,S,z,D,C,N,B,Y=t[1].label+"",$,_e,te,oe,K,be,H,x,le,ae,ee,ve,re,ge,ne,Me,Le,R,V=t[5]&&cl(t);function Re(F,ie){return F[0]?Ws:Es}let Ae=Re(t),Te=Ae(t),ce=!t[5]&&fl(t),he=t[7],fe=[];for(let F=0;F`,k=v(),_=s("a"),_.innerHTML=`Github + `),L=s("input"),W=v(),U=s("div"),j=s("button"),j.textContent="Run",q=v(),A=s("button"),A.textContent="Kill",S=v(),C&&C.c(),u(o,"class","grow input"),u(n,"class","flex items-center gap-1"),u(c,"class","grow input"),u(a,"class","flex items-center gap-1"),u(_,"class","grow input"),u(_,"placeholder","Working directory"),u(d,"class","flex items-center gap-1"),u(L,"class","grow input"),u(L,"placeholder","Environment variables"),u(g,"class","flex items-center gap-1"),u(j,"class","btn"),u(A,"class","btn"),u(U,"class","flex children:grow gap-1"),u(e,"class","flex flex-col childre:grow gap-1")},m(N,B){m(N,e,B),r(e,n),r(n,i),r(n,o),G(o,t[0]),r(e,l),r(e,a),r(a,f),r(a,c),G(c,t[3]),r(e,p),r(e,d),r(d,w),r(d,_),G(_,t[1]),r(e,y),r(e,g),r(g,b),r(g,L),G(L,t[2]),r(e,W),r(e,U),r(U,j),r(U,q),r(U,A),r(e,S),C&&C.m(e,null),z||(D=[O(o,"input",t[10]),O(c,"input",t[11]),O(_,"input",t[12]),O(L,"input",t[13]),O(j,"click",t[6]),O(A,"click",t[7])],z=!0)},p(N,[B]){B&1&&o.value!==N[0]&&G(o,N[0]),B&8&&c.value!==N[3]&&G(c,N[3]),B&2&&_.value!==N[1]&&G(_,N[1]),B&4&&L.value!==N[2]&&G(L,N[2]),N[5]?C?C.p(N,B):(C=sl(N),C.c(),C.m(e,null)):C&&(C.d(1),C=null)},i:J,o:J,d(N){N&&h(e),C&&C.d(),z=!1,pe(D)}}}function ps(t,e,n){const i=navigator.userAgent.includes("Windows");let o=i?"cmd":"sh",l=i?["/C"]:["-c"],{onMessage:a}=e,f='echo "hello world"',c=null,p="SOMETHING=value ANOTHER=2",d="",w="",_;function y(){return p.split(" ").reduce((S,z)=>{let[D,C]=z.split("=");return{...S,[D]:C}},{})}function g(){n(5,_=null);const S=new Ml(o,[...l,f],{cwd:c||null,env:y(),encoding:d});S.on("close",z=>{a(`command finished with code ${z.code} and signal ${z.signal}`),n(5,_=null)}),S.on("error",z=>a(`command error: "${z}"`)),S.stdout.on("data",z=>a(`command stdout: "${z}"`)),S.stderr.on("data",z=>a(`command stderr: "${z}"`)),S.spawn().then(z=>{n(5,_=z)}).catch(a)}function b(){_.kill().then(()=>a("killed child process")).catch(a)}function L(){_.write(w).catch(a)}function W(){f=this.value,n(0,f)}function U(){d=this.value,n(3,d)}function j(){c=this.value,n(1,c)}function q(){p=this.value,n(2,p)}function A(){w=this.value,n(4,w)}return t.$$set=S=>{"onMessage"in S&&n(9,a=S.onMessage)},[f,c,p,d,w,_,g,b,L,a,W,U,j,q,A]}class hs extends Se{constructor(e){super(),Ce(this,e,ps,ds,ke,{onMessage:9})}}function Ni(t){return M(this,void 0,void 0,function(){return T(this,function(e){return[2,Xt("tauri://update-status",function(n){t(n==null?void 0:n.payload)})]})})}function Yl(){return M(this,void 0,void 0,function(){function t(){e&&e(),e=void 0}var e;return T(this,function(n){return[2,new Promise(function(i,o){Ni(function(l){return l.error?(t(),o(l.error)):l.status==="DONE"?(t(),i()):void 0}).then(function(l){e=l}).catch(function(l){throw t(),l}),ni("tauri://update-install").catch(function(l){throw t(),l})})]})})}function Kl(){return M(this,void 0,void 0,function(){function t(){e&&e(),e=void 0}var e;return T(this,function(n){return[2,new Promise(function(i,o){Fl("tauri://update-available",function(l){var a;a=l==null?void 0:l.payload,t(),i({manifest:a,shouldUpdate:!0})}).catch(function(l){throw t(),l}),Ni(function(l){return l.error?(t(),o(l.error)):l.status==="UPTODATE"?(t(),i({shouldUpdate:!1})):void 0}).then(function(l){e=l}).catch(function(l){throw t(),l}),ni("tauri://update").catch(function(l){throw t(),l})})]})})}Object.freeze({__proto__:null,onUpdaterEvent:Ni,installUpdate:Yl,checkUpdate:Kl});function ms(t){let e;return{c(){e=s("button"),e.innerHTML='
',u(e,"class","btn text-accentText dark:text-darkAccentText flex items-center justify-center")},m(n,i){m(n,e,i)},p:J,d(n){n&&h(e)}}}function vs(t){let e,n,i;return{c(){e=s("button"),e.textContent="Install update",u(e,"class","btn")},m(o,l){m(o,e,l),n||(i=O(e,"click",t[4]),n=!0)},p:J,d(o){o&&h(e),n=!1,i()}}}function _s(t){let e,n,i;return{c(){e=s("button"),e.textContent="Check update",u(e,"class","btn")},m(o,l){m(o,e,l),n||(i=O(e,"click",t[3]),n=!0)},p:J,d(o){o&&h(e),n=!1,i()}}}function bs(t){let e;function n(l,a){return!l[0]&&!l[2]?_s:!l[1]&&l[2]?vs:ms}let i=n(t),o=i(t);return{c(){e=s("div"),o.c(),u(e,"class","flex children:grow children:h10")},m(l,a){m(l,e,a),o.m(e,null)},p(l,[a]){i===(i=n(l))&&o?o.p(l,a):(o.d(1),o=i(l),o&&(o.c(),o.m(e,null)))},i:J,o:J,d(l){l&&h(e),o.d()}}}function gs(t,e,n){let{onMessage:i}=e,o;at(async()=>{o=await Xt("tauri://update-status",i)}),Di(()=>{o&&o()});let l,a,f;async function c(){n(0,l=!0);try{const{shouldUpdate:d,manifest:w}=await Kl();i(`Should update: ${d}`),i(w),n(2,f=d)}catch(d){i(d)}finally{n(0,l=!1)}}async function p(){n(1,a=!0);try{await Yl(),i("Installation complete, restart required."),await Fi()}catch(d){i(d)}finally{n(1,a=!1)}}return t.$$set=d=>{"onMessage"in d&&n(5,i=d.onMessage)},[l,a,f,c,p,i]}class ys extends Se{constructor(e){super(),Ce(this,e,gs,bs,ke,{onMessage:5})}}function Ql(t){return M(this,void 0,void 0,function(){return T(this,function(e){return[2,P({__tauriModule:"Clipboard",message:{cmd:"writeText",data:t}})]})})}function Zl(){return M(this,void 0,void 0,function(){return T(this,function(t){return[2,P({__tauriModule:"Clipboard",message:{cmd:"readText",data:null}})]})})}Object.freeze({__proto__:null,writeText:Ql,readText:Zl});function ws(t){let e,n,i,o,l,a,f,c;return{c(){e=s("div"),n=s("input"),i=v(),o=s("button"),o.textContent="Write",l=v(),a=s("button"),a.textContent="Read",u(n,"class","grow input"),u(n,"placeholder","Text to write to the clipboard"),u(o,"class","btn"),u(o,"type","button"),u(a,"class","btn"),u(a,"type","button"),u(e,"class","flex gap-1")},m(p,d){m(p,e,d),r(e,n),G(n,t[0]),r(e,i),r(e,o),r(e,l),r(e,a),f||(c=[O(n,"input",t[4]),O(o,"click",t[1]),O(a,"click",t[2])],f=!0)},p(p,[d]){d&1&&n.value!==p[0]&&G(n,p[0])},i:J,o:J,d(p){p&&h(e),f=!1,pe(c)}}}function ks(t,e,n){let{onMessage:i}=e,o="clipboard message";function l(){Ql(o).then(()=>{i("Wrote to the clipboard")}).catch(i)}function a(){Zl().then(c=>{i(`Clipboard contents: ${c}`)}).catch(i)}function f(){o=this.value,n(0,o)}return t.$$set=c=>{"onMessage"in c&&n(3,i=c.onMessage)},[o,l,a,i,f]}class Ms extends Se{constructor(e){super(),Ce(this,e,ks,ws,ke,{onMessage:3})}}function Ts(t){let e;return{c(){e=s("div"),e.innerHTML=`
Not available for Linux
+ `,u(e,"class","flex flex-col gap-2")},m(n,i){m(n,e,i)},p:J,i:J,o:J,d(n){n&&h(e)}}}function Cs(t,e,n){let{onMessage:i}=e;const o=window.constraints={audio:!0,video:!0};function l(f){const c=document.querySelector("video"),p=f.getVideoTracks();i("Got stream with constraints:",o),i(`Using video device: ${p[0].label}`),window.stream=f,c.srcObject=f}function a(f){if(f.name==="ConstraintNotSatisfiedError"){const c=o.video;i(`The resolution ${c.width.exact}x${c.height.exact} px is not supported by your device.`)}else f.name==="PermissionDeniedError"&&i("Permissions have not been granted to use your camera and microphone, you need to allow the page access to your devices in order for the demo to work.");i(`getUserMedia error: ${f.name}`,f)}return at(async()=>{try{const f=await navigator.mediaDevices.getUserMedia(o);l(f)}catch(f){a(f)}}),Di(()=>{window.stream.getTracks().forEach(function(f){f.stop()})}),t.$$set=f=>{"onMessage"in f&&n(0,i=f.onMessage)},[i]}class Ss extends Se{constructor(e){super(),Ce(this,e,Cs,Ts,ke,{onMessage:0})}}function ul(t,e,n){const i=t.slice();return i[32]=e[n],i}function al(t,e,n){const i=t.slice();return i[35]=e[n],i}function cl(t){let e,n,i,o,l,a,f,c,p,d,w,_,y,g,b;function L(S,z){return S[3]?Ls:zs}let W=L(t),U=W(t);function j(S,z){return S[2]?Ps:As}let q=j(t),A=q(t);return{c(){e=s("div"),n=s("span"),n.textContent="Tauri API Validation",i=v(),o=s("span"),l=s("span"),U.c(),f=v(),c=s("span"),c.innerHTML='
',p=v(),d=s("span"),A.c(),_=v(),y=s("span"),y.innerHTML='
',u(n,"class","lt-sm:pl-10 text-darkPrimaryText"),u(l,"title",a=t[3]?"Switch to Light mode":"Switch to Dark mode"),u(l,"class","hover:bg-hoverOverlay active:bg-hoverOverlayDarker dark:hover:bg-darkHoverOverlay dark:active:bg-darkHoverOverlayDarker"),u(c,"title","Minimize"),u(c,"class","hover:bg-hoverOverlay active:bg-hoverOverlayDarker dark:hover:bg-darkHoverOverlay dark:active:bg-darkHoverOverlayDarker"),u(d,"title",w=t[2]?"Restore":"Maximize"),u(d,"class","hover:bg-hoverOverlay active:bg-hoverOverlayDarker dark:hover:bg-darkHoverOverlay dark:active:bg-darkHoverOverlayDarker"),u(y,"title","Close"),u(y,"class","hover:bg-red-700 dark:hover:bg-red-700 hover:text-darkPrimaryText active:bg-red-700/90 dark:active:bg-red-700/90 active:text-darkPrimaryText "),u(o,"class","h-100% children:h-100% children:w-12 children:inline-flex children:items-center children:justify-center"),u(e,"class","w-screen select-none h-8 pl-2 flex justify-between items-center absolute text-primaryText dark:text-darkPrimaryText"),u(e,"data-tauri-drag-region","")},m(S,z){m(S,e,z),r(e,n),r(e,i),r(e,o),r(o,l),U.m(l,null),r(o,f),r(o,c),r(o,p),r(o,d),A.m(d,null),r(o,_),r(o,y),g||(b=[O(l,"click",t[12]),O(c,"click",t[9]),O(d,"click",t[10]),O(y,"click",t[11])],g=!0)},p(S,z){W!==(W=L(S))&&(U.d(1),U=W(S),U&&(U.c(),U.m(l,null))),z[0]&8&&a!==(a=S[3]?"Switch to Light mode":"Switch to Dark mode")&&u(l,"title",a),q!==(q=j(S))&&(A.d(1),A=q(S),A&&(A.c(),A.m(d,null))),z[0]&4&&w!==(w=S[2]?"Restore":"Maximize")&&u(d,"title",w)},d(S){S&&h(e),U.d(),A.d(),g=!1,pe(b)}}}function zs(t){let e;return{c(){e=s("div"),u(e,"class","i-ph-moon")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function Ls(t){let e;return{c(){e=s("div"),u(e,"class","i-ph-sun")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function As(t){let e;return{c(){e=s("div"),u(e,"class","i-codicon-chrome-maximize")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function Ps(t){let e;return{c(){e=s("div"),u(e,"class","i-codicon-chrome-restore")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function Os(t){let e;return{c(){e=s("span"),u(e,"class","i-codicon-menu animate-duration-300ms animate-fade-in")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function Es(t){let e;return{c(){e=s("span"),u(e,"class","i-codicon-close animate-duration-300ms animate-fade-in")},m(n,i){m(n,e,i)},d(n){n&&h(e)}}}function fl(t){let e,n,i,o,l,a,f,c,p;function d(y,g){return y[3]?Ds:Ws}let w=d(t),_=w(t);return{c(){e=s("a"),_.c(),n=v(),i=s("br"),o=v(),l=s("div"),a=v(),f=s("br"),u(e,"href","##"),u(e,"class","nv justify-between h-8"),u(l,"class","bg-white/5 h-2px")},m(y,g){m(y,e,g),_.m(e,null),m(y,n,g),m(y,i,g),m(y,o,g),m(y,l,g),m(y,a,g),m(y,f,g),c||(p=O(e,"click",t[12]),c=!0)},p(y,g){w!==(w=d(y))&&(_.d(1),_=w(y),_&&(_.c(),_.m(e,null)))},d(y){y&&h(e),_.d(),y&&h(n),y&&h(i),y&&h(o),y&&h(l),y&&h(a),y&&h(f),c=!1,p()}}}function Ws(t){let e,n;return{c(){e=E(`Switch to Dark mode + `),n=s("div"),u(n,"class","i-ph-moon")},m(i,o){m(i,e,o),m(i,n,o)},d(i){i&&h(e),i&&h(n)}}}function Ds(t){let e,n;return{c(){e=E(`Switch to Light mode + `),n=s("div"),u(n,"class","i-ph-sun")},m(i,o){m(i,e,o),m(i,n,o)},d(i){i&&h(e),i&&h(n)}}}function js(t){let e,n,i,o,l=t[35].label+"",a,f,c,p;function d(){return t[20](t[35])}return{c(){e=s("a"),n=s("div"),i=v(),o=s("p"),a=E(l),u(n,"class",t[35].icon+" mr-2"),u(e,"href","##"),u(e,"class",f="nv "+(t[1]===t[35]?"nv_selected":""))},m(w,_){m(w,e,_),r(e,n),r(e,i),r(e,o),r(o,a),c||(p=O(e,"click",d),c=!0)},p(w,_){t=w,_[0]&2&&f!==(f="nv "+(t[1]===t[35]?"nv_selected":""))&&u(e,"class",f)},d(w){w&&h(e),c=!1,p()}}}function dl(t){let e,n=t[35]&&js(t);return{c(){n&&n.c(),e=$n()},m(i,o){n&&n.m(i,o),m(i,e,o)},p(i,o){i[35]&&n.p(i,o)},d(i){n&&n.d(i),i&&h(e)}}}function pl(t){let e,n=t[32].html+"",i;return{c(){e=new or(!1),i=$n(),e.a=i},m(o,l){e.m(n,o,l),m(o,i,l)},p(o,l){l[0]&64&&n!==(n=o[32].html+"")&&e.p(n)},d(o){o&&h(i),o&&e.d()}}}function Rs(t){let e,n,i,o,l,a,f,c,p,d,w,_,y,g,b,L,W,U,j,q,A,S,z,D,C,N,B,Y=t[1].label+"",$,_e,te,oe,K,be,H,Q,le,ae,ee,ve,re,ge,ne,Me,Le,R,V=t[5]&&cl(t);function Re(F,ie){return F[0]?Es:Os}let Ae=Re(t),Te=Ae(t),ce=!t[5]&&fl(t),he=t[7],fe=[];for(let F=0;F`,w=v(),_=s("a"),_.innerHTML=`Github `,y=v(),g=s("a"),g.innerHTML=`Source - `,b=v(),L=s("br"),W=v(),U=s("div"),j=v(),q=s("br"),A=v(),S=s("div");for(let F=0;F',ge=v(),ne=s("div");for(let F=0;F{Gt(X,1)}),ti()}Pe?(K=new Pe(tt(F)),Kn(K.$$.fragment),Ee(K.$$.fragment,1),Vt(K,oe,null)):K=null}if(ie[0]&64){me=F[6];let X;for(X=0;X{await confirm("Are you sure?")||H.preventDefault()}),qe.onFileDropEvent(H=>{W(`File drop: ${JSON.stringify(H.payload)}`)});const o=navigator.userAgent.toLowerCase(),l=o.includes("android")||o.includes("iphone"),u=[{label:"Welcome",component:kr,icon:"i-ph-hand-waving"},{label:"Communication",component:Lr,icon:"i-codicon-radio-tower"},!l&&{label:"CLI",component:Cr,icon:"i-codicon-terminal"},!l&&{label:"Dialog",component:Nr,icon:"i-codicon-multiple-windows"},{label:"File system",component:Gr,icon:"i-codicon-files"},{label:"HTTP",component:es,icon:"i-ph-globe-hemisphere-west"},!l&&{label:"Notifications",component:os,icon:"i-codicon-bell-dot"},!l&&{label:"Window",component:ss,icon:"i-codicon-window"},!l&&{label:"Shortcuts",component:ds,icon:"i-codicon-record-keys"},{label:"Shell",component:ms,icon:"i-codicon-terminal-bash"},!l&&{label:"Updater",component:ws,icon:"i-codicon-cloud-download"},!l&&{label:"Clipboard",component:Ts,icon:"i-codicon-clippy"},{label:"WebRTC",component:zs,icon:"i-ph-broadcast"}];let f=u[0];function c(H){n(1,f=H)}let p;at(async()=>{const H=Nt();n(2,p=await H.isMaximized()),Xt("tauri://resize",async()=>{n(2,p=await H.isMaximized())})});function d(){Nt().minimize()}async function k(){const H=Nt();await H.isMaximized()?H.unmaximize():H.maximize()}let _=!1;async function y(){_||(_=await Ul("Are you sure that you want to close this window?",{title:"Tauri API"}),_&&Nt().close())}let g;at(()=>{n(3,g=localStorage&&localStorage.getItem("theme")=="dark"),ml(g)});function b(){n(3,g=!g),ml(g)}let L=yl([]);_l(t,L,H=>n(6,i=H));function W(H){L.update(x=>[{html:`
[${new Date().toLocaleTimeString()}]: `+(typeof H=="string"?H:JSON.stringify(H,null,1))+"
"},...x])}function U(H){L.update(x=>[{html:`
[${new Date().toLocaleTimeString()}]: `+H+"
"},...x])}function j(){L.update(()=>[])}let q,A,S;function z(H){S=H.clientY;const x=window.getComputedStyle(q);A=parseInt(x.height,10);const le=ee=>{const ve=ee.clientY-S,re=A-ve;n(4,q.style.height=`${re{document.removeEventListener("mouseup",ae),document.removeEventListener("mousemove",le)};document.addEventListener("mouseup",ae),document.addEventListener("mousemove",le)}let D;at(async()=>{n(5,D=await El()==="win32")});let C=!1,N,B,Y=!1,$=0,_e=0;const te=(H,x,le)=>Math.min(Math.max(x,H),le);at(()=>{n(18,N=document.querySelector("#sidebar")),B=document.querySelector("#sidebarToggle"),document.addEventListener("click",H=>{B.contains(H.target)?n(0,C=!C):C&&!N.contains(H.target)&&n(0,C=!1)}),document.addEventListener("touchstart",H=>{if(B.contains(H.target))return;const x=H.touches[0].clientX;(0{if(Y){const x=H.touches[0].clientX;_e=x;const le=(x-$)/10;N.style.setProperty("--translate-x",`-${te(0,C?0-le:18.75-le,18.75)}rem`)}}),document.addEventListener("touchend",()=>{if(Y){const H=(_e-$)/10;n(0,C=C?H>-(18.75/2):H>18.75/2)}Y=!1})});const oe=()=>Ri("https://tauri.app/"),K=H=>{c(H),n(0,C=!1)};function be(H){Yn[H?"unshift":"push"](()=>{q=H,n(4,q)})}return t.$$.update=()=>{if(t.$$.dirty[0]&1){const H=document.querySelector("#sidebar");H&&Fs(H,C)}},[C,f,p,g,q,D,i,u,c,d,k,y,b,L,W,U,j,z,N,oe,K,be]}class Us extends Se{constructor(e){super(),Ce(this,e,Is,Hs,ke,{},null,[-1,-1])}}new Us({target:document.querySelector("#app")}); + `,b=v(),L=s("br"),W=v(),U=s("div"),j=v(),q=s("br"),A=v(),S=s("div");for(let F=0;F',ge=v(),ne=s("div");for(let F=0;F{Gt(X,1)}),ti()}Pe?(K=new Pe(tt(F)),Kn(K.$$.fragment),Ee(K.$$.fragment,1),Vt(K,oe,null)):K=null}if(ie[0]&64){me=F[6];let X;for(X=0;X{await confirm("Are you sure?")||H.preventDefault()}),qe.onFileDropEvent(H=>{W(`File drop: ${JSON.stringify(H.payload)}`)});const o=navigator.userAgent.toLowerCase(),l=o.includes("android")||o.includes("iphone"),a=[{label:"Welcome",component:wr,icon:"i-ph-hand-waving"},{label:"Communication",component:zr,icon:"i-codicon-radio-tower"},!l&&{label:"CLI",component:Tr,icon:"i-codicon-terminal"},!l&&{label:"Dialog",component:Ur,icon:"i-codicon-multiple-windows"},{label:"File system",component:Vr,icon:"i-codicon-files"},{label:"HTTP",component:$r,icon:"i-ph-globe-hemisphere-west"},!l&&{label:"Notifications",component:is,icon:"i-codicon-bell-dot"},!l&&{label:"Window",component:rs,icon:"i-codicon-window"},!l&&{label:"Shortcuts",component:fs,icon:"i-codicon-record-keys"},{label:"Shell",component:hs,icon:"i-codicon-terminal-bash"},!l&&{label:"Updater",component:ys,icon:"i-codicon-cloud-download"},!l&&{label:"Clipboard",component:Ms,icon:"i-codicon-clippy"},{label:"WebRTC",component:Ss,icon:"i-ph-broadcast"}];let f=a[0];function c(H){n(1,f=H)}let p;at(async()=>{const H=Nt();n(2,p=await H.isMaximized()),Xt("tauri://resize",async()=>{n(2,p=await H.isMaximized())})});function d(){Nt().minimize()}async function w(){const H=Nt();await H.isMaximized()?H.unmaximize():H.maximize()}let _=!1;async function y(){_||(_=await Ul("Are you sure that you want to close this window?",{title:"Tauri API"}),_&&Nt().close())}let g;at(()=>{n(3,g=localStorage&&localStorage.getItem("theme")=="dark"),ml(g)});function b(){n(3,g=!g),ml(g)}let L=yl([]);_l(t,L,H=>n(6,i=H));function W(H){L.update(Q=>[{html:`
[${new Date().toLocaleTimeString()}]: `+(typeof H=="string"?H:JSON.stringify(H,null,1))+"
"},...Q])}function U(H){L.update(Q=>[{html:`
[${new Date().toLocaleTimeString()}]: `+H+"
"},...Q])}function j(){L.update(()=>[])}let q,A,S;function z(H){S=H.clientY;const Q=window.getComputedStyle(q);A=parseInt(Q.height,10);const le=ee=>{const ve=ee.clientY-S,re=A-ve;n(4,q.style.height=`${re{document.removeEventListener("mouseup",ae),document.removeEventListener("mousemove",le)};document.addEventListener("mouseup",ae),document.addEventListener("mousemove",le)}let D;at(async()=>{n(5,D=await El()==="win32")});let C=!1,N,B,Y=!1,$=0,_e=0;const te=(H,Q,le)=>Math.min(Math.max(Q,H),le);at(()=>{n(18,N=document.querySelector("#sidebar")),B=document.querySelector("#sidebarToggle"),document.addEventListener("click",H=>{B.contains(H.target)?n(0,C=!C):C&&!N.contains(H.target)&&n(0,C=!1)}),document.addEventListener("touchstart",H=>{if(B.contains(H.target))return;const Q=H.touches[0].clientX;(0{if(Y){const Q=H.touches[0].clientX;_e=Q;const le=(Q-$)/10;N.style.setProperty("--translate-x",`-${te(0,C?0-le:18.75-le,18.75)}rem`)}}),document.addEventListener("touchend",()=>{if(Y){const H=(_e-$)/10;n(0,C=C?H>-(18.75/2):H>18.75/2)}Y=!1})});const oe=()=>Ri("https://tauri.app/"),K=H=>{c(H),n(0,C=!1)};function be(H){Yn[H?"unshift":"push"](()=>{q=H,n(4,q)})}return t.$$.update=()=>{if(t.$$.dirty[0]&1){const H=document.querySelector("#sidebar");H&&Hs(H,C)}},[C,f,p,g,q,D,i,a,c,d,w,y,b,L,W,U,j,z,N,oe,K,be]}class Is extends Se{constructor(e){super(),Ce(this,e,Fs,Rs,ke,{},null,[-1,-1])}}new Is({target:document.querySelector("#app")}); diff --git a/examples/api/package.json b/examples/api/package.json index 9e89c0952..29cff8b61 100644 --- a/examples/api/package.json +++ b/examples/api/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "type": "module", "scripts": { - "dev": "vite --clearScreen false --port 5000", + "dev": "vite --clearScreen false", "build": "vite build", "serve": "vite preview", "tauri": "node ../../tooling/cli/node/tauri.js" @@ -15,9 +15,10 @@ "devDependencies": { "@iconify-json/codicon": "^1.1.10", "@iconify-json/ph": "^1.1.1", - "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", + "@sveltejs/vite-plugin-svelte": "^1.0.1", + "internal-ip": "^7.0.0", "svelte": "^3.49.0", "unocss": "^0.39.3", - "vite": "^2.9.12" + "vite": "^3.0.9" } } diff --git a/examples/api/src-tauri/Cargo.lock b/examples/api/src-tauri/Cargo.lock index 6f0b89c6a..e868532a7 100644 --- a/examples/api/src-tauri/Cargo.lock +++ b/examples/api/src-tauri/Cargo.lock @@ -112,9 +112,7 @@ version = "0.1.0" dependencies = [ "android_logger", "env_logger 0.9.0", - "jni", "log", - "mobile-entry-point", "paste", "serde", "serde_json", @@ -1659,6 +1657,18 @@ dependencies = [ "safemem", ] +[[package]] +name = "local-ip-address" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d6f43d42d775afa8073bfa6aba569b340a3635efa8c9f7702c9c6ed209692f" +dependencies = [ + "libc", + "neli", + "thiserror", + "windows-sys", +] + [[package]] name = "lock_api" version = "0.4.7" @@ -1808,17 +1818,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "mobile-entry-point" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bef5a90018326583471cccca10424d7b3e770397b02f03276543cbb9b6a1a6" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "multipart" version = "0.18.0" @@ -1878,6 +1877,16 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "neli" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9053554eb5dcb7e10d9cdab1206965bde870eed5d0d341532ca035e3ba221508" +dependencies = [ + "byteorder", + "libc", +] + [[package]] name = "new_debug_unreachable" version = "1.0.4" @@ -3243,6 +3252,7 @@ dependencies = [ "brotli", "ico", "json-patch", + "local-ip-address", "plist", "png 0.17.5", "proc-macro2", @@ -3255,6 +3265,7 @@ dependencies = [ "tauri-utils", "thiserror", "time", + "url", "uuid 1.1.2", "walkdir", ] diff --git a/examples/api/src-tauri/Cargo.toml b/examples/api/src-tauri/Cargo.toml index c4d4d321a..cbcd8c1aa 100644 --- a/examples/api/src-tauri/Cargo.toml +++ b/examples/api/src-tauri/Cargo.toml @@ -45,11 +45,9 @@ tauri-runtime-wry = { path = "../../../core/tauri-runtime-wry/" } [target.'cfg(target_os = "android")'.dependencies] android_logger = "0.9.0" -jni = "0.19.0" paste = "1.0" [target.'cfg(target_os = "ios")'.dependencies] -mobile-entry-point = "0.1.0" env_logger = "0.9.0" [features] diff --git a/examples/api/src-tauri/tauri.conf.json b/examples/api/src-tauri/tauri.conf.json index 3f3dd772e..6ad3567bc 100644 --- a/examples/api/src-tauri/tauri.conf.json +++ b/examples/api/src-tauri/tauri.conf.json @@ -2,8 +2,8 @@ "$schema": "../../../tooling/cli/schema.json", "build": { "distDir": "../dist", - "devPath": "http://localhost:5000", - "beforeDevCommand": "yarn dev", + "devPath": "http://localhost:5173", + "beforeDevCommand": "yarn dev --host", "beforeBuildCommand": "yarn build" }, "package": { diff --git a/examples/api/vite.config.js b/examples/api/vite.config.js index 10825d144..9157d89bb 100644 --- a/examples/api/vite.config.js +++ b/examples/api/vite.config.js @@ -1,22 +1,30 @@ import { defineConfig } from 'vite' import Unocss from 'unocss/vite' import { svelte } from '@sveltejs/vite-plugin-svelte' +import { internalIpV4 } from 'internal-ip' // https://vitejs.dev/config/ -export default defineConfig({ - plugins: [Unocss(), svelte()], - build: { - rollupOptions: { - output: { - entryFileNames: `assets/[name].js`, - chunkFileNames: `assets/[name].js`, - assetFileNames: `assets/[name].[ext]` +export default defineConfig(async ({ command, mode }) => { + const host = await internalIpV4() + return { + plugins: [Unocss(), svelte()], + build: { + rollupOptions: { + output: { + entryFileNames: `assets/[name].js`, + chunkFileNames: `assets/[name].js`, + assetFileNames: `assets/[name].[ext]` + } + } + }, + server: { + hmr: { + host, + port: 5183 + }, + fs: { + allow: ['.', '../../tooling/api/dist'] } - } - }, - server: { - fs: { - allow: ['.', '../../tooling/api/dist'] } } }) diff --git a/examples/api/yarn.lock b/examples/api/yarn.lock index fa6f5c151..b9cd0c3c2 100644 --- a/examples/api/yarn.lock +++ b/examples/api/yarn.lock @@ -15,6 +15,11 @@ resolved "https://registry.yarnpkg.com/@antfu/utils/-/utils-0.5.2.tgz#8c2d931ff927be0ebe740169874a3d4004ab414b" integrity sha512-CQkeV+oJxUazwjlHD0/3ZD08QWKuGQkhnrKo3e6ly5pd48VUpXbb77q0xMU4+vc2CkJnDS02Eq/M9ugyX20XZA== +"@esbuild/linux-loong64@0.14.54": + version "0.14.54" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz#de2a4be678bd4d0d1ffbb86e6de779cde5999028" + integrity sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw== + "@iconify-json/codicon@^1.1.10": version "1.1.10" resolved "https://registry.yarnpkg.com/@iconify-json/codicon/-/codicon-1.1.10.tgz#22fee909be51afebfbcc6cd57209064b5363f202" @@ -80,15 +85,15 @@ estree-walker "^2.0.1" picomatch "^2.2.2" -"@sveltejs/vite-plugin-svelte@^1.0.0-next.49": - version "1.0.0-next.49" - resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.0-next.49.tgz#44cc00a19c6c23002516b66c5ab90ee66720df57" - integrity sha512-AKh0Ka8EDgidnxWUs8Hh2iZLZovkETkefO99XxZ4sW4WGJ7VFeBx5kH/NIIGlaNHLcrIvK3CK0HkZwC3Cici0A== +"@sveltejs/vite-plugin-svelte@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.1.tgz#7f468f03c933fcdfc60d4773671c73f33b9ef4d6" + integrity sha512-PorCgUounn0VXcpeJu+hOweZODKmGuLHsLomwqSj+p26IwjjGffmYQfVHtiTWq+NqaUuuHWWG7vPge6UFw4Aeg== dependencies: "@rollup/pluginutils" "^4.2.1" debug "^4.3.4" deepmerge "^4.2.2" - kleur "^4.1.4" + kleur "^4.1.5" magic-string "^0.26.2" svelte-hmr "^0.14.12" @@ -323,6 +328,13 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + defu@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/defu/-/defu-6.0.0.tgz#b397a6709a2f3202747a3d9daf9446e41ad0c5fc" @@ -338,138 +350,139 @@ duplexer@^0.1.2: resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== -esbuild-android-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.47.tgz#ef95b42c67bcf4268c869153fa3ad1466c4cea6b" - integrity sha512-R13Bd9+tqLVFndncMHssZrPWe6/0Kpv2/dt4aA69soX4PRxlzsVpCvoJeFE8sOEoeVEiBkI0myjlkDodXlHa0g== +esbuild-android-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz#505f41832884313bbaffb27704b8bcaa2d8616be" + integrity sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ== -esbuild-android-arm64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.47.tgz#4ebd7ce9fb250b4695faa3ee46fd3b0754ecd9e6" - integrity sha512-OkwOjj7ts4lBp/TL6hdd8HftIzOy/pdtbrNA4+0oVWgGG64HrdVzAF5gxtJufAPOsEjkyh1oIYvKAUinKKQRSQ== +esbuild-android-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz#8ce69d7caba49646e009968fe5754a21a9871771" + integrity sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg== -esbuild-darwin-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.47.tgz#e0da6c244f497192f951807f003f6a423ed23188" - integrity sha512-R6oaW0y5/u6Eccti/TS6c/2c1xYTb1izwK3gajJwi4vIfNs1s8B1dQzI1UiC9T61YovOQVuePDcfqHLT3mUZJA== +esbuild-darwin-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz#24ba67b9a8cb890a3c08d9018f887cc221cdda25" + integrity sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug== -esbuild-darwin-arm64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.47.tgz#cd40fd49a672fca581ed202834239dfe540a9028" - integrity sha512-seCmearlQyvdvM/noz1L9+qblC5vcBrhUaOoLEDDoLInF/VQ9IkobGiLlyTPYP5dW1YD4LXhtBgOyevoIHGGnw== +esbuild-darwin-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz#3f7cdb78888ee05e488d250a2bdaab1fa671bf73" + integrity sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw== -esbuild-freebsd-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.47.tgz#8da6a14c095b29c01fc8087a16cb7906debc2d67" - integrity sha512-ZH8K2Q8/Ux5kXXvQMDsJcxvkIwut69KVrYQhza/ptkW50DC089bCVrJZZ3sKzIoOx+YPTrmsZvqeZERjyYrlvQ== +esbuild-freebsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz#09250f997a56ed4650f3e1979c905ffc40bbe94d" + integrity sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg== -esbuild-freebsd-arm64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.47.tgz#ad31f9c92817ff8f33fd253af7ab5122dc1b83f6" - integrity sha512-ZJMQAJQsIOhn3XTm7MPQfCzEu5b9STNC+s90zMWe2afy9EwnHV7Ov7ohEMv2lyWlc2pjqLW8QJnz2r0KZmeAEQ== +esbuild-freebsd-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz#bafb46ed04fc5f97cbdb016d86947a79579f8e48" + integrity sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q== -esbuild-linux-32@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.47.tgz#de085e4db2e692ea30c71208ccc23fdcf5196c58" - integrity sha512-FxZOCKoEDPRYvq300lsWCTv1kcHgiiZfNrPtEhFAiqD7QZaXrad8LxyJ8fXGcWzIFzRiYZVtB3ttvITBvAFhKw== +esbuild-linux-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz#e2a8c4a8efdc355405325033fcebeb941f781fe5" + integrity sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw== -esbuild-linux-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.47.tgz#2a9321bbccb01f01b04cebfcfccbabeba3658ba1" - integrity sha512-nFNOk9vWVfvWYF9YNYksZptgQAdstnDCMtR6m42l5Wfugbzu11VpMCY9XrD4yFxvPo9zmzcoUL/88y0lfJZJJw== +esbuild-linux-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz#de5fdba1c95666cf72369f52b40b03be71226652" + integrity sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg== -esbuild-linux-arm64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.47.tgz#b9da7b6fc4b0ca7a13363a0c5b7bb927e4bc535a" - integrity sha512-ywfme6HVrhWcevzmsufjd4iT3PxTfCX9HOdxA7Hd+/ZM23Y9nXeb+vG6AyA6jgq/JovkcqRHcL9XwRNpWG6XRw== +esbuild-linux-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz#dae4cd42ae9787468b6a5c158da4c84e83b0ce8b" + integrity sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig== -esbuild-linux-arm@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.47.tgz#56fec2a09b9561c337059d4af53625142aded853" - integrity sha512-ZGE1Bqg/gPRXrBpgpvH81tQHpiaGxa8c9Rx/XOylkIl2ypLuOcawXEAo8ls+5DFCcRGt/o3sV+PzpAFZobOsmA== +esbuild-linux-arm@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz#a2c1dff6d0f21dbe8fc6998a122675533ddfcd59" + integrity sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw== -esbuild-linux-mips64le@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.47.tgz#9db21561f8f22ed79ef2aedb7bbef082b46cf823" - integrity sha512-mg3D8YndZ1LvUiEdDYR3OsmeyAew4MA/dvaEJxvyygahWmpv1SlEEnhEZlhPokjsUMfRagzsEF/d/2XF+kTQGg== +esbuild-linux-mips64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz#d9918e9e4cb972f8d6dae8e8655bf9ee131eda34" + integrity sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw== -esbuild-linux-ppc64le@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.47.tgz#dc3a3da321222b11e96e50efafec9d2de408198b" - integrity sha512-WER+f3+szmnZiWoK6AsrTKGoJoErG2LlauSmk73LEZFQ/iWC+KhhDsOkn1xBUpzXWsxN9THmQFltLoaFEH8F8w== +esbuild-linux-ppc64le@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz#3f9a0f6d41073fb1a640680845c7de52995f137e" + integrity sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ== -esbuild-linux-riscv64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.47.tgz#9bd6dcd3dca6c0357084ecd06e1d2d4bf105335f" - integrity sha512-1fI6bP3A3rvI9BsaaXbMoaOjLE3lVkJtLxsgLHqlBhLlBVY7UqffWBvkrX/9zfPhhVMd9ZRFiaqXnB1T7BsL2g== +esbuild-linux-riscv64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz#618853c028178a61837bc799d2013d4695e451c8" + integrity sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg== -esbuild-linux-s390x@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.47.tgz#a458af939b52f2cd32fc561410d441a51f69d41f" - integrity sha512-eZrWzy0xFAhki1CWRGnhsHVz7IlSKX6yT2tj2Eg8lhAwlRE5E96Hsb0M1mPSE1dHGpt1QVwwVivXIAacF/G6mw== +esbuild-linux-s390x@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz#d1885c4c5a76bbb5a0fe182e2c8c60eb9e29f2a6" + integrity sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA== -esbuild-netbsd-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.47.tgz#6388e785d7e7e4420cb01348d7483ab511b16aa8" - integrity sha512-Qjdjr+KQQVH5Q2Q1r6HBYswFTToPpss3gqCiSw2Fpq/ua8+eXSQyAMG+UvULPqXceOwpnPo4smyZyHdlkcPppQ== +esbuild-netbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz#69ae917a2ff241b7df1dbf22baf04bd330349e81" + integrity sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w== -esbuild-openbsd-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.47.tgz#309af806db561aa886c445344d1aacab850dbdc5" - integrity sha512-QpgN8ofL7B9z8g5zZqJE+eFvD1LehRlxr25PBkjyyasakm4599iroUpaj96rdqRlO2ShuyqwJdr+oNqWwTUmQw== +esbuild-openbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz#db4c8495287a350a6790de22edea247a57c5d47b" + integrity sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw== -esbuild-sunos-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.47.tgz#3f19612dcdb89ba6c65283a7ff6e16f8afbf8aaa" - integrity sha512-uOeSgLUwukLioAJOiGYm3kNl+1wJjgJA8R671GYgcPgCx7QR73zfvYqXFFcIO93/nBdIbt5hd8RItqbbf3HtAQ== +esbuild-sunos-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz#54287ee3da73d3844b721c21bc80c1dc7e1bf7da" + integrity sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw== -esbuild-windows-32@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.47.tgz#a92d279c8458d5dc319abcfeb30aa49e8f2e6f7f" - integrity sha512-H0fWsLTp2WBfKLBgwYT4OTfFly4Im/8B5f3ojDv1Kx//kiubVY0IQunP2Koc/fr/0wI7hj3IiBDbSrmKlrNgLQ== +esbuild-windows-32@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz#f8aaf9a5667630b40f0fb3aa37bf01bbd340ce31" + integrity sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w== -esbuild-windows-64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.47.tgz#2564c3fcf0c23d701edb71af8c52d3be4cec5f8a" - integrity sha512-/Pk5jIEH34T68r8PweKRi77W49KwanZ8X6lr3vDAtOlH5EumPE4pBHqkCUdELanvsT14yMXLQ/C/8XPi1pAtkQ== +esbuild-windows-64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz#bf54b51bd3e9b0f1886ffdb224a4176031ea0af4" + integrity sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ== -esbuild-windows-arm64@0.14.47: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.47.tgz#86d9db1a22d83360f726ac5fba41c2f625db6878" - integrity sha512-HFSW2lnp62fl86/qPQlqw6asIwCnEsEoNIL1h2uVMgakddf+vUuMcCbtUY1i8sst7KkgHrVKCJQB33YhhOweCQ== +esbuild-windows-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz#937d15675a15e4b0e4fafdbaa3a01a776a2be982" + integrity sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg== -esbuild@^0.14.27: - version "0.14.47" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.47.tgz#0d6415f6bd8eb9e73a58f7f9ae04c5276cda0e4d" - integrity sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA== +esbuild@^0.14.47: + version "0.14.54" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.54.tgz#8b44dcf2b0f1a66fc22459943dccf477535e9aa2" + integrity sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA== optionalDependencies: - esbuild-android-64 "0.14.47" - esbuild-android-arm64 "0.14.47" - esbuild-darwin-64 "0.14.47" - esbuild-darwin-arm64 "0.14.47" - esbuild-freebsd-64 "0.14.47" - esbuild-freebsd-arm64 "0.14.47" - esbuild-linux-32 "0.14.47" - esbuild-linux-64 "0.14.47" - esbuild-linux-arm "0.14.47" - esbuild-linux-arm64 "0.14.47" - esbuild-linux-mips64le "0.14.47" - esbuild-linux-ppc64le "0.14.47" - esbuild-linux-riscv64 "0.14.47" - esbuild-linux-s390x "0.14.47" - esbuild-netbsd-64 "0.14.47" - esbuild-openbsd-64 "0.14.47" - esbuild-sunos-64 "0.14.47" - esbuild-windows-32 "0.14.47" - esbuild-windows-64 "0.14.47" - esbuild-windows-arm64 "0.14.47" + "@esbuild/linux-loong64" "0.14.54" + esbuild-android-64 "0.14.54" + esbuild-android-arm64 "0.14.54" + esbuild-darwin-64 "0.14.54" + esbuild-darwin-arm64 "0.14.54" + esbuild-freebsd-64 "0.14.54" + esbuild-freebsd-arm64 "0.14.54" + esbuild-linux-32 "0.14.54" + esbuild-linux-64 "0.14.54" + esbuild-linux-arm "0.14.54" + esbuild-linux-arm64 "0.14.54" + esbuild-linux-mips64le "0.14.54" + esbuild-linux-ppc64le "0.14.54" + esbuild-linux-riscv64 "0.14.54" + esbuild-linux-s390x "0.14.54" + esbuild-netbsd-64 "0.14.54" + esbuild-openbsd-64 "0.14.54" + esbuild-sunos-64 "0.14.54" + esbuild-windows-32 "0.14.54" + esbuild-windows-64 "0.14.54" + esbuild-windows-arm64 "0.14.54" estree-walker@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== -execa@^5.1.1: +execa@^5.0.0, execa@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -558,6 +571,26 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +internal-ip@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-7.0.0.tgz#5b1c6a9d7e188aa73a1b69717daf50c8d8ed774f" + integrity sha512-qE4TeD4brqC45Vq/+VASeMiS1KRyfBkR6HT2sh9pZVVCzSjPkaCEfKFU+dL0PRv7NHJtvoKN2r82G6wTfzorkw== + dependencies: + default-gateway "^6.0.3" + ipaddr.js "^2.0.1" + is-ip "^3.1.0" + p-event "^4.2.0" + +ip-regex@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5" + integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q== + +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -584,6 +617,13 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-ip@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-ip/-/is-ip-3.1.0.tgz#2ae5ddfafaf05cb8008a62093cf29734f657c5d8" + integrity sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q== + dependencies: + ip-regex "^4.0.0" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -604,10 +644,10 @@ jiti@^1.13.0: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.14.0.tgz#5350fff532a4d891ca4bcd700c47c1f40e6ee326" integrity sha512-4IwstlaKQc9vCTC+qUXLM1hajy2ImiL9KnLvVYiaHOtS/v3wRjhLlGl121AmgDgx/O43uKmxownJghS5XMya2A== -kleur@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.4.tgz#8c202987d7e577766d039a8cd461934c01cda04d" - integrity sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA== +kleur@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" + integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== kolorist@^1.5.1: version "1.5.1" @@ -710,6 +750,18 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +p-event@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" + integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== + dependencies: + p-timeout "^3.1.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + p-limit@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" @@ -724,6 +776,13 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-timeout@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -764,10 +823,10 @@ picomatch@^2.2.2: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== -postcss@^8.4.13: - version "8.4.14" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf" - integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== +postcss@^8.4.16: + version "8.4.16" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" + integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== dependencies: nanoid "^3.3.4" picocolors "^1.0.0" @@ -785,7 +844,7 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -resolve@^1.22.0: +resolve@^1.22.1: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -799,10 +858,10 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rollup@^2.59.0: - version "2.75.7" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.75.7.tgz#221ff11887ae271e37dcc649ba32ce1590aaa0b9" - integrity sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ== +"rollup@>=2.75.6 <2.77.0 || ~2.77.0": + version "2.77.3" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.77.3.tgz#8f00418d3a2740036e15deb653bed1a90ee0cc12" + integrity sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g== optionalDependencies: fsevents "~2.3.2" @@ -926,15 +985,15 @@ unocss@^0.39.3: "@unocss/transformer-variant-group" "0.39.3" "@unocss/vite" "0.39.3" -vite@^2.9.12: - version "2.9.12" - resolved "https://registry.yarnpkg.com/vite/-/vite-2.9.12.tgz#b1d636b0a8ac636afe9d83e3792d4895509a941b" - integrity sha512-suxC36dQo9Rq1qMB2qiRorNJtJAdxguu5TMvBHOc/F370KvqAe9t48vYp+/TbPKRNrMh/J55tOUmkuIqstZaew== +vite@^3.0.9: + version "3.0.9" + resolved "https://registry.yarnpkg.com/vite/-/vite-3.0.9.tgz#45fac22c2a5290a970f23d66c1aef56a04be8a30" + integrity sha512-waYABTM+G6DBTCpYAxvevpG50UOlZuynR0ckTK5PawNVt7ebX6X7wNXHaGIO6wYYFXSM7/WcuFuO2QzhBB6aMw== dependencies: - esbuild "^0.14.27" - postcss "^8.4.13" - resolve "^1.22.0" - rollup "^2.59.0" + esbuild "^0.14.47" + postcss "^8.4.16" + resolve "^1.22.1" + rollup ">=2.75.6 <2.77.0 || ~2.77.0" optionalDependencies: fsevents "~2.3.2" diff --git a/tooling/cli/Cargo.lock b/tooling/cli/Cargo.lock index 646219416..0ca964b02 100644 --- a/tooling/cli/Cargo.lock +++ b/tooling/cli/Cargo.lock @@ -127,18 +127,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a32fd6af2b5827bce66c29053ba0e7c42b9dcab01835835058558c10851a46b" -[[package]] -name = "bicycle" -version = "0.1.0" -source = "git+https://github.com/BrainiumLLC/bicycle?rev=28080e0c6fa4067d9dd1b0f2b7322b6b32178e1f#28080e0c6fa4067d9dd1b0f2b7322b6b32178e1f" -dependencies = [ - "handlebars 3.5.5", - "log", - "serde", - "serde_json", - "thiserror", -] - [[package]] name = "bit_field" version = "0.10.1" @@ -199,16 +187,6 @@ dependencies = [ "byte-tools", ] -[[package]] -name = "bossy" -version = "0.2.1" -source = "git+https://github.com/lucasfernog/bossy?branch=fix/winapi-features#83ee04daddbc9b985b5f8dcf54d7229f0542d41d" -dependencies = [ - "libc", - "log", - "winapi 0.3.9", -] - [[package]] name = "bstr" version = "0.2.17" @@ -272,13 +250,10 @@ dependencies = [ [[package]] name = "cargo-mobile" version = "0.1.0" -source = "git+https://github.com/tauri-apps/cargo-mobile?branch=dev#32de2201d4a607c2d4b910cc2a33d052fe852bd8" +source = "git+https://github.com/tauri-apps/cargo-mobile?branch=dev#9733784cbb8af4fe0accc634463ff58424c88e62" dependencies = [ - "bicycle", - "bossy", "cocoa", "colored 1.9.3", - "const-utf16", "core-foundation 0.7.0", "deunicode", "dunce", @@ -286,20 +261,20 @@ dependencies = [ "english-numbers", "env_logger 0.7.1", "freedesktop_entry_parser", + "handlebars 3.5.5", "heck 0.4.0", - "hit", "home", "ignore", "indexmap", "java-properties", "lexical-core", + "libc", "log", "objc", "objc_id", "once-cell-regex", "openssl", "path_abs", - "reserved-names", "serde", "serde_json", "structopt", @@ -307,8 +282,8 @@ dependencies = [ "thiserror", "toml", "ureq", - "windows 0.26.0", - "yes-or-no", + "winapi 0.3.9", + "windows 0.39.0", ] [[package]] @@ -483,12 +458,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "const-utf16" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90feefab165fe011746e3be2f0708b7b180fcbd9f5054ff81a454d7bd93d8285" - [[package]] name = "constant_time_eq" version = "0.1.5" @@ -1334,18 +1303,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hit" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a8b280c3c6e2a2a51b3dde2f1071b28afff0ebce59e29443b1b391e7efe32fd" -dependencies = [ - "bossy", - "log", - "once-cell-regex", - "thiserror", -] - [[package]] name = "hmac" version = "0.12.1" @@ -2740,14 +2697,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "reserved-names" -version = "0.1.0" -source = "git+https://github.com/BrainiumLLC/reserved-names#cc46545db485b13851e9136280b7d8e5a95a9d18" -dependencies = [ - "thiserror", -] - [[package]] name = "ring" version = "0.16.20" @@ -3350,12 +3299,12 @@ version = "1.0.5" dependencies = [ "anyhow", "base64", - "bossy", "cargo-mobile", "clap 3.2.7", "colored 2.0.0", "ctrlc", "dialoguer", + "dirs-next", "env_logger 0.9.0", "glob", "handlebars 4.3.1", @@ -4009,19 +3958,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "347cdcaae1addebdff584aea1f9fbc0426dedbe1315f1dcf30c7a9876401cd25" -dependencies = [ - "windows_aarch64_msvc 0.26.0", - "windows_i686_gnu 0.26.0", - "windows_i686_msvc 0.26.0", - "windows_x86_64_gnu 0.26.0", - "windows_x86_64_msvc 0.26.0", -] - [[package]] name = "windows" version = "0.37.0" @@ -4036,6 +3972,19 @@ dependencies = [ "windows_x86_64_msvc 0.37.0", ] +[[package]] +name = "windows" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1c4bd0a50ac6020f65184721f758dba47bb9fbc2133df715ec74a237b26794a" +dependencies = [ + "windows_aarch64_msvc 0.39.0", + "windows_i686_gnu 0.39.0", + "windows_i686_msvc 0.39.0", + "windows_x86_64_gnu 0.39.0", + "windows_x86_64_msvc 0.39.0", +] + [[package]] name = "windows-implement" version = "0.37.0" @@ -4065,12 +4014,6 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3263d25f1170419995b78ff10c06b949e8a986c35c208dc24333c64753a87169" -[[package]] -name = "windows_aarch64_msvc" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7758986b022add546ae53ccad31f4852ce6bd2e2c2d3cc2b1d7d06dea0b90da" - [[package]] name = "windows_aarch64_msvc" version = "0.36.1" @@ -4084,10 +4027,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2623277cb2d1c216ba3b578c0f3cf9cdebeddb6e66b1b218bb33596ea7769c3a" [[package]] -name = "windows_i686_gnu" -version = "0.26.0" +name = "windows_aarch64_msvc" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29261214caab8e589f61031ba1ccd5c3c25e61db2118a3aec4459f58ff798726" +checksum = "ec7711666096bd4096ffa835238905bb33fb87267910e154b18b44eaabb340f2" [[package]] name = "windows_i686_gnu" @@ -4102,10 +4045,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3925fd0b0b804730d44d4b6278c50f9699703ec49bcd628020f46f4ba07d9e1" [[package]] -name = "windows_i686_msvc" -version = "0.26.0" +name = "windows_i686_gnu" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43984fb3b944743142112ae926e7adeccb60f35bb81d43114f4d0fe2871f60ba" +checksum = "763fc57100a5f7042e3057e7e8d9bdd7860d330070251a73d003563a3bb49e1b" [[package]] name = "windows_i686_msvc" @@ -4120,10 +4063,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce907ac74fe331b524c1298683efbf598bb031bc84d5e274db2083696d07c57c" [[package]] -name = "windows_x86_64_gnu" -version = "0.26.0" +name = "windows_i686_msvc" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a80fc90e1ad19769e596a3f58d0776319059e21cac9069a5a2a791362ce7190" +checksum = "7bc7cbfe58828921e10a9f446fcaaf649204dcfe6c1ddd712c5eebae6bda1106" [[package]] name = "windows_x86_64_gnu" @@ -4138,10 +4081,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2babfba0828f2e6b32457d5341427dcbb577ceef556273229959ac23a10af33d" [[package]] -name = "windows_x86_64_msvc" -version = "0.26.0" +name = "windows_x86_64_gnu" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc24ddac19a0cf02ad2b32d8897f202fc1a13ef285e2d4774e6610783cc8398f" +checksum = "6868c165637d653ae1e8dc4d82c25d4f97dd6605eaa8d784b5c6e0ab2a252b65" [[package]] name = "windows_x86_64_msvc" @@ -4155,6 +4098,12 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4dd6dc7df2d84cf7b33822ed5b86318fb1781948e9663bacd047fc9dd52259d" +[[package]] +name = "windows_x86_64_msvc" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4d40883ae9cae962787ca76ba76390ffa29214667a111db9e0a1ad8377e809" + [[package]] name = "winreg" version = "0.10.1" @@ -4189,16 +4138,6 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" -[[package]] -name = "yes-or-no" -version = "0.1.0" -source = "git+https://github.com/BrainiumLLC/yes-or-no#71d932693601fcf93ff906b90ad61f85b52117c5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "zeroize" version = "1.5.5" diff --git a/tooling/cli/Cargo.toml b/tooling/cli/Cargo.toml index 9c2b987ab..aec9d268e 100644 --- a/tooling/cli/Cargo.toml +++ b/tooling/cli/Cargo.toml @@ -26,14 +26,11 @@ include = [ name = "cargo-tauri" path = "src/main.rs" -[patch.crates-io] -bossy = { git = "https://github.com/lucasfernog/bossy", branch = "fix/winapi-features" } - [dependencies] # cargo-mobile = { path = "../../../cargo-mobile/", default-features = false } cargo-mobile = { git = "https://github.com/tauri-apps/cargo-mobile", branch = "dev", default-features = false } -bossy = "0.2" textwrap = { version = "0.11.0", features = ["term_size"] } +dirs-next = "2.0" thiserror = "1" clap = { version = "3.2", features = [ "derive" ] } anyhow = "1.0" diff --git a/tooling/cli/schema.json b/tooling/cli/schema.json index 91ec0a399..a8b1bd06b 100644 --- a/tooling/cli/schema.json +++ b/tooling/cli/schema.json @@ -2433,7 +2433,7 @@ "type": "object", "properties": { "developmentTeam": { - "description": "The development team. This value is required for iOS development because code signing is enforced. The `APPLE_DEVELOPMENT_TEAM` environment variable can be set to overwrite it.", + "description": "The development team. This value is required for iOS development because code signing is enforced. The `TAURI_APPLE_DEVELOPMENT_TEAM` environment variable can be set to overwrite it.", "type": [ "string", "null" diff --git a/tooling/cli/src/build.rs b/tooling/cli/src/build.rs index 332058853..b0f2ecd5f 100644 --- a/tooling/cli/src/build.rs +++ b/tooling/cli/src/build.rs @@ -83,6 +83,8 @@ pub fn command(mut options: Options) -> Result<()> { let config_guard = config.lock().unwrap(); let config_ = config_guard.as_ref().unwrap(); + let mut interface = AppInterface::new(config_)?; + let bundle_identifier_source = match config_.find_bundle_identifier_overwriter() { Some(source) if source == MERGE_CONFIG_EXTENSION_NAME => merge_config_path.unwrap_or(source), Some(source) => source, @@ -154,7 +156,6 @@ pub fn command(mut options: Options) -> Result<()> { list.extend(config_.build.features.clone().unwrap_or_default()); } - let mut interface = AppInterface::new(config_)?; let app_settings = interface.app_settings(); let interface_options = options.clone().into(); diff --git a/tooling/cli/src/dev.rs b/tooling/cli/src/dev.rs index 7db4a57a4..53502e2d6 100644 --- a/tooling/cli/src/dev.rs +++ b/tooling/cli/src/dev.rs @@ -49,7 +49,7 @@ pub struct Options { pub features: Option>, /// Exit on panic #[clap(short, long)] - exit_on_panic: bool, + pub exit_on_panic: bool, /// JSON string or path to JSON file to merge with tauri.conf.json #[clap(short, long)] pub config: Option, @@ -74,6 +74,15 @@ pub fn command(options: Options) -> Result<()> { } fn command_internal(mut options: Options) -> Result<()> { + let mut interface = setup(&mut options)?; + let exit_on_panic = options.exit_on_panic; + let no_watch = options.no_watch; + interface.dev(options.into(), move |status, reason| { + on_dev_exit(status, reason, exit_on_panic, no_watch) + }) +} + +pub fn setup(options: &mut Options) -> Result { let tauri_path = tauri_dir(); options.config = if let Some(config) = &options.config { Some(if config.starts_with('{') { @@ -89,6 +98,8 @@ fn command_internal(mut options: Options) -> Result<()> { let config = get_config(options.config.as_deref())?; + let interface = AppInterface::new(config.lock().unwrap().as_ref().unwrap())?; + if let Some(before_dev) = config .lock() .unwrap() @@ -261,13 +272,7 @@ fn command_internal(mut options: Options) -> Result<()> { } } - let mut interface = AppInterface::new(config.lock().unwrap().as_ref().unwrap())?; - - let exit_on_panic = options.exit_on_panic; - let no_watch = options.no_watch; - interface.dev(options.into(), move |status, reason| { - on_dev_exit(status, reason, exit_on_panic, no_watch) - }) + Ok(interface) } fn on_dev_exit(status: ExitStatus, reason: ExitReason, exit_on_panic: bool, no_watch: bool) { diff --git a/tooling/cli/src/helpers/flock.rs b/tooling/cli/src/helpers/flock.rs new file mode 100644 index 000000000..0ab6ae36a --- /dev/null +++ b/tooling/cli/src/helpers/flock.rs @@ -0,0 +1,363 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +// taken from https://github.com/rust-lang/cargo/blob/b0c9586f4cbf426914df47c65de38ea323772c74/src/cargo/util/flock.rs +#![allow(dead_code)] + +use std::fs::{create_dir_all, File, OpenOptions}; +use std::io; +use std::io::{Read, Seek, SeekFrom, Write}; +use std::path::{Path, PathBuf}; + +use crate::Result; +use anyhow::Context as _; +use sys::*; + +#[derive(Debug)] +pub struct FileLock { + f: Option, + path: PathBuf, + state: State, +} + +#[derive(PartialEq, Debug)] +enum State { + Unlocked, + Shared, + Exclusive, +} + +impl FileLock { + /// Returns the underlying file handle of this lock. + pub fn file(&self) -> &File { + self.f.as_ref().unwrap() + } + + /// Returns the underlying path that this lock points to. + /// + /// Note that special care must be taken to ensure that the path is not + /// referenced outside the lifetime of this lock. + pub fn path(&self) -> &Path { + assert_ne!(self.state, State::Unlocked); + &self.path + } + + /// Returns the parent path containing this file + pub fn parent(&self) -> &Path { + assert_ne!(self.state, State::Unlocked); + self.path.parent().unwrap() + } +} + +impl Read for FileLock { + fn read(&mut self, buf: &mut [u8]) -> io::Result { + self.file().read(buf) + } +} + +impl Seek for FileLock { + fn seek(&mut self, to: SeekFrom) -> io::Result { + self.file().seek(to) + } +} + +impl Write for FileLock { + fn write(&mut self, buf: &[u8]) -> io::Result { + self.file().write(buf) + } + + fn flush(&mut self) -> io::Result<()> { + self.file().flush() + } +} + +impl Drop for FileLock { + fn drop(&mut self) { + if self.state != State::Unlocked { + if let Some(f) = self.f.take() { + let _ = unlock(&f); + } + } + } +} + +/// Opens exclusive access to a file, returning the locked version of a +/// file. +/// +/// This function will create a file at `path` if it doesn't already exist +/// (including intermediate directories), and then it will acquire an +/// exclusive lock on `path`. If the process must block waiting for the +/// lock, the `msg` is logged. +/// +/// The returned file can be accessed to look at the path and also has +/// read/write access to the underlying file. +pub fn open_rw

(path: P, msg: &str) -> Result +where + P: AsRef, +{ + open( + path.as_ref(), + OpenOptions::new().read(true).write(true).create(true), + State::Exclusive, + msg, + ) +} + +/// Opens shared access to a file, returning the locked version of a file. +/// +/// This function will fail if `path` doesn't already exist, but if it does +/// then it will acquire a shared lock on `path`. If the process must block +/// waiting for the lock, the `msg` is logged. +/// +/// The returned file can be accessed to look at the path and also has read +/// access to the underlying file. Any writes to the file will return an +/// error. +pub fn open_ro

(path: P, msg: &str) -> Result +where + P: AsRef, +{ + open( + path.as_ref(), + OpenOptions::new().read(true), + State::Shared, + msg, + ) +} + +fn open(path: &Path, opts: &OpenOptions, state: State, msg: &str) -> Result { + // If we want an exclusive lock then if we fail because of NotFound it's + // likely because an intermediate directory didn't exist, so try to + // create the directory and then continue. + let f = opts + .open(&path) + .or_else(|e| { + if e.kind() == io::ErrorKind::NotFound && state == State::Exclusive { + create_dir_all(path.parent().unwrap())?; + Ok(opts.open(&path)?) + } else { + Err(anyhow::Error::from(e)) + } + }) + .with_context(|| format!("failed to open: {}", path.display()))?; + match state { + State::Exclusive => { + acquire(msg, path, &|| try_lock_exclusive(&f), &|| { + lock_exclusive(&f) + })?; + } + State::Shared => { + acquire(msg, path, &|| try_lock_shared(&f), &|| lock_shared(&f))?; + } + State::Unlocked => {} + } + Ok(FileLock { + f: Some(f), + path: path.to_path_buf(), + state, + }) +} + +/// Acquires a lock on a file in a "nice" manner. +/// +/// Almost all long-running blocking actions in Cargo have a status message +/// associated with them as we're not sure how long they'll take. Whenever a +/// conflicted file lock happens, this is the case (we're not sure when the lock +/// will be released). +/// +/// This function will acquire the lock on a `path`, printing out a nice message +/// to the console if we have to wait for it. It will first attempt to use `try` +/// to acquire a lock on the crate, and in the case of contention it will emit a +/// status message based on `msg` to `config`'s shell, and then use `block` to +/// block waiting to acquire a lock. +/// +/// Returns an error if the lock could not be acquired or if any error other +/// than a contention error happens. +fn acquire( + msg: &str, + path: &Path, + lock_try: &dyn Fn() -> io::Result<()>, + lock_block: &dyn Fn() -> io::Result<()>, +) -> Result<()> { + // File locking on Unix is currently implemented via `flock`, which is known + // to be broken on NFS. We could in theory just ignore errors that happen on + // NFS, but apparently the failure mode [1] for `flock` on NFS is **blocking + // forever**, even if the "non-blocking" flag is passed! + // + // As a result, we just skip all file locks entirely on NFS mounts. That + // should avoid calling any `flock` functions at all, and it wouldn't work + // there anyway. + // + // [1]: https://github.com/rust-lang/cargo/issues/2615 + if is_on_nfs_mount(path) { + return Ok(()); + } + + match lock_try() { + Ok(()) => return Ok(()), + + // In addition to ignoring NFS which is commonly not working we also + // just ignore locking on filesystems that look like they don't + // implement file locking. + Err(e) if error_unsupported(&e) => return Ok(()), + + Err(e) => { + if !error_contended(&e) { + let e = anyhow::Error::from(e); + let cx = format!("failed to lock file: {}", path.display()); + return Err(e.context(cx)); + } + } + } + let msg = format!("waiting for file lock on {}", msg); + log::info!(action = "Blocking"; "{}", &msg); + + lock_block().with_context(|| format!("failed to lock file: {}", path.display()))?; + return Ok(()); + + #[cfg(all(target_os = "linux", not(target_env = "musl")))] + fn is_on_nfs_mount(path: &Path) -> bool { + use std::ffi::CString; + use std::mem; + use std::os::unix::prelude::*; + + let path = match CString::new(path.as_os_str().as_bytes()) { + Ok(path) => path, + Err(_) => return false, + }; + + unsafe { + let mut buf: libc::statfs = mem::zeroed(); + let r = libc::statfs(path.as_ptr(), &mut buf); + + r == 0 && buf.f_type as u32 == libc::NFS_SUPER_MAGIC as u32 + } + } + + #[cfg(any(not(target_os = "linux"), target_env = "musl"))] + fn is_on_nfs_mount(_path: &Path) -> bool { + false + } +} + +#[cfg(unix)] +mod sys { + use std::fs::File; + use std::io::{Error, Result}; + use std::os::unix::io::AsRawFd; + + pub(super) fn lock_shared(file: &File) -> Result<()> { + flock(file, libc::LOCK_SH) + } + + pub(super) fn lock_exclusive(file: &File) -> Result<()> { + flock(file, libc::LOCK_EX) + } + + pub(super) fn try_lock_shared(file: &File) -> Result<()> { + flock(file, libc::LOCK_SH | libc::LOCK_NB) + } + + pub(super) fn try_lock_exclusive(file: &File) -> Result<()> { + flock(file, libc::LOCK_EX | libc::LOCK_NB) + } + + pub(super) fn unlock(file: &File) -> Result<()> { + flock(file, libc::LOCK_UN) + } + + pub(super) fn error_contended(err: &Error) -> bool { + err.raw_os_error().map_or(false, |x| x == libc::EWOULDBLOCK) + } + + pub(super) fn error_unsupported(err: &Error) -> bool { + match err.raw_os_error() { + // Unfortunately, depending on the target, these may or may not be the same. + // For targets in which they are the same, the duplicate pattern causes a warning. + #[allow(unreachable_patterns)] + Some(libc::ENOTSUP | libc::EOPNOTSUPP) => true, + Some(libc::ENOSYS) => true, + _ => false, + } + } + + #[cfg(not(target_os = "solaris"))] + fn flock(file: &File, flag: libc::c_int) -> Result<()> { + let ret = unsafe { libc::flock(file.as_raw_fd(), flag) }; + if ret < 0 { + Err(Error::last_os_error()) + } else { + Ok(()) + } + } + + #[cfg(target_os = "solaris")] + fn flock(file: &File, flag: libc::c_int) -> Result<()> { + // Solaris lacks flock(), so simply succeed with a no-op + Ok(()) + } +} + +#[cfg(windows)] +mod sys { + use std::fs::File; + use std::io::{Error, Result}; + use std::mem; + use std::os::windows::io::AsRawHandle; + + use winapi::shared::minwindef::DWORD; + use winapi::shared::winerror::{ERROR_INVALID_FUNCTION, ERROR_LOCK_VIOLATION}; + use winapi::um::fileapi::{LockFileEx, UnlockFile}; + use winapi::um::minwinbase::{LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY}; + + pub(super) fn lock_shared(file: &File) -> Result<()> { + lock_file(file, 0) + } + + pub(super) fn lock_exclusive(file: &File) -> Result<()> { + lock_file(file, LOCKFILE_EXCLUSIVE_LOCK) + } + + pub(super) fn try_lock_shared(file: &File) -> Result<()> { + lock_file(file, LOCKFILE_FAIL_IMMEDIATELY) + } + + pub(super) fn try_lock_exclusive(file: &File) -> Result<()> { + lock_file(file, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY) + } + + pub(super) fn error_contended(err: &Error) -> bool { + err + .raw_os_error() + .map_or(false, |x| x == ERROR_LOCK_VIOLATION as i32) + } + + pub(super) fn error_unsupported(err: &Error) -> bool { + err + .raw_os_error() + .map_or(false, |x| x == ERROR_INVALID_FUNCTION as i32) + } + + pub(super) fn unlock(file: &File) -> Result<()> { + unsafe { + let ret = UnlockFile(file.as_raw_handle(), 0, 0, !0, !0); + if ret == 0 { + Err(Error::last_os_error()) + } else { + Ok(()) + } + } + } + + fn lock_file(file: &File, flags: DWORD) -> Result<()> { + unsafe { + let mut overlapped = mem::zeroed(); + let ret = LockFileEx(file.as_raw_handle(), flags, 0, !0, !0, &mut overlapped); + if ret == 0 { + Err(Error::last_os_error()) + } else { + Ok(()) + } + } + } +} diff --git a/tooling/cli/src/helpers/mod.rs b/tooling/cli/src/helpers/mod.rs index 5284a6ec5..a3cb56a01 100644 --- a/tooling/cli/src/helpers/mod.rs +++ b/tooling/cli/src/helpers/mod.rs @@ -4,6 +4,7 @@ pub mod app_paths; pub mod config; +pub mod flock; pub mod framework; pub mod template; pub mod updater_signature; diff --git a/tooling/cli/src/interface/mod.rs b/tooling/cli/src/interface/mod.rs index 6133531be..e946f071d 100644 --- a/tooling/cli/src/interface/mod.rs +++ b/tooling/cli/src/interface/mod.rs @@ -12,7 +12,12 @@ use std::{ use crate::helpers::config::Config; use tauri_bundler::bundle::{PackageType, Settings, SettingsBuilder}; -pub use rust::{Options, Rust as AppInterface}; +pub use rust::{MobileOptions, Options, Rust as AppInterface}; + +pub trait DevProcess { + fn kill(&mut self) -> std::io::Result<()>; + fn try_wait(&mut self) -> std::io::Result>; +} pub trait AppSettings { fn get_package_settings(&self) -> tauri_bundler::PackageSettings; @@ -83,4 +88,9 @@ pub trait Interface: Sized { options: Options, on_exit: F, ) -> crate::Result<()>; + fn mobile_dev crate::Result>>( + &mut self, + options: MobileOptions, + runner: R, + ) -> crate::Result<()>; } diff --git a/tooling/cli/src/interface/rust.rs b/tooling/cli/src/interface/rust.rs index 228c5bb5c..4e787e05e 100644 --- a/tooling/cli/src/interface/rust.rs +++ b/tooling/cli/src/interface/rust.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: MIT use std::{ + collections::HashMap, ffi::OsStr, fs::{File, FileType}, io::{Read, Write}, @@ -10,7 +11,6 @@ use std::{ process::ExitStatus, str::FromStr, sync::{ - atomic::{AtomicBool, Ordering}, mpsc::{channel, sync_channel}, Arc, Mutex, }, @@ -24,13 +24,12 @@ use log::warn; use log::{debug, info}; use notify::{watcher, DebouncedEvent, RecursiveMode, Watcher}; use serde::Deserialize; -use shared_child::SharedChild; use tauri_bundler::{ AppCategory, BundleBinary, BundleSettings, DebianSettings, MacOsSettings, PackageSettings, UpdaterSettings, WindowsSettings, }; -use super::{AppSettings, ExitReason, Interface}; +use super::{AppSettings, DevProcess, ExitReason, Interface}; use crate::helpers::{ app_paths::tauri_dir, config::{reload as reload_config, wix_settings, Config}, @@ -40,7 +39,7 @@ mod desktop; mod manifest; use manifest::{rewrite_manifest, Manifest}; -#[derive(Debug, Clone)] +#[derive(Debug, Default, Clone)] pub struct Options { pub runner: Option, pub debug: bool, @@ -79,30 +78,13 @@ impl From for Options { } } -pub struct DevChild { - manually_killed_app: Arc, - build_child: Arc, - app_child: Arc>>>, -} - -impl DevChild { - fn kill(&self) -> std::io::Result<()> { - if let Some(child) = &*self.app_child.lock().unwrap() { - child.kill()?; - } else { - self.build_child.kill()?; - } - self.manually_killed_app.store(true, Ordering::Relaxed); - Ok(()) - } - - fn try_wait(&self) -> std::io::Result> { - if let Some(child) = &*self.app_child.lock().unwrap() { - child.try_wait() - } else { - self.build_child.try_wait() - } - } +#[derive(Debug, Clone)] +pub struct MobileOptions { + pub debug: bool, + pub features: Option>, + pub args: Vec, + pub config: Option, + pub no_watch: bool, } #[derive(Debug)] @@ -144,8 +126,10 @@ impl Interface for Rust { std::env::set_var("MACOSX_DEPLOYMENT_TARGET", minimum_system_version); } + let app_settings = RustAppSettings::new(config, manifest)?; + Ok(Self { - app_settings: RustAppSettings::new(config, manifest)?, + app_settings, config_features: config.build.features.clone().unwrap_or_default(), product_name: config.package.product_name.clone(), available_targets: None, @@ -173,28 +157,56 @@ impl Interface for Rust { fn dev( &mut self, - options: Options, + mut options: Options, on_exit: F, ) -> crate::Result<()> { let on_exit = Arc::new(on_exit); - let on_exit_ = on_exit.clone(); + let run_args = dev_options( + &mut options.args, + &mut options.features, + self.app_settings.manifest.features(), + ); if options.no_watch { let (tx, rx) = sync_channel(1); - self.run_dev(options, move |status, reason| { + self.run_dev(options, run_args, move |status, reason| { tx.send(()).unwrap(); - on_exit_(status, reason) + on_exit(status, reason) })?; rx.recv().unwrap(); Ok(()) } else { - let child = self.run_dev(options.clone(), move |status, reason| { - on_exit_(status, reason) - })?; + let config = options.config.clone(); + let run = Arc::new(|rust: &mut Rust| { + let on_exit = on_exit.clone(); + rust.run_dev(options.clone(), run_args.clone(), move |status, reason| { + on_exit(status, reason) + }) + }); + self.run_dev_watcher(config, run) + } + } - self.run_dev_watcher(child, options, on_exit) + fn mobile_dev crate::Result>>( + &mut self, + mut options: MobileOptions, + runner: R, + ) -> crate::Result<()> { + dev_options( + &mut options.args, + &mut options.features, + self.app_settings.manifest.features(), + ); + + if options.no_watch { + runner(options)?; + Ok(()) + } else { + let config = options.config.clone(); + let run = Arc::new(|_rust: &mut Rust| runner(options.clone())); + self.run_dev_watcher(config, run) } } } @@ -223,50 +235,54 @@ fn lookup(dir: &Path, mut f: F) { } } +fn dev_options( + args: &mut Vec, + features: &mut Option>, + manifest_features: HashMap>, +) -> Vec { + if !args.contains(&"--no-default-features".into()) { + let enable_features: Vec = manifest_features + .get("default") + .cloned() + .unwrap_or_default() + .into_iter() + .filter(|feature| { + if let Some(manifest_feature) = manifest_features.get(feature) { + !manifest_feature.contains(&"tauri/custom-protocol".into()) + } else { + feature != "tauri/custom-protocol" + } + }) + .collect(); + args.push("--no-default-features".into()); + if !enable_features.is_empty() { + features.get_or_insert(Vec::new()).extend(enable_features); + } + } + + let mut dev_args = Vec::new(); + let mut run_args = Vec::new(); + let mut reached_run_args = false; + for arg in args.clone() { + if reached_run_args { + run_args.push(arg); + } else if arg == "--" { + reached_run_args = true; + } else { + dev_args.push(arg); + } + } + *args = dev_args; + run_args +} + impl Rust { fn run_dev( &mut self, - mut options: Options, + options: Options, + run_args: Vec, on_exit: F, - ) -> crate::Result { - if !options.args.contains(&"--no-default-features".into()) { - let manifest_features = self.app_settings.manifest.features(); - let enable_features: Vec = manifest_features - .get("default") - .cloned() - .unwrap_or_default() - .into_iter() - .filter(|feature| { - if let Some(manifest_feature) = manifest_features.get(feature) { - !manifest_feature.contains(&"tauri/custom-protocol".into()) - } else { - feature != "tauri/custom-protocol" - } - }) - .collect(); - options.args.push("--no-default-features".into()); - if !enable_features.is_empty() { - options - .features - .get_or_insert(Vec::new()) - .extend(enable_features); - } - } - - let mut args = Vec::new(); - let mut run_args = Vec::new(); - let mut reached_run_args = false; - for arg in options.args.clone() { - if reached_run_args { - run_args.push(arg); - } else if arg == "--" { - reached_run_args = true; - } else { - args.push(arg); - } - } - options.args = args; - + ) -> crate::Result> { desktop::run_dev( options, run_args, @@ -276,14 +292,16 @@ impl Rust { self.product_name.clone(), on_exit, ) + .map(|c| Box::new(c) as Box) } - fn run_dev_watcher( + fn run_dev_watcher crate::Result>>( &mut self, - child: DevChild, - options: Options, - on_exit: Arc, + config: Option, + run: Arc, ) -> crate::Result<()> { + let child = run(self)?; + let process = Arc::new(Mutex::new(child)); let (tx, rx) = channel(); let tauri_path = tauri_dir(); @@ -326,7 +344,7 @@ impl Rust { } loop { - let on_exit = on_exit.clone(); + let run = run.clone(); if let Ok(event) = rx.recv() { let event_path = match event { DebouncedEvent::Create(path) => Some(path), @@ -338,7 +356,7 @@ impl Rust { if let Some(event_path) = event_path { if event_path.file_name() == Some(OsStr::new("tauri.conf.json")) { - let config = reload_config(options.config.as_deref())?; + let config = reload_config(config.as_deref())?; self.app_settings.manifest = rewrite_manifest(config.lock().unwrap().as_ref().unwrap())?; } else { @@ -353,9 +371,7 @@ impl Rust { break; } } - *p = self.run_dev(options.clone(), move |status, reason| { - on_exit(status, reason) - })?; + *p = run(self)?; } } } diff --git a/tooling/cli/src/interface/rust/desktop.rs b/tooling/cli/src/interface/rust/desktop.rs index b93a3d826..66a785a87 100644 --- a/tooling/cli/src/interface/rust/desktop.rs +++ b/tooling/cli/src/interface/rust/desktop.rs @@ -1,7 +1,8 @@ -use super::{AppSettings, DevChild, ExitReason, Options, RustAppSettings, Target}; +use super::{AppSettings, DevProcess, ExitReason, Options, RustAppSettings, Target}; use crate::CommandExt; use anyhow::Context; +#[cfg(target_os = "linux")] use heck::ToKebabCase; use shared_child::SharedChild; use std::{ @@ -15,6 +16,34 @@ use std::{ }, }; +pub struct DevChild { + manually_killed_app: Arc, + build_child: Option>, + app_child: Arc>>>, +} + +impl DevProcess for DevChild { + fn kill(&mut self) -> std::io::Result<()> { + if let Some(child) = &*self.app_child.lock().unwrap() { + child.kill()?; + } else if let Some(child) = &self.build_child { + child.kill()?; + } + self.manually_killed_app.store(true, Ordering::Relaxed); + Ok(()) + } + + fn try_wait(&mut self) -> std::io::Result> { + if let Some(child) = &*self.app_child.lock().unwrap() { + child.try_wait() + } else if let Some(child) = &self.build_child { + child.try_wait() + } else { + unreachable!() + } + } +} + pub fn run_dev( options: Options, run_args: Vec, @@ -23,7 +52,7 @@ pub fn run_dev( app_settings: &RustAppSettings, product_name: Option, on_exit: F, -) -> crate::Result { +) -> crate::Result { let bin_path = app_settings.app_binary_path(&options)?; let manually_killed_app = Arc::new(AtomicBool::default()); @@ -73,7 +102,7 @@ pub fn run_dev( Ok(DevChild { manually_killed_app, - build_child, + build_child: Some(build_child), app_child, }) } diff --git a/tooling/cli/src/lib.rs b/tooling/cli/src/lib.rs index 5fc4b6433..307485324 100644 --- a/tooling/cli/src/lib.rs +++ b/tooling/cli/src/lib.rs @@ -14,7 +14,7 @@ mod mobile; mod plugin; mod signer; -use clap::{FromArgMatches, IntoApp, Parser, Subcommand}; +use clap::{FromArgMatches, IntoApp, Parser, Subcommand, ValueEnum}; use env_logger::fmt::Color; use env_logger::Builder; use log::{debug, log_enabled, Level}; @@ -23,9 +23,33 @@ use std::io::{BufReader, Write}; use std::process::{exit, Command, ExitStatus, Output, Stdio}; use std::{ ffi::OsString, + fmt::Display, sync::{Arc, Mutex}, }; +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +pub enum RunMode { + Desktop, + #[cfg(target_os = "macos")] + Ios, + Android, +} + +impl Display for RunMode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}", + match self { + Self::Desktop => "desktop", + #[cfg(target_os = "macos")] + Self::Ios => "iOS", + Self::Android => "android", + } + ) + } +} + #[derive(Deserialize)] pub struct VersionMetadata { tauri: String, diff --git a/tooling/cli/src/mobile/android.rs b/tooling/cli/src/mobile/android.rs index ba3f7f030..290ce1fe2 100644 --- a/tooling/cli/src/mobile/android.rs +++ b/tooling/cli/src/mobile/android.rs @@ -6,10 +6,11 @@ use cargo_mobile::{ android::{ adb, config::{Config as AndroidConfig, Metadata as AndroidMetadata}, - device::Device, + device::{Device, RunError}, env::{Env, Error as EnvError}, target::{BuildError, Target}, }, + config::Config, device::PromptError, opts::{NoiseLevel, Profile}, os, @@ -19,12 +20,15 @@ use cargo_mobile::{ use clap::{Parser, Subcommand}; use super::{ - ensure_init, get_config, get_metadata, + ensure_init, get_config, init::{command as init_command, Options as InitOptions}, - Target as MobileTarget, + write_options, CliOptions, DevChild, Target as MobileTarget, +}; +use crate::{ + helpers::{config::get as get_tauri_config, flock}, + interface::{AppSettings, DevProcess, Interface, MobileOptions, Options as InterfaceOptions}, + Result, }; -use crate::helpers::config::get as get_tauri_config; -use crate::Result; pub(crate) mod project; @@ -32,16 +36,24 @@ pub(crate) mod project; enum Error { #[error(transparent)] EnvInitFailed(EnvError), + #[error(transparent)] + InitDotCargo(super::init::Error), #[error("invalid tauri configuration: {0}")] InvalidTauriConfig(String), #[error("{0}")] ProjectNotInitialized(String), #[error(transparent)] OpenFailed(os::OpenFileError), + #[error("{0}")] + DevFailed(String), #[error(transparent)] BuildFailed(BuildError), + #[error(transparent)] + RunFailed(RunError), #[error("{0}")] TargetInvalid(String), + #[error(transparent)] + FailedToPromptForDevice(PromptError), } #[derive(Parser)] @@ -68,9 +80,44 @@ pub struct BuildOptions { value_parser(clap::builder::PossibleValuesParser::new(["aarch64", "armv7", "i686", "x86_64"])) )] targets: Option>, - /// Builds with the debug flag + /// Builds with the release flag #[clap(short, long)] - debug: bool, + release: bool, +} + +#[derive(Debug, Clone, Parser)] +#[clap(about = "Android dev")] +pub struct DevOptions { + /// List of cargo features to activate + #[clap(short, long, multiple_occurrences(true), multiple_values(true))] + pub features: Option>, + /// Exit on panic + #[clap(short, long)] + exit_on_panic: bool, + /// JSON string or path to JSON file to merge with tauri.conf.json + #[clap(short, long)] + pub config: Option, + /// Disable the file watcher + #[clap(long)] + pub no_watch: bool, + /// Open Android Studio instead of trying to run on a connected device + #[clap(short, long)] + pub open: bool, +} + +impl From for crate::dev::Options { + fn from(options: DevOptions) -> Self { + Self { + runner: None, + target: None, + features: options.features, + exit_on_panic: options.exit_on_panic, + config: options.config, + release_mode: false, + args: Vec::new(), + no_watch: options.no_watch, + } + } } #[derive(Subcommand)] @@ -78,6 +125,7 @@ enum Commands { Init(InitOptions), /// Open project in Android Studio Open, + Dev(DevOptions), #[clap(hide(true))] Build(BuildOptions), } @@ -87,76 +135,182 @@ pub fn command(cli: Cli) -> Result<()> { Commands::Init(options) => init_command(options, MobileTarget::Android)?, Commands::Open => open()?, Commands::Build(options) => build(options)?, + Commands::Dev(options) => dev(options)?, } Ok(()) } -fn with_config( - f: impl FnOnce(&AndroidConfig, &AndroidMetadata) -> Result<(), Error>, -) -> Result<(), Error> { - let tauri_config = - get_tauri_config(None).map_err(|e| Error::InvalidTauriConfig(e.to_string()))?; - let tauri_config_guard = tauri_config.lock().unwrap(); - let tauri_config_ = tauri_config_guard.as_ref().unwrap(); - let config = get_config(tauri_config_); - let metadata = get_metadata(tauri_config_); - f(config.android(), metadata.android()) +fn with_config( + f: impl FnOnce(&Config, &AndroidConfig, &AndroidMetadata) -> Result, +) -> Result { + let (config, metadata) = { + let tauri_config = + get_tauri_config(None).map_err(|e| Error::InvalidTauriConfig(e.to_string()))?; + let tauri_config_guard = tauri_config.lock().unwrap(); + let tauri_config_ = tauri_config_guard.as_ref().unwrap(); + get_config(tauri_config_) + }; + f(&config, config.android(), metadata.android()) +} + +fn device_prompt<'a>(env: &'_ Env) -> Result, PromptError> { + let device_list = + adb::device_list(env).map_err(|cause| PromptError::detection_failed("Android", cause))?; + if !device_list.is_empty() { + let index = if device_list.len() > 1 { + prompt::list( + concat!("Detected ", "Android", " devices"), + device_list.iter(), + "device", + None, + "Device", + ) + .map_err(|cause| PromptError::prompt_failed("Android", cause))? + } else { + 0 + }; + let device = device_list.into_iter().nth(index).unwrap(); + println!( + "Detected connected device: {} with target {:?}", + device, + device.target().triple, + ); + Ok(device) + } else { + Err(PromptError::none_detected("Android")) + } +} + +fn dev(options: DevOptions) -> Result<()> { + with_config(|_, config, _metadata| { + run_dev(options, config).map_err(|e| Error::DevFailed(e.to_string())) + }) + .map_err(Into::into) +} + +fn run_dev(options: DevOptions, config: &AndroidConfig) -> Result<()> { + let mut dev_options = options.clone().into(); + let mut interface = crate::dev::setup(&mut dev_options)?; + + let bundle_identifier = { + let tauri_config = + get_tauri_config(None).map_err(|e| Error::InvalidTauriConfig(e.to_string()))?; + let tauri_config_guard = tauri_config.lock().unwrap(); + let tauri_config_ = tauri_config_guard.as_ref().unwrap(); + tauri_config_.tauri.bundle.identifier.clone() + }; + + let app_settings = interface.app_settings(); + let bin_path = app_settings.app_binary_path(&InterfaceOptions { + debug: !dev_options.release_mode, + ..Default::default() + })?; + let out_dir = bin_path.parent().unwrap(); + let _lock = flock::open_rw(&out_dir.join("lock").with_extension("android"), "Android")?; + + let open = options.open; + interface.mobile_dev( + MobileOptions { + debug: true, + features: options.features, + args: Vec::new(), + config: options.config, + no_watch: options.no_watch, + }, + |options| { + let cli_options = CliOptions { + features: options.features.clone(), + args: options.args.clone(), + vars: Default::default(), + }; + write_options(cli_options, &bundle_identifier, MobileTarget::Android)?; + + if open { + open_dev(config) + } else { + match run(options) { + Ok(c) => Ok(Box::new(c) as Box), + Err(Error::FailedToPromptForDevice(e)) => { + log::error!("{}", e); + open_dev(config) + } + Err(e) => Err(e.into()), + } + } + }, + ) +} + +fn open_dev(config: &AndroidConfig) -> ! { + log::info!("Opening Android Studio"); + if let Err(e) = os::open_file_with("Android Studio", config.project_dir()) { + log::error!("{}", e); + } + loop { + std::thread::sleep(std::time::Duration::from_secs(24 * 60 * 60)); + } } fn open() -> Result<()> { - with_config(|config, _metadata| { + with_config(|_, config, _metadata| { ensure_init(config.project_dir(), MobileTarget::Android) .map_err(|e| Error::ProjectNotInitialized(e.to_string()))?; os::open_file_with("Android Studio", config.project_dir()).map_err(Error::OpenFailed) - })?; - Ok(()) + }) + .map_err(Into::into) } -fn build(options: BuildOptions) -> Result<()> { +fn run(options: MobileOptions) -> Result { let profile = if options.debug { Profile::Debug } else { Profile::Release }; - fn device_prompt<'a>(env: &'_ Env) -> Result, PromptError> { - let device_list = - adb::device_list(env).map_err(|cause| PromptError::detection_failed("Android", cause))?; - if !device_list.is_empty() { - let index = if device_list.len() > 1 { - prompt::list( - concat!("Detected ", "Android", " devices"), - device_list.iter(), - "device", - None, - "Device", - ) - .map_err(|cause| PromptError::prompt_failed("Android", cause))? - } else { - 0 - }; - let device = device_list.into_iter().nth(index).unwrap(); - println!( - "Detected connected device: {} with target {:?}", - device, - device.target().triple, - ); - Ok(device) - } else { - Err(PromptError::none_detected("Android")) - } - } + with_config(|root_conf, config, metadata| { + let build_app_bundle = metadata.asset_packs().is_some(); + + ensure_init(config.project_dir(), MobileTarget::Android) + .map_err(|e| Error::ProjectNotInitialized(e.to_string()))?; + + let env = Env::new().map_err(Error::EnvInitFailed)?; + super::init::init_dot_cargo(root_conf, Some(&env)).map_err(Error::InitDotCargo)?; + + device_prompt(&env) + .map_err(Error::FailedToPromptForDevice)? + .run( + config, + &env, + NoiseLevel::Polite, + profile, + None, + build_app_bundle, + false, + ".MainActivity".into(), + ) + .map_err(Error::RunFailed) + }) + .map(|c| DevChild(Some(c))) +} + +fn build(options: BuildOptions) -> Result<()> { + let profile = if options.release { + Profile::Release + } else { + Profile::Debug + }; fn detect_target_ok<'a>(env: &Env) -> Option<&'a Target<'a>> { device_prompt(env).map(|device| device.target()).ok() } - with_config(|config, metadata| { + with_config(|root_conf, config, metadata| { ensure_init(config.project_dir(), MobileTarget::Android) .map_err(|e| Error::ProjectNotInitialized(e.to_string()))?; let env = Env::new().map_err(Error::EnvInitFailed)?; + super::init::init_dot_cargo(root_conf, Some(&env)).map_err(Error::InitDotCargo)?; call_for_targets_with_fallback( options.targets.unwrap_or_default().iter(), @@ -164,18 +318,11 @@ fn build(options: BuildOptions) -> Result<()> { &env, |target: &Target| { target - .build( - config, - metadata, - &env, - NoiseLevel::Polite, - true.into(), - profile, - ) + .build(config, metadata, &env, NoiseLevel::Polite, true, profile) .map_err(Error::BuildFailed) }, ) .map_err(|e| Error::TargetInvalid(e.to_string()))? - })?; - Ok(()) + }) + .map_err(Into::into) } diff --git a/tooling/cli/src/mobile/android/project.rs b/tooling/cli/src/mobile/android/project.rs index 0d4c504f7..c40c54a84 100644 --- a/tooling/cli/src/mobile/android/project.rs +++ b/tooling/cli/src/mobile/android/project.rs @@ -6,11 +6,9 @@ use crate::helpers::template; use cargo_mobile::{ android::{ config::{Config, Metadata}, - env::Env, - ndk, target::Target, }, - dot_cargo, os, + bossy, os, target::TargetTrait as _, util::{ self, @@ -42,8 +40,6 @@ pub enum Error { }, #[error("failed to symlink asset directory")] AssetDirSymlinkFailed, - #[error(transparent)] - DotCargoGenFailed(ndk::MissingToolError), #[error("failed to copy {src} to {dest}: {cause}")] FileCopyFailed { src: PathBuf, @@ -57,10 +53,8 @@ pub enum Error { pub fn gen( config: &Config, metadata: &Metadata, - env: &Env, (handlebars, mut map): (Handlebars, template::JsonMap), wrapper: &TextWrapper, - dot_cargo: &mut dot_cargo::DotCargo, ) -> Result<(), Error> { println!("Installing Android toolchains..."); Target::install_all().map_err(Error::RustupFailed)?; @@ -138,7 +132,15 @@ pub fn gen( created_dirs.push(parent); } - fs::File::create(path) + let mut options = fs::OpenOptions::new(); + + #[cfg(unix)] + if path.file_name().unwrap() == OsStr::new("gradlew") { + use std::os::unix::fs::OpenOptionsExt; + options.mode(0o755); + } + + options.create_new(true).write(true).open(path) }, ) .map_err(|e| Error::TemplateProcessingFailed(e.to_string()))?; @@ -173,16 +175,5 @@ pub fn gen( os::ln::force_symlink_relative(config.app().asset_dir(), dest, ln::TargetStyle::Directory) .map_err(|_| Error::AssetDirSymlinkFailed)?; - { - for target in Target::all().values() { - dot_cargo.insert_target( - target.triple.to_owned(), - target - .generate_cargo_config(config, env) - .map_err(Error::DotCargoGenFailed)?, - ); - } - } - Ok(()) } diff --git a/tooling/cli/src/mobile/init.rs b/tooling/cli/src/mobile/init.rs index 54bb1ff01..34a0d1847 100644 --- a/tooling/cli/src/mobile/init.rs +++ b/tooling/cli/src/mobile/init.rs @@ -2,14 +2,16 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use super::{get_config, get_metadata, Target}; -use crate::helpers::{app_paths::tauri_dir, config::get as get_tauri_config, template::JsonMap}; +use super::{get_config, Target}; +use crate::helpers::{config::get as get_tauri_config, template::JsonMap}; use crate::Result; use cargo_mobile::{ - android, + android::{self, env::Env as AndroidEnv, ndk, target::Target as AndroidTarget}, + bossy, config::Config, - dot_cargo, opts, + dot_cargo, os::code_command, + target::TargetTrait as _, util::{ self, cli::{Report, TextWrapper}, @@ -18,12 +20,7 @@ use cargo_mobile::{ use clap::Parser; use handlebars::{Context, Handlebars, Helper, HelperResult, Output, RenderContext, RenderError}; -use std::{ - fs, io, - path::{Path, PathBuf}, -}; - -use opts::{NonInteractive, OpenInEditor, ReinstallDeps, SkipDevTools}; +use std::{fs, io, path::PathBuf}; #[derive(Debug, Parser)] #[clap(about = "Initializes a Tauri Android project")] @@ -37,16 +34,7 @@ pub fn command(mut options: Options, target: Target) -> Result<()> { options.ci = options.ci || std::env::var("CI").is_ok(); let wrapper = TextWrapper::with_splitter(textwrap::termwidth(), textwrap::NoHyphenation); - exec( - target, - &wrapper, - options.ci.into(), - SkipDevTools::Yes, - ReinstallDeps::Yes, - OpenInEditor::No, - tauri_dir(), - ) - .map_err(|e| anyhow::anyhow!("{:#}", e))?; + exec(target, &wrapper, options.ci, true, true).map_err(|e| anyhow::anyhow!("{:#}", e))?; Ok(()) } @@ -64,6 +52,8 @@ pub enum Error { #[error(transparent)] DotCargoLoad(dot_cargo::LoadError), #[error(transparent)] + DotCargoGenFailed(ndk::MissingToolError), + #[error(transparent)] HostTargetTripleDetection(util::HostTargetTripleError), #[cfg(target_os = "macos")] #[error(transparent)] @@ -74,42 +64,9 @@ pub enum Error { AndroidInit(super::android::project::Error), #[error(transparent)] DotCargoWrite(dot_cargo::WriteError), - #[error(transparent)] - OpenInEditor(util::OpenInEditorError), } -pub fn exec( - target: Target, - wrapper: &TextWrapper, - non_interactive: NonInteractive, - skip_dev_tools: SkipDevTools, - #[allow(unused_variables)] reinstall_deps: ReinstallDeps, - open_in_editor: OpenInEditor, - cwd: impl AsRef, -) -> Result { - let cwd = cwd.as_ref(); - let tauri_config = - get_tauri_config(None).map_err(|e| Error::InvalidTauriConfig(e.to_string()))?; - let tauri_config_guard = tauri_config.lock().unwrap(); - let tauri_config_ = tauri_config_guard.as_ref().unwrap(); - - let config = get_config(tauri_config_); - let metadata = get_metadata(tauri_config_); - - let asset_dir = config.app().asset_dir(); - if !asset_dir.is_dir() { - fs::create_dir_all(&asset_dir).map_err(|cause| Error::AssetDirCreation { asset_dir, cause })?; - } - if skip_dev_tools.no() && util::command_present("code").unwrap_or_default() { - let mut command = code_command(); - command.add_args(&["--install-extension", "vadimcn.vscode-lldb"]); - if non_interactive.yes() { - command.add_arg("--force"); - } - command - .run_and_wait() - .map_err(Error::LldbExtensionInstall)?; - } +pub fn init_dot_cargo(config: &Config, android_env: Option<&AndroidEnv>) -> Result<(), Error> { let mut dot_cargo = dot_cargo::DotCargo::load(config.app()).map_err(Error::DotCargoLoad)?; // Mysteriously, builds that don't specify `--target` seem to fight over // the build cache with builds that use `--target`! This means that @@ -124,6 +81,49 @@ pub fn exec( dot_cargo .set_default_target(util::host_target_triple().map_err(Error::HostTargetTripleDetection)?); + if let Some(env) = android_env { + for target in AndroidTarget::all().values() { + dot_cargo.insert_target( + target.triple.to_owned(), + target + .generate_cargo_config(config.android(), env) + .map_err(Error::DotCargoGenFailed)?, + ); + } + } + + dot_cargo.write(config.app()).map_err(Error::DotCargoWrite) +} + +pub fn exec( + target: Target, + wrapper: &TextWrapper, + non_interactive: bool, + skip_dev_tools: bool, + #[allow(unused_variables)] reinstall_deps: bool, +) -> Result { + let tauri_config = + get_tauri_config(None).map_err(|e| Error::InvalidTauriConfig(e.to_string()))?; + let tauri_config_guard = tauri_config.lock().unwrap(); + let tauri_config_ = tauri_config_guard.as_ref().unwrap(); + + let (config, metadata) = get_config(tauri_config_); + + let asset_dir = config.app().asset_dir(); + if !asset_dir.is_dir() { + fs::create_dir_all(&asset_dir).map_err(|cause| Error::AssetDirCreation { asset_dir, cause })?; + } + if !skip_dev_tools && util::command_present("code").unwrap_or_default() { + let mut command = code_command(); + command.add_args(&["--install-extension", "vadimcn.vscode-lldb"]); + if non_interactive { + command.add_arg("--force"); + } + command + .run_and_wait() + .map_err(Error::LldbExtensionInstall)?; + } + let (handlebars, mut map) = handlebars(&config); // TODO: make this a relative path map.insert( @@ -135,24 +135,26 @@ pub fn exec( ); // Generate Android Studio project - if target == Target::Android { - match android::env::Env::new() { - Ok(env) => super::android::project::gen( - config.android(), - metadata.android(), - &env, - (handlebars, map), - wrapper, - &mut dot_cargo, - ) - .map_err(Error::AndroidInit)?, + let android_env = if target == Target::Android { + match AndroidEnv::new() { + Ok(env) => { + super::android::project::gen( + config.android(), + metadata.android(), + (handlebars, map), + wrapper, + ) + .map_err(Error::AndroidInit)?; + Some(env) + } Err(err) => { if err.sdk_or_ndk_issue() { Report::action_request( - " to initialize Android environment; Android support won't be usable until you fix the issue below and re-run `cargo mobile init`!", + " to initialize Android environment; Android support won't be usable until you fix the issue below and re-run `tauri android init`!", err, ) .print(wrapper); + None } else { return Err(Error::AndroidEnv(err)); } @@ -173,20 +175,16 @@ pub fn exec( ) .map_err(Error::IosInit)?; } - } + None + }; - dot_cargo - .write(config.app()) - .map_err(Error::DotCargoWrite)?; + init_dot_cargo(&config, android_env.as_ref())?; Report::victory( "Project generated successfully!", "Make cool apps! 🌻 🐕 🎉", ) .print(wrapper); - if open_in_editor.yes() { - util::open_in_editor(cwd).map_err(Error::OpenInEditor)?; - } Ok(config) } diff --git a/tooling/cli/src/mobile/ios.rs b/tooling/cli/src/mobile/ios.rs index fcd568512..22fe55fd5 100644 --- a/tooling/cli/src/mobile/ios.rs +++ b/tooling/cli/src/mobile/ios.rs @@ -2,24 +2,33 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use crate::helpers::config::get as get_tauri_config; use cargo_mobile::{ apple::{ config::{Config as AppleConfig, Metadata as AppleMetadata}, + device::{Device, RunError}, + ios_deploy, target::{CompileLibError, Target}, }, + config::Config, + device::PromptError, env::{Env, Error as EnvError}, opts::{NoiseLevel, Profile}, os, util, + util::prompt, }; use clap::{Parser, Subcommand}; use super::{ - ensure_init, get_config, get_metadata, + ensure_init, env_vars, get_config, init::{command as init_command, Options as InitOptions}, - Target as MobileTarget, + write_options, CliOptions, DevChild, Target as MobileTarget, }; -use crate::Result; +use crate::{ + helpers::{config::get as get_tauri_config, flock}, + interface::{AppSettings, DevProcess, Interface, MobileOptions, Options as InterfaceOptions}, + Result, +}; + use std::{collections::HashMap, ffi::OsStr, path::PathBuf}; pub(crate) mod project; @@ -28,12 +37,16 @@ pub(crate) mod project; enum Error { #[error(transparent)] EnvInitFailed(EnvError), + #[error(transparent)] + InitDotCargo(super::init::Error), #[error("invalid tauri configuration: {0}")] InvalidTauriConfig(String), #[error("{0}")] ProjectNotInitialized(String), #[error(transparent)] OpenFailed(os::OpenFileError), + #[error("{0}")] + DevFailed(String), #[error(transparent)] NoHomeDir(util::NoHomeDir), #[error("SDK root provided by Xcode was invalid. {sdk_root} doesn't exist or isn't a directory")] @@ -46,6 +59,10 @@ enum Error { ArchInvalid { arch: String }, #[error(transparent)] CompileLibFailed(CompileLibError), + #[error(transparent)] + FailedToPromptForDevice(PromptError), + #[error(transparent)] + RunFailed(RunError), } #[derive(Parser)] @@ -80,10 +97,49 @@ pub struct XcodeScriptOptions { arches: Vec, } +#[derive(Debug, Clone, Parser)] +#[clap(about = "iOS dev")] +pub struct DevOptions { + /// List of cargo features to activate + #[clap(short, long, multiple_occurrences(true), multiple_values(true))] + pub features: Option>, + /// Exit on panic + #[clap(short, long)] + exit_on_panic: bool, + /// JSON string or path to JSON file to merge with tauri.conf.json + #[clap(short, long)] + pub config: Option, + /// Run the code in release mode + #[clap(long = "release")] + pub release_mode: bool, + /// Disable the file watcher + #[clap(long)] + pub no_watch: bool, + /// Open Xcode instead of trying to run on a connected device + #[clap(short, long)] + pub open: bool, +} + +impl From for crate::dev::Options { + fn from(options: DevOptions) -> Self { + Self { + runner: None, + target: None, + features: options.features, + exit_on_panic: options.exit_on_panic, + config: options.config, + release_mode: options.release_mode, + args: Vec::new(), + no_watch: options.no_watch, + } + } +} + #[derive(Subcommand)] enum Commands { Init(InitOptions), Open, + Dev(DevOptions), #[clap(hide(true))] XcodeScript(XcodeScriptOptions), } @@ -92,31 +148,159 @@ pub fn command(cli: Cli) -> Result<()> { match cli.command { Commands::Init(options) => init_command(options, MobileTarget::Ios)?, Commands::Open => open()?, + Commands::Dev(options) => dev(options)?, Commands::XcodeScript(options) => xcode_script(options)?, } Ok(()) } -fn with_config( - f: impl FnOnce(&AppleConfig, &AppleMetadata) -> Result<(), Error>, -) -> Result<(), Error> { - let tauri_config = - get_tauri_config(None).map_err(|e| Error::InvalidTauriConfig(e.to_string()))?; - let tauri_config_guard = tauri_config.lock().unwrap(); - let tauri_config_ = tauri_config_guard.as_ref().unwrap(); - let config = get_config(tauri_config_); - let metadata = get_metadata(tauri_config_); - f(config.apple(), metadata.apple()) +fn with_config( + f: impl FnOnce(&Config, &AppleConfig, &AppleMetadata) -> Result, +) -> Result { + let (config, metadata) = { + let tauri_config = + get_tauri_config(None).map_err(|e| Error::InvalidTauriConfig(e.to_string()))?; + let tauri_config_guard = tauri_config.lock().unwrap(); + let tauri_config_ = tauri_config_guard.as_ref().unwrap(); + get_config(tauri_config_) + }; + f(&config, config.apple(), metadata.apple()) +} + +fn env() -> Result { + let env = Env::new() + .map_err(Error::EnvInitFailed)? + .explicit_env_vars(env_vars()); + Ok(env) +} + +fn device_prompt<'a>(env: &'_ Env) -> Result, PromptError> { + let device_list = + ios_deploy::device_list(env).map_err(|cause| PromptError::detection_failed("iOS", cause))?; + if !device_list.is_empty() { + let index = if device_list.len() > 1 { + prompt::list( + concat!("Detected ", "iOS", " devices"), + device_list.iter(), + "device", + None, + "Device", + ) + .map_err(|cause| PromptError::prompt_failed("iOS", cause))? + } else { + 0 + }; + let device = device_list.into_iter().nth(index).unwrap(); + println!( + "Detected connected device: {} with target {:?}", + device, + device.target().triple, + ); + Ok(device) + } else { + Err(PromptError::none_detected("iOS")) + } +} + +fn dev(options: DevOptions) -> Result<()> { + with_config(|_, config, _metadata| { + run_dev(options, config).map_err(|e| Error::DevFailed(e.to_string())) + }) + .map_err(Into::into) +} + +fn run_dev(options: DevOptions, config: &AppleConfig) -> Result<()> { + let mut dev_options = options.clone().into(); + let mut interface = crate::dev::setup(&mut dev_options)?; + + let bundle_identifier = { + let tauri_config = + get_tauri_config(None).map_err(|e| Error::InvalidTauriConfig(e.to_string()))?; + let tauri_config_guard = tauri_config.lock().unwrap(); + let tauri_config_ = tauri_config_guard.as_ref().unwrap(); + tauri_config_.tauri.bundle.identifier.clone() + }; + + let app_settings = interface.app_settings(); + let bin_path = app_settings.app_binary_path(&InterfaceOptions { + debug: !dev_options.release_mode, + ..Default::default() + })?; + let out_dir = bin_path.parent().unwrap(); + let _lock = flock::open_rw(&out_dir.join("lock").with_extension("ios"), "iOS")?; + + let open = options.open; + interface.mobile_dev( + MobileOptions { + debug: true, + features: options.features, + args: Vec::new(), + config: options.config, + no_watch: options.no_watch, + }, + |options| { + let cli_options = CliOptions { + features: options.features.clone(), + args: options.args.clone(), + vars: Default::default(), + }; + write_options(cli_options, &bundle_identifier, MobileTarget::Ios)?; + if open { + open_dev(config) + } else { + match run(options) { + Ok(c) => Ok(Box::new(c) as Box), + Err(Error::FailedToPromptForDevice(e)) => { + log::error!("{}", e); + open_dev(config) + } + Err(e) => Err(e.into()), + } + } + }, + ) +} + +fn open_dev(config: &AppleConfig) -> ! { + log::info!("Opening Xcode"); + if let Err(e) = os::open_file_with("Xcode", config.project_dir()) { + log::error!("{}", e); + } + loop { + std::thread::sleep(std::time::Duration::from_secs(24 * 60 * 60)); + } } fn open() -> Result<()> { - with_config(|config, _metadata| { + with_config(|_, config, _metadata| { ensure_init(config.project_dir(), MobileTarget::Ios) .map_err(|e| Error::ProjectNotInitialized(e.to_string()))?; os::open_file_with("Xcode", config.project_dir()).map_err(Error::OpenFailed) - })?; - Ok(()) + }) + .map_err(Into::into) +} + +fn run(options: MobileOptions) -> Result { + let profile = if options.debug { + Profile::Debug + } else { + Profile::Release + }; + + with_config(|root_conf, config, _| { + ensure_init(config.project_dir(), MobileTarget::Ios) + .map_err(|e| Error::ProjectNotInitialized(e.to_string()))?; + + let env = env()?; + super::init::init_dot_cargo(root_conf, None).map_err(Error::InitDotCargo)?; + + device_prompt(&env) + .map_err(Error::FailedToPromptForDevice)? + .run(config, &env, NoiseLevel::Polite, false, profile) + .map_err(Error::RunFailed) + }) + .map(|c| DevChild(Some(c))) } fn xcode_script(options: XcodeScriptOptions) -> Result<()> { @@ -135,8 +319,9 @@ fn xcode_script(options: XcodeScriptOptions) -> Result<()> { let profile = profile_from_configuration(&options.configuration); let macos = macos_from_platform(&options.platform); - with_config(|config, metadata| { - let env = Env::new().map_err(Error::EnvInitFailed)?; + with_config(|root_conf, config, metadata| { + let env = env()?; + super::init::init_dot_cargo(root_conf, None).map_err(Error::InitDotCargo)?; // The `PATH` env var Xcode gives us is missing any additions // made by the user's profile, so we'll manually add cargo's // `PATH`. @@ -216,7 +401,7 @@ fn xcode_script(options: XcodeScriptOptions) -> Result<()> { config, metadata, NoiseLevel::Polite, - true.into(), + true, profile, &env, target_env, @@ -224,7 +409,6 @@ fn xcode_script(options: XcodeScriptOptions) -> Result<()> { .map_err(Error::CompileLibFailed)?; } Ok(()) - })?; - - Ok(()) + }) + .map_err(Into::into) } diff --git a/tooling/cli/src/mobile/ios/project.rs b/tooling/cli/src/mobile/ios/project.rs index b743151ad..a0e5a8f35 100644 --- a/tooling/cli/src/mobile/ios/project.rs +++ b/tooling/cli/src/mobile/ios/project.rs @@ -9,7 +9,7 @@ use cargo_mobile::{ deps, rust_version_check, target::Target, }, - opts, + bossy, target::TargetTrait as _, util::{self, cli::TextWrapper, ln}, }; @@ -53,9 +53,9 @@ pub fn gen( metadata: &Metadata, (handlebars, mut map): (Handlebars, template::JsonMap), wrapper: &TextWrapper, - non_interactive: opts::NonInteractive, - skip_dev_tools: opts::SkipDevTools, - reinstall_deps: opts::ReinstallDeps, + non_interactive: bool, + skip_dev_tools: bool, + reinstall_deps: bool, ) -> Result<(), Error> { println!("Installing iOS toolchains..."); Target::install_all().map_err(Error::Rustup)?; diff --git a/tooling/cli/src/mobile/mod.rs b/tooling/cli/src/mobile/mod.rs index 6aced9de5..aa6bf5893 100644 --- a/tooling/cli/src/mobile/mod.rs +++ b/tooling/cli/src/mobile/mod.rs @@ -2,7 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: MIT -use crate::helpers::{app_paths::tauri_dir, config::Config as TauriConfig}; +use crate::{ + helpers::{app_paths::tauri_dir, config::Config as TauriConfig}, + interface::DevProcess, +}; use anyhow::{bail, Result}; #[cfg(target_os = "macos")] use cargo_mobile::apple::config::{ @@ -10,15 +13,48 @@ use cargo_mobile::apple::config::{ }; use cargo_mobile::{ android::config::{Metadata as AndroidMetadata, Raw as RawAndroidConfig}, + bossy, config::{app::Raw as RawAppConfig, metadata::Metadata, Config, Raw}, }; -use std::path::PathBuf; +use serde::{Deserialize, Serialize}; +use std::{collections::HashMap, ffi::OsString, path::PathBuf, process::ExitStatus}; pub mod android; mod init; #[cfg(target_os = "macos")] pub mod ios; +pub struct DevChild(Option); + +impl Drop for DevChild { + fn drop(&mut self) { + // consume the handle since we're not waiting on it + // just to prevent a log error + // note that this doesn't leak any memory + self.0.take().unwrap().leak(); + } +} + +impl DevProcess for DevChild { + fn kill(&mut self) -> std::io::Result<()> { + self + .0 + .as_mut() + .unwrap() + .kill() + .map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "failed to kill")) + } + + fn try_wait(&mut self) -> std::io::Result> { + self + .0 + .as_mut() + .unwrap() + .try_wait() + .map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "failed to wait")) + } +} + #[derive(PartialEq, Eq)] pub enum Target { Android, @@ -44,13 +80,113 @@ impl Target { } } -fn get_metadata(_config: &TauriConfig) -> Metadata { - Metadata { +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct CliOptions { + pub features: Option>, + pub args: Vec, + pub vars: HashMap, +} + +fn options_path(bundle_identifier: &str, target: Target) -> PathBuf { + let out_dir = dirs_next::cache_dir() + .or_else(dirs_next::home_dir) + .unwrap_or_else(std::env::temp_dir); + let out_dir = out_dir.join(".tauri").join(bundle_identifier); + let _ = std::fs::create_dir_all(&out_dir); + out_dir + .join("cli-options") + .with_extension(target.command_name()) +} + +fn env_vars() -> HashMap { + let mut vars = HashMap::new(); + for (k, v) in std::env::vars_os() { + let k = k.to_string_lossy(); + if k.starts_with("TAURI") && k != "TAURI_PRIVATE_KEY" && k != "TAURI_KEY_PASSWORD" { + vars.insert(k.into_owned(), v); + } + } + vars +} + +/// Writes CLI options to be used later on the Xcode and Android Studio build commands +pub fn write_options( + mut options: CliOptions, + bundle_identifier: &str, + target: Target, +) -> crate::Result<()> { + options.vars.extend(env_vars()); + std::fs::write( + options_path(bundle_identifier, target), + &serde_json::to_string(&options)?, + )?; + Ok(()) +} + +fn read_options(config: &TauriConfig, target: Target) -> crate::Result { + let data = std::fs::read_to_string(options_path(&config.tauri.bundle.identifier, target))?; + let options = serde_json::from_str(&data)?; + Ok(options) +} + +fn get_config(config: &TauriConfig) -> (Config, Metadata) { + let mut s = config.tauri.bundle.identifier.rsplit('.'); + let app_name = s.next().unwrap_or("app").to_string(); + let mut domain = String::new(); + for w in s { + domain.push_str(w); + domain.push('.'); + } + domain.pop(); + + #[cfg(target_os = "macos")] + let ios_options = read_options(config, Target::Ios).unwrap_or_default(); + let android_options = read_options(config, Target::Android).unwrap_or_default(); + + let raw = Raw { + app: RawAppConfig { + name: app_name, + stylized_name: config.package.product_name.clone(), + domain, + asset_dir: None, + template_pack: None, + }, + #[cfg(target_os = "macos")] + apple: Some(RawAppleConfig { + development_team: std::env::var("TAURI_APPLE_DEVELOPMENT_TEAM") + .ok() + .or_else(|| config.tauri.ios.development_team.clone()) + .expect("you must set `tauri > iOS > developmentTeam` config value or the `TAURI_APPLE_DEVELOPMENT_TEAM` environment variable"), + project_dir: None, + ios_no_default_features: None, + ios_features: ios_options.features.clone(), + macos_no_default_features: None, + macos_features: None, + bundle_version: None, + bundle_version_short: None, + ios_version: None, + macos_version: None, + use_legacy_build_system: None, + plist_pairs: None, + }), + android: Some(RawAndroidConfig { + min_sdk_version: None, + vulkan_validation: None, + project_dir: None, + no_default_features: None, + features: android_options.features.clone(), + }), + }; + let config = Config::from_raw(tauri_dir(), raw).unwrap(); + + let metadata = Metadata { #[cfg(target_os = "macos")] apple: AppleMetadata { supported: true, ios: ApplePlatform { - features: None, + no_default_features: false, + cargo_args: Some(ios_options.args), + features: ios_options.features, frameworks: None, valid_archs: None, vendor_frameworks: None, @@ -67,7 +203,9 @@ fn get_metadata(_config: &TauriConfig) -> Metadata { }, android: AndroidMetadata { supported: true, - features: None, + no_default_features: false, + cargo_args: Some(android_options.args), + features: android_options.features, app_sources: None, app_plugins: None, project_dependencies: None, @@ -75,53 +213,9 @@ fn get_metadata(_config: &TauriConfig) -> Metadata { app_dependencies_platform: None, asset_packs: None, }, - } -} - -fn get_config(config: &TauriConfig) -> Config { - let mut s = config.tauri.bundle.identifier.rsplit('.'); - let app_name = s.next().unwrap_or("app").to_string(); - let mut domain = String::new(); - for w in s { - domain.push_str(w); - domain.push('.'); - } - domain.pop(); - let raw = Raw { - app: RawAppConfig { - name: app_name, - stylized_name: config.package.product_name.clone(), - domain, - asset_dir: None, - template_pack: None, - }, - #[cfg(target_os = "macos")] - apple: Some(RawAppleConfig { - development_team: std::env::var("APPLE_DEVELOPMENT_TEAM") - .ok() - .or_else(|| config.tauri.ios.development_team.clone()) - .expect("you must set `tauri > iOS > developmentTeam` config value or the `APPLE_DEVELOPMENT_TEAM` environment variable"), - project_dir: None, - ios_no_default_features: None, - ios_features: None, - macos_no_default_features: None, - macos_features: None, - bundle_version: None, - bundle_version_short: None, - ios_version: None, - macos_version: None, - use_legacy_build_system: None, - plist_pairs: None, - }), - android: Some(RawAndroidConfig { - min_sdk_version: None, - vulkan_validation: None, - project_dir: None, - no_default_features: None, - features: None, - }), }; - Config::from_raw(tauri_dir(), raw).unwrap() + + (config, metadata) } fn ensure_init(project_dir: PathBuf, target: Target) -> Result<()> { diff --git a/tooling/cli/templates/mobile/android/app/build.gradle.kts b/tooling/cli/templates/mobile/android/app/build.gradle.kts index cc33f0d8b..5696afc5c 100644 --- a/tooling/cli/templates/mobile/android/app/build.gradle.kts +++ b/tooling/cli/templates/mobile/android/app/build.gradle.kts @@ -40,6 +40,16 @@ android { } flavorDimensions.add("abi") productFlavors { + create("universal") { + dimension = "abi" + ndk { + abiFilters += listOf( + {{~#each targets}} + "{{this.abi}}",{{/each}} + ) + } + } + {{~#each targets}} create("{{this.arch}}") { @@ -75,7 +85,9 @@ dependencies { afterEvaluate { android.applicationVariants.all { - productFlavors.forEach { _ -> + tasks["mergeUniversalReleaseJniLibFolders"].dependsOn(tasks["rustBuildRelease"]) + tasks["mergeUniversalDebugJniLibFolders"].dependsOn(tasks["rustBuildDebug"]) + productFlavors.filter{ it.name != "universal" }.forEach { _ -> val archAndBuildType = name.capitalize() tasks["merge${archAndBuildType}JniLibFolders"].dependsOn(tasks["rustBuild${archAndBuildType}"]) } diff --git a/tooling/cli/templates/mobile/android/app/src/main/AndroidManifest.xml b/tooling/cli/templates/mobile/android/app/src/main/AndroidManifest.xml index cf42dcd2c..657c7e775 100644 --- a/tooling/cli/templates/mobile/android/app/src/main/AndroidManifest.xml +++ b/tooling/cli/templates/mobile/android/app/src/main/AndroidManifest.xml @@ -3,11 +3,8 @@ package="{{reverse-domain app.domain}}.{{snake-case app.name}}"> = 20) { loadedUrl = url runInitializationScripts() } diff --git a/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index eca70cfe5..000000000 --- a/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp deleted file mode 100644 index b2dfe3d1b..000000000 Binary files a/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and /dev/null differ diff --git a/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp deleted file mode 100644 index 62b611da0..000000000 Binary files a/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and /dev/null differ diff --git a/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp deleted file mode 100644 index 1b9a6956b..000000000 Binary files a/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp deleted file mode 100644 index 9287f5083..000000000 Binary files a/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp deleted file mode 100644 index 9126ae37c..000000000 Binary files a/tooling/cli/templates/mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and /dev/null differ diff --git a/tooling/cli/templates/mobile/android/app/src/main/res/values/strings.xml b/tooling/cli/templates/mobile/android/app/src/main/res/values/strings.xml index d7c29c74f..1a1f24574 100644 --- a/tooling/cli/templates/mobile/android/app/src/main/res/values/strings.xml +++ b/tooling/cli/templates/mobile/android/app/src/main/res/values/strings.xml @@ -1,3 +1,3 @@ - qoo + {{app.stylized-name}} \ No newline at end of file diff --git a/tooling/cli/templates/mobile/android/buildSrc/build.gradle.kts b/tooling/cli/templates/mobile/android/buildSrc/build.gradle.kts index f3753b206..86a264bdd 100644 --- a/tooling/cli/templates/mobile/android/buildSrc/build.gradle.kts +++ b/tooling/cli/templates/mobile/android/buildSrc/build.gradle.kts @@ -2,10 +2,6 @@ plugins { `kotlin-dsl` } -kotlinDslPluginOptions { - experimentalWarning.set(false) -} - gradlePlugin { plugins { create("pluginsForCoolKids") { diff --git a/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/BuildTask.kt b/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/BuildTask.kt index 9796cc8c3..381080bfe 100644 --- a/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/BuildTask.kt +++ b/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/BuildTask.kt @@ -1,10 +1,8 @@ package {{reverse-domain app.domain}} -import com.android.build.gradle.* import java.io.File import org.gradle.api.DefaultTask import org.gradle.api.GradleException -import org.gradle.api.Project import org.gradle.api.logging.LogLevel import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory @@ -23,20 +21,11 @@ open class BuildTask : DefaultTask() { @TaskAction fun build() { - val rootDirRel = rootDirRel - if (rootDirRel == null) { - throw GradleException("rootDirRel cannot be null") - } - val target = target - if (target == null) { - throw GradleException("target cannot be null") - } - val release = release - if (release == null) { - throw GradleException("release cannot be null") - } + val rootDirRel = rootDirRel ?: throw GradleException("rootDirRel cannot be null") + val target = target ?: throw GradleException("target cannot be null") + val release = release ?: throw GradleException("release cannot be null") project.exec { - workingDir(File(project.getProjectDir(), rootDirRel.getPath())) + workingDir(File(project.projectDir, rootDirRel.path)) executable("{{ tauri-binary }}") args(listOf("tauri", "android", "build")) if (project.logger.isEnabled(LogLevel.DEBUG)) { @@ -47,7 +36,7 @@ open class BuildTask : DefaultTask() { if (release) { args("--release") } - args(listOf("--target", "${target}")) + args(listOf("--target", target)) }.assertNormalExitValue() } } diff --git a/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/RustPlugin.kt b/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/RustPlugin.kt index 86b86cd4f..7028af56d 100644 --- a/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/RustPlugin.kt +++ b/tooling/cli/templates/mobile/android/buildSrc/src/main/kotlin/RustPlugin.kt @@ -1,11 +1,11 @@ package {{reverse-domain app.domain}} -import com.android.build.gradle.* -import java.io.File import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.Plugin import org.gradle.api.Project +import java.io.File +import java.util.* const val TASK_GROUP = "rust" @@ -16,7 +16,7 @@ open class Config { } open class RustPlugin : Plugin { - internal lateinit var config: Config + private lateinit var config: Config override fun apply(project: Project) { config = project.extensions.create("rust", Config::class.java) @@ -28,17 +28,25 @@ open class RustPlugin : Plugin { throw GradleException("arches cannot be null") } for (profile in listOf("debug", "release")) { - val buildTask = project.tasks.maybeCreate("rustBuild${profile.capitalize()}", DefaultTask::class.java).apply { + val profileCapitalized = profile.capitalize(Locale.ROOT) + val buildTask = project.tasks.maybeCreate( + "rustBuild$profileCapitalized", + DefaultTask::class.java + ).apply { group = TASK_GROUP - description = "Build dynamic library in ${profile} mode for all targets" + description = "Build dynamic library in $profile mode for all targets" } for (targetPair in config.targets!!.withIndex()) { val targetName = targetPair.value val targetArch = config.arches!![targetPair.index] - val targetBuildTask = project.tasks.maybeCreate("rustBuild${targetArch.capitalize()}${profile.capitalize()}", BuildTask::class.java).apply { + val targetArchCapitalized = targetArch.capitalize(Locale.ROOT) + val targetBuildTask = project.tasks.maybeCreate( + "rustBuild$targetArchCapitalized$profileCapitalized", + BuildTask::class.java + ).apply { group = TASK_GROUP - description = "Build dynamic library in ${profile} mode for $targetArch" - rootDirRel = File(config.rootDirRel) + description = "Build dynamic library in $profile mode for $targetArch" + rootDirRel = config.rootDirRel?.let { File(it) } target = targetName release = profile == "release" }